D868UV: parse CSV files downloaded from amateurradio.digital.
This commit is contained in:
parent
08ae731218
commit
46203f940e
56
d868uv.c
56
d868uv.c
@ -2687,7 +2687,7 @@ static int d868uv_verify_config(radio_device_t *radio)
|
|||||||
//
|
//
|
||||||
// Read and dump the callsign database.
|
// Read and dump the callsign database.
|
||||||
//
|
//
|
||||||
static void read_csv(radio_device_t *radio)
|
static void dump_csv(radio_device_t *radio)
|
||||||
{
|
{
|
||||||
callsign_sizes_t sz = {0};
|
callsign_sizes_t sz = {0};
|
||||||
|
|
||||||
@ -2809,52 +2809,30 @@ static void d868uv_write_csv(radio_device_t *radio, FILE *csv)
|
|||||||
// Need to rearrange the fields like:
|
// Need to rearrange the fields like:
|
||||||
// Radio ID, Name, City, Callsign, State, Country, Remarks
|
// Radio ID, Name, City, Callsign, State, Country, Remarks
|
||||||
//
|
//
|
||||||
char line[256];
|
|
||||||
unsigned nbytes = 0;
|
unsigned nbytes = 0;
|
||||||
|
char *radioid, *callsign, *name, *city, *state, *country, *remarks;
|
||||||
|
|
||||||
while (fgets(line, sizeof(line), csv)) {
|
if (csv_init(csv) < 0) {
|
||||||
trim_spaces(line, 255);
|
|
||||||
if (line[0] < '0' || line[0] > '9') {
|
|
||||||
// Eastern egg: when file contains a line "dump",
|
|
||||||
// read the callsign database from the radio
|
|
||||||
// and save to a file.
|
|
||||||
if (strcmp(line, "dump") == 0) {
|
|
||||||
free(data);
|
free(data);
|
||||||
read_csv(radio);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Skip header.
|
while (csv_read(csv, &radioid, &callsign, &name, &city, &state, &country, &remarks)) {
|
||||||
continue;
|
//printf("%s,%s,%s,%s,%s,%s,%s\n", radioid, callsign, name, city, state, country, remarks);
|
||||||
}
|
|
||||||
|
|
||||||
// Replace non-ASCII characters with '?'.
|
unsigned id = strtoul(radioid, 0, 10);
|
||||||
char *p;
|
|
||||||
for (p=line; *p; p++) {
|
|
||||||
if (*p < ' ' || *p > '~')
|
|
||||||
*p = '?';
|
|
||||||
}
|
|
||||||
|
|
||||||
char *callsign = strchr(line, ','); if (! callsign) continue; *callsign++ = 0;
|
|
||||||
char *name = strchr(callsign, ','); if (! name) continue; *name++ = 0;
|
|
||||||
char *city = strchr(name, ','); if (! city) continue; *city++ = 0;
|
|
||||||
char *state = strchr(city, ','); if (! state) continue; *state++ = 0;
|
|
||||||
char *country = strchr(state, ','); if (! country) continue; *country++ = 0;
|
|
||||||
char *remarks = strchr(country, ','); if (! remarks) continue; *remarks++ = 0;
|
|
||||||
if ((p = strchr(remarks, ',')) != 0)
|
|
||||||
*p = 0;
|
|
||||||
callsign = trim_spaces(callsign, 16);
|
|
||||||
name = trim_spaces(name, 16);
|
|
||||||
city = trim_spaces(city, 15);
|
|
||||||
state = trim_spaces(state, 16);
|
|
||||||
country = trim_spaces(country, 16);
|
|
||||||
remarks = trim_spaces(remarks, 16);
|
|
||||||
//printf("%s,%s,%s,%s,%s,%s,%s\n", line, callsign, name, city, state, country, remarks);
|
|
||||||
|
|
||||||
unsigned id = strtoul(line, 0, 10);
|
|
||||||
if (id < 1 || id > 0xffffff) {
|
if (id < 1 || id > 0xffffff) {
|
||||||
fprintf(stderr, "Bad id: %d\n", id);
|
fprintf(stderr, "Bad id: %d\n", id);
|
||||||
fprintf(stderr, "Line: '%s,%s,%s,%s,%s,%s,%s'\n",
|
fprintf(stderr, "Line: '%s,%s,%s,%s,%s,%s,%s'\n",
|
||||||
line, callsign, name, city, state, country, remarks);
|
radioid, callsign, name, city, state, country, remarks);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Eastern egg: when file contains id 1 with callsign 'dump',
|
||||||
|
// read the callsign database from the radio
|
||||||
|
// and save to a file.
|
||||||
|
if (id == 1 && strcmp(callsign, "dump") == 0) {
|
||||||
|
free(data);
|
||||||
|
dump_csv(radio);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2872,7 +2850,7 @@ static void d868uv_write_csv(radio_device_t *radio, FILE *csv)
|
|||||||
m->offset = nbytes;
|
m->offset = nbytes;
|
||||||
|
|
||||||
// Fill data.
|
// Fill data.
|
||||||
p = &data[nbytes];
|
char *p = &data[nbytes];
|
||||||
|
|
||||||
// Radio ID.
|
// Radio ID.
|
||||||
*p++ = 0;
|
*p++ = 0;
|
||||||
|
111
util.c
111
util.c
@ -142,6 +142,22 @@ char *trim_spaces(char *line, int limit)
|
|||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Strip optional quotes around the string.
|
||||||
|
//
|
||||||
|
char *trim_quotes(char *line)
|
||||||
|
{
|
||||||
|
if (*line == '"') {
|
||||||
|
int last = strlen(line) - 1;
|
||||||
|
|
||||||
|
if (line[last] == '"') {
|
||||||
|
line[last] = 0;
|
||||||
|
return line+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Delay in milliseconds.
|
// Delay in milliseconds.
|
||||||
//
|
//
|
||||||
@ -722,3 +738,98 @@ void print_tone(FILE *out, unsigned data)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize CSV parser.
|
||||||
|
// Check header for correctness.
|
||||||
|
// Return negative on error.
|
||||||
|
//
|
||||||
|
static int csv_skip_field1;
|
||||||
|
|
||||||
|
int csv_init(FILE *csv)
|
||||||
|
{
|
||||||
|
char line[256];
|
||||||
|
|
||||||
|
if (!fgets(line, sizeof(line), csv))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
char *field1 = line;
|
||||||
|
char *field2 = strchr(field1, ','); if (! field2) return -1; *field2++ = 0;
|
||||||
|
char *field3 = strchr(field2, ','); if (! field3) return -1; *field3++ = 0;
|
||||||
|
char *field4 = strchr(field3, ','); if (! field4) return -1; *field4++ = 0;
|
||||||
|
|
||||||
|
field1 = trim_quotes(field1);
|
||||||
|
field2 = trim_quotes(field2);
|
||||||
|
field3 = trim_quotes(field3);
|
||||||
|
//printf("Line: %s,%s,%s\n", field1, field2, field3);
|
||||||
|
|
||||||
|
if (strcmp(field1, "Radio ID") == 0 &&
|
||||||
|
strcmp(field2, "Callsign") == 0) {
|
||||||
|
// Correct format:
|
||||||
|
// Radio ID,Callsign,Name,City,State,Country,Remarks
|
||||||
|
csv_skip_field1 = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (strcmp(field2, "Radio ID") == 0 &&
|
||||||
|
strcmp(field3, "Callsign") == 0) {
|
||||||
|
// Correct format:
|
||||||
|
// "No.","Radio ID","Callsign","Name","City","State","Country","Remarks"
|
||||||
|
csv_skip_field1 = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Parse one line of CSV file.
|
||||||
|
// Return 1 on success, 0 on EOF.
|
||||||
|
//
|
||||||
|
int csv_read(FILE *csv, char **radioid, char **callsign, char **name,
|
||||||
|
char **city, char **state, char **country, char **remarks)
|
||||||
|
{
|
||||||
|
static char line[256];
|
||||||
|
|
||||||
|
again:
|
||||||
|
if (!fgets(line, sizeof(line), csv))
|
||||||
|
return 0;
|
||||||
|
//printf("Line: '%s'\n", line);
|
||||||
|
|
||||||
|
// Replace non-ASCII characters with '?'.
|
||||||
|
char *p;
|
||||||
|
for (p=line; *p; p++) {
|
||||||
|
if ((uint8_t)*p > '~')
|
||||||
|
*p = '?';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (csv_skip_field1) {
|
||||||
|
*radioid = strchr(line, ',');
|
||||||
|
if (! *radioid)
|
||||||
|
return 0;
|
||||||
|
*(*radioid)++ = 0;
|
||||||
|
} else
|
||||||
|
*radioid = line;
|
||||||
|
|
||||||
|
*callsign = strchr(*radioid, ','); if (! *callsign) return 0; *(*callsign)++ = 0;
|
||||||
|
*name = strchr(*callsign, ','); if (! *name) return 0; *(*name)++ = 0;
|
||||||
|
*city = strchr(*name, ','); if (! *city) return 0; *(*city)++ = 0;
|
||||||
|
*state = strchr(*city, ','); if (! *state) return 0; *(*state)++ = 0;
|
||||||
|
*country = strchr(*state, ','); if (! *country) return 0; *(*country)++ = 0;
|
||||||
|
*remarks = strchr(*country, ','); if (! *remarks) return 0; *(*remarks)++ = 0;
|
||||||
|
if ((p = strchr(*remarks, ',')) != 0)
|
||||||
|
*p = 0;
|
||||||
|
|
||||||
|
*radioid = trim_spaces(trim_quotes(*radioid), 16);
|
||||||
|
*callsign = trim_spaces(trim_quotes(*callsign), 16);
|
||||||
|
*name = trim_spaces(trim_quotes(*name), 16);
|
||||||
|
*city = trim_spaces(trim_quotes(*city), 15);
|
||||||
|
*state = trim_spaces(trim_quotes(*state), 16);
|
||||||
|
*country = trim_spaces(trim_quotes(*country), 16);
|
||||||
|
*remarks = trim_spaces(trim_quotes(*remarks), 16);
|
||||||
|
//printf("%s,%s,%s,%s,%s,%s,%s\n", *radioid, *callsign, *name, *city, *state, *country, *remarks);
|
||||||
|
|
||||||
|
if (**radioid < '1' || **radioid > '9')
|
||||||
|
goto again;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
19
util.h
19
util.h
@ -49,6 +49,25 @@ void print_hex_addr_data(unsigned addr, const unsigned char *data, int len);
|
|||||||
//
|
//
|
||||||
char *trim_spaces(char *line, int limit);
|
char *trim_spaces(char *line, int limit);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Strip optional quotes around the string.
|
||||||
|
//
|
||||||
|
char *trim_quotes(char *line);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize CSV parser.
|
||||||
|
// Check header for correctness.
|
||||||
|
// Return -1 on error.
|
||||||
|
//
|
||||||
|
int csv_init(FILE *csv);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Parse one line of CSV file.
|
||||||
|
// Return 1 on success, 0 on EOF.
|
||||||
|
//
|
||||||
|
int csv_read(FILE *csv, char **radioid, char **callsign, char **name,
|
||||||
|
char **city, char **state, char **country, char **remarks);
|
||||||
|
|
||||||
//
|
//
|
||||||
// DFU functions.
|
// DFU functions.
|
||||||
//
|
//
|
||||||
|
Loading…
Reference in New Issue
Block a user