parse_config port to rust
This commit is contained in:
parent
5658759cf3
commit
3f4b18368b
106
radio.c
106
radio.c
@ -35,109 +35,3 @@
|
||||
#include "radio.h"
|
||||
#include "util.h"
|
||||
|
||||
/*
|
||||
typedef struct { char* ident; radio_device_t* device; } radio_tab_t;
|
||||
|
||||
static radio_tab_t radio_tab[] = {
|
||||
{ "DR780", &radio_md380 }, // TYT MD-380, Retevis RT3, RT8
|
||||
{ "MD390", &radio_md390 }, // TYT MD-390
|
||||
{ "MD-UV380", &radio_uv380 }, // TYT MD-UV380
|
||||
{ "MD-UV390", &radio_uv390 }, // TYT MD-UV390, Retevis RT3S
|
||||
{ "2017", &radio_md2017 }, // TYT MD-2017, Retevis RT82
|
||||
{ "MD9600", &radio_md9600 }, // TYT MD-9600
|
||||
{ "BF-5R", &radio_rd5r }, // Baofeng RD-5R, TD-5R
|
||||
{ "1801", &radio_dm1801 }, // Baofeng DM-1801
|
||||
{ "DM-1701", &radio_rt84 }, // Baofeng DM-1701, Retevis RT84
|
||||
{ "MD-760P", &radio_gd77 }, // Radioddity GD-77, version 3.1.1 and later
|
||||
{ "D868UVE", &radio_d868uv }, // Anytone AT-D868UV
|
||||
{ "D878UV", &radio_d878uv }, // Anytone AT-D878UV
|
||||
{ "D6X2UV", &radio_dmr6x2 }, // BTECH DMR-6x2
|
||||
{ "ZD3688", &radio_d900 }, // Zastone D900
|
||||
{ "TP660", &radio_dp880 }, // Zastone DP880
|
||||
{ "ZN><:", &radio_rt27d }, // Radtel RT-27D
|
||||
{ 0, 0 }
|
||||
};
|
||||
*/
|
||||
|
||||
//
|
||||
// Read the configuration from text file, and modify the firmware.
|
||||
//
|
||||
void radio_parse_config(radio_device_t* device, const char *filename)
|
||||
{
|
||||
FILE *conf;
|
||||
char line [256], *p, *v;
|
||||
int table_id = 0, table_dirty = 0;
|
||||
|
||||
fprintf(stderr, "Read configuration from file '%s'.\n", filename);
|
||||
conf = fopen(filename, "r");
|
||||
if (! conf) {
|
||||
perror(filename);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
device->channel_count = 0;
|
||||
while (fgets(line, sizeof(line), conf)) {
|
||||
line[sizeof(line)-1] = 0;
|
||||
|
||||
// Strip comments.
|
||||
v = strchr(line, '#');
|
||||
if (v)
|
||||
*v = 0;
|
||||
|
||||
// Strip trailing spaces and newline.
|
||||
v = line + strlen(line) - 1;
|
||||
while (v >= line && (*v=='\n' || *v=='\r' || *v==' ' || *v=='\t'))
|
||||
*v-- = 0;
|
||||
|
||||
// Ignore comments and empty lines.
|
||||
p = line;
|
||||
if (*p == 0)
|
||||
continue;
|
||||
|
||||
if (*p != ' ') {
|
||||
// Table finished.
|
||||
table_id = 0;
|
||||
|
||||
// Find the value.
|
||||
v = strchr(p, ':');
|
||||
if (! v) {
|
||||
// Table header: get table type.
|
||||
table_id = device->parse_header(device, p);
|
||||
if (! table_id) {
|
||||
badline: fprintf(stderr, "Invalid line: '%s'\n", line);
|
||||
exit(-1);
|
||||
}
|
||||
table_dirty = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Parameter.
|
||||
*v++ = 0;
|
||||
|
||||
// Skip spaces.
|
||||
while (*v == ' ' || *v == '\t')
|
||||
v++;
|
||||
|
||||
device->parse_parameter(device, p, v);
|
||||
|
||||
} else {
|
||||
// Table row or comment.
|
||||
// Skip spaces.
|
||||
// Ignore comments and empty lines.
|
||||
while (*p == ' ' || *p == '\t')
|
||||
p++;
|
||||
if (*p == '#' || *p == 0)
|
||||
continue;
|
||||
if (! table_id) {
|
||||
goto badline;
|
||||
}
|
||||
|
||||
if (! device->parse_row(device, table_id, ! table_dirty, p)) {
|
||||
goto badline;
|
||||
}
|
||||
table_dirty = 1;
|
||||
}
|
||||
}
|
||||
fclose(conf);
|
||||
device->update_timestamp(device);
|
||||
}
|
||||
|
97
src/radio.rs
97
src/radio.rs
@ -37,8 +37,6 @@ pub static mut radio_mem: [u8; 1024*1024*2] = [0; 1024*1024*2];
|
||||
|
||||
extern {
|
||||
|
||||
fn radio_parse_config(device: *const radio_device_t, filename: *const c_char);
|
||||
|
||||
fn dfu_init(vid: c_uint, pid: c_uint) -> *const c_char;
|
||||
fn dfu_reboot();
|
||||
fn dfu_close();
|
||||
@ -311,12 +309,99 @@ pub fn save_image(radio: &Radio, filename: &str) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Read the configuration from text file, and modify the firmware.
|
||||
/// Read the configuration from a text file, and modify the firmware.
|
||||
pub fn parse_config(radio: &Radio, filename: &str) {
|
||||
let device = radio.ptr;
|
||||
let filename = CString::new(filename.to_string()).unwrap();
|
||||
use std::io::{BufRead, BufReader};
|
||||
|
||||
let device = radio.ptr as *mut radio_device_t;
|
||||
|
||||
let parse_header_fn = unsafe {
|
||||
(*device).parse_header.unwrap()
|
||||
};
|
||||
|
||||
let parse_parameter_fn = unsafe {
|
||||
(*device).parse_parameter.unwrap()
|
||||
};
|
||||
|
||||
let parse_row_fn = unsafe {
|
||||
(*device).parse_row.unwrap()
|
||||
};
|
||||
|
||||
let update_timestamp_fn = unsafe {
|
||||
(*device).update_timestamp.unwrap()
|
||||
};
|
||||
|
||||
eprintln!("Read configuration from file '{}'.", filename);
|
||||
let file = std::fs::File::open(filename).unwrap();
|
||||
let file = BufReader::new(file);
|
||||
|
||||
let mut table_id: c_int = 0;
|
||||
let mut table_dirty: c_int = 0;
|
||||
|
||||
for line in file.lines() {
|
||||
let line = line.unwrap();
|
||||
// Strip text after comment marker '#'
|
||||
let trimmed_line = line
|
||||
.split('#')
|
||||
.next()
|
||||
.unwrap()
|
||||
.trim_end();
|
||||
|
||||
// Skip comments and blank lines
|
||||
if trimmed_line.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Table row
|
||||
if trimmed_line.chars().nth(0) == Some(' ') {
|
||||
if table_id == 0 {
|
||||
eprintln!("Invalid line: '{}'", line);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
let trimmed_more = CString::new(trimmed_line.trim_start()).unwrap();
|
||||
let ptr = trimmed_more.as_ptr() as *mut c_char;
|
||||
let output = unsafe { parse_row_fn(device, table_id, !table_dirty, ptr) };
|
||||
if output == 0 {
|
||||
eprintln!("Invalid line: '{}'", line);
|
||||
exit(-1);
|
||||
}
|
||||
table_dirty = 1;
|
||||
} else {
|
||||
// Table finished
|
||||
table_id = 0;
|
||||
|
||||
// Find the value
|
||||
if let Some(colon_byte_idx) = line.find(':') {
|
||||
|
||||
let (param_str, value_str) = line.split_at(colon_byte_idx);
|
||||
let stripped_value_str = value_str.strip_prefix(':').unwrap();
|
||||
|
||||
let param_c_str = CString::new(param_str.trim_start()).unwrap();
|
||||
let param_ptr = param_c_str.as_ptr() as *mut c_char;
|
||||
|
||||
let value_c_str = CString::new(stripped_value_str.trim_start()).unwrap();
|
||||
let value_ptr = value_c_str.as_ptr() as *mut c_char;
|
||||
|
||||
unsafe {
|
||||
parse_parameter_fn(device, param_ptr, value_ptr);
|
||||
}
|
||||
} else { // Table header
|
||||
let c_line = CString::new(trimmed_line).unwrap();
|
||||
let ptr = c_line.as_ptr() as *mut c_char;
|
||||
table_id = unsafe { parse_header_fn(device, ptr) };
|
||||
|
||||
if table_id == 0 {
|
||||
eprintln!("Invalid line: '{}'", line);
|
||||
exit(-1);
|
||||
}
|
||||
table_dirty = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
radio_parse_config(device, filename.as_ptr())
|
||||
update_timestamp_fn(device);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user