/* Input and output parsing tools. */ #include #include #include #include #include "logger.h" #include "version.h" #include "parsers.h" #include "constants.h" #include "geometry.h" #include /* Parse basic command line arguments for programs */ int parse_basic_args(int argc, char **argv, const char *progname, BASIC_ARGS *args, void (*print_help)(void)) { int bad_args = 0, parsed_args = 0, total_args = 1, i; char *params; /* Default values for options */ args->verbose = 0; args->logtofile = 0; /* Parse arguments */ for(i = 1; i < argc; i++) { if(argv[i][0] == '-') { switch(argv[i][1]) { case 'h': if(argv[i][2] != '\0') { log_error("invalid argument '%s'", argv[i]); bad_args++; break; } print_help(); return 2; case 'v': if(argv[i][2] != '\0') { log_error("invalid argument '%s'", argv[i]); bad_args++; break; } if(args->verbose) { log_error("repeated option -v"); bad_args++; break; } args->verbose = 1; break; case 'l': { if(args->logtofile) { log_error("repeated option -l"); bad_args++; break; } params = &argv[i][2]; if(strlen(params) == 0) { log_error("bad input argument -l. Missing filename."); bad_args++; } else { args->logtofile = 1; args->logfname = params; } break; } case '-': { params = &argv[i][2]; if(strcmp(params, "version")) { log_error("invalid argument '%s'", argv[i]); bad_args++; } else { print_version(progname); return 2; } break; } default: log_error("invalid argument '%s'", argv[i]); bad_args++; break; } } else { if(parsed_args == 0) { args->inputfname = argv[i]; parsed_args++; } else { log_error("invalid argument '%s'. Already given model file %s", argv[i], args->inputfname); bad_args++; } } } /* Check if parsing went well */ if(parsed_args > total_args) { log_error("%s: too many input arguments. given %d, max %d.", progname, parsed_args, total_args); } if(bad_args > 0) { log_error("%d bad input argument(s)", bad_args); return 1; } if(parsed_args < total_args) { return 3; } return 0; } /* Parse command line arguments for tessh* programs */ int parse_tessb_args(int argc, char **argv, const char *progname, TESSB_ARGS *args, void (*print_help)(const char *)) { int bad_args = 0, parsed_args = 0, total_args = 1, parsed_order = 0, parsed_ratio1 = 0, parsed_ratio2 = 0, parsed_ratio3 = 0, i, nchar, nread; char *params; /* Default values for options */ args->verbose = 0; args->logtofile = 0; args->lon_order = 2; args->lat_order = 2; args->r_order = 2; args->adaptative = 1; args->ratio1 = 0; /* zero means use the default for the program */ args->ratio2 = 0; args->ratio3 = 0; /* Parse arguments */ for(i = 1; i < argc; i++) { if(argv[i][0] == '-') { switch(argv[i][1]) { case 'h': if(argv[i][2] != '\0') { log_error("invalid argument '%s'", argv[i]); bad_args++; break; } print_help(progname); return 2; case 'v': if(argv[i][2] != '\0') { log_error("invalid argument '%s'", argv[i]); bad_args++; break; } if(args->verbose) { log_error("repeated option -v"); bad_args++; break; } args->verbose = 1; break; case 'l': { if(args->logtofile) { log_error("repeated option -l"); bad_args++; break; } params = &argv[i][2]; if(strlen(params) == 0) { log_error("bad input argument -l. Missing filename."); bad_args++; } else { args->logtofile = 1; args->logfname = params; } break; } case '-': { params = &argv[i][2]; if(strcmp(params, "version")) { log_error("invalid argument '%s'", argv[i]); bad_args++; } else { print_version(progname); return 2; } break; } case 'a': if(argv[i][2] != '\0') { log_error("invalid argument '%s'", argv[i]); bad_args++; break; } if(!args->adaptative) { log_error("repeated option -a"); bad_args++; break; } args->adaptative = 0; break; case 'o': { if(parsed_order) { log_error("repeated option -o"); bad_args++; break; } params = &argv[i][2]; nchar = 0; nread = sscanf(params, "%d/%d/%d%n", &(args->lon_order), &(args->lat_order), &(args->r_order), &nchar); if(nread != 3 || *(params + nchar) != '\0') { log_error("bad input argument '%s'", argv[i]); bad_args++; } parsed_order = 1; break; } case 't': { //ELDAR BAYKIEV/////////////////////////////////////////////////////////////////// switch(argv[i][2]) { case '1': { if(parsed_ratio1) { log_error("repeated option -t1"); bad_args++; break; } params = &argv[i][3]; nchar = 0; nread = sscanf(params, "%lf%n", &(args->ratio1), &nchar); if(nread != 1 || *(params + nchar) != '\0') { log_error("bad input argument '%s'", argv[i]); bad_args++; } parsed_ratio1 = 1; break; } case '2': { if(parsed_ratio2) { log_error("repeated option -t2"); bad_args++; break; } params = &argv[i][3]; nchar = 0; nread = sscanf(params, "%lf%n", &(args->ratio2), &nchar); if(nread != 1 || *(params + nchar) != '\0') { log_error("bad input argument '%s'", argv[i]); bad_args++; } parsed_ratio2 = 1; break; } case '3': { if(parsed_ratio3) { log_error("repeated option -t3"); bad_args++; break; } params = &argv[i][3]; nchar = 0; nread = sscanf(params, "%lf%n", &(args->ratio3), &nchar); if(nread != 1 || *(params + nchar) != '\0') { log_error("bad input argument '%s'", argv[i]); bad_args++; } parsed_ratio3 = 1; break; } } //ELDAR BAYKIEV/////////////////////////////////////////////////////////////////// } default: log_error("invalid argument '%s'", argv[i]); bad_args++; break; } } else { if(parsed_args == 0) { args->modelfname = argv[i]; parsed_args++; } else { log_error("invalid argument '%s'. Already given model file %s", argv[i], args->modelfname); bad_args++; } } } /* Check if parsing went well */ if(bad_args > 0 || parsed_args != total_args) { if(parsed_args < total_args) { log_error("%s: missing input file.", progname, parsed_args, total_args); } if(parsed_args > total_args) { log_error("%s: too many input arguments. given %d, max %d.", progname, parsed_args, total_args); } if(bad_args > 0) { log_error("%d bad input argument(s)", bad_args); } return 1; } return 0; } //parse arguments for gradient calculator int parse_gradcalc_args(int argc, char **argv, const char *progname, GRADCALC_ARGS *args, void (*print_help)(const char *)) { int bad_args = 0, parsed_args = 0, total_args = 5, i; char *params; /* Default values for options */ args->verbose = 0; args->logtofile = 0; args->gridbx_set = FALSE; args->gridby_set = FALSE; args->gridbz_set = FALSE; args->out_set = -1; args->bz_NEU_NED = -1; args->bz_NEU_NED_set = FALSE; /* Parse arguments */ for(i = 1; i < argc; i++) { if(argv[i][0] == '-') { switch(argv[i][1]) { case 'h': if(argv[i][2] != '\0') { //log_error("invalid argument '%s'", argv[i]); printf("invalid argument '%s'\n", argv[i]); bad_args++; break; } print_help(progname); return 2; case '-': { params = &argv[i][2]; if(strcmp(params, "version")) { printf("invalid argument '%s'\n", argv[i]); bad_args++; } else { print_version(progname); return 2; } break; } case 'b': params = &argv[i][2]; if(strlen(params) <= 1) { printf("bad input argument -b. Missing component and filename\n"); bad_args++; break; } else { switch(argv[i][2]) { case 'x': if(args->gridbx_set) { printf("invalid argument '%s', gridfile bx already set\n", argv[i]); bad_args++; break; } else { args->gridbx_set = 1; args->gridbx_fn = &argv[i][3]; } break; case 'y': if(args->gridby_set) { printf("invalid argument '%s', gridfile by already set\n", argv[i]); bad_args++; break; } else { args->gridby_set = 1; args->gridby_fn = &argv[i][3]; } break; case 'z': if(args->gridbz_set) { printf("invalid argument '%s', gridfile by already set\n", argv[i]); bad_args++; break; } else { args->gridbz_set = 1; args->gridbz_fn = &argv[i][3]; } break; default: printf("invalid argument '%s', wrong component\n", argv[i]); bad_args++; break; } } break; case 'c': params = &argv[i][2]; if(args->bz_NEU_NED_set) { printf("invalid argument '%s', coordinate system is already set\n", argv[i]); bad_args++; break; } if(strlen(params) > 1) { printf("invalid argument '%s', specify coordinate system in the input grids\n", argv[i]); bad_args++; break; } if(argv[i][2] == '1') { args->bz_NEU_NED_set = 1; args->bz_NEU_NED = 1; break; } else if(argv[i][2] == '2') { args->bz_NEU_NED_set = 1; args->bz_NEU_NED = -1; break; } else { printf("invalid argument '%s', there are only NED (1) and NEU (2, default) coordinate systems\n", argv[i]); bad_args++; break; } break; case 'o': params = &argv[i][2]; if(args->out_set>=0) { printf("invalid argument '%s', output format is already set\n", argv[i]); bad_args++; break; } if(strlen(params) != 1) { printf("invalid argument '%s', specify output format\n", argv[i]); bad_args++; break; } //TODO Add check if it is integer args->out_set = atoi(params); break; default: printf("invalid argument '%s'\n", argv[i]); bad_args++; break; } } } if(parsed_args > total_args) { //log_error("%s: too many input arguments. given %d, max %d.", progname, parsed_args, total_args); } if(bad_args > 0) { //log_error("%d bad input argument(s)", bad_args); return 1; } if(parsed_args < total_args) { return 3; } return 0; } /* Strip trailing spaces and newlines from the end of a string */ void strstrip(char *str) { int i; for(i = strlen(str) - 1; i >= 0; i--) { if(str[i] != ' ' && str[i] != '\n' && str[i] != '\r' && str[i] != '\0') break; } str[i + 1] = '\0'; } /* Read a single tesseroid from a string */ int gets_mag_tess(const char *str, MAG_TESSEROID *tess) { double w, e, s, n, top, bot, dens, suscept, Bx, By, Bz, Rx, Ry, Rz; int nread, nchars; nread = sscanf(str, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf%n", &w, &e, &s, &n, &top, &bot, &dens, &suscept, &Bx, &By, &Bz, &nchars); if(nread != 11 || str[nchars] != '\0') { return 1; } tess->w = w; tess->e = e; tess->s = s; tess->n = n; tess->r1 = MEAN_EARTH_RADIUS + bot; tess->r2 = MEAN_EARTH_RADIUS + top; tess->density = dens; tess->suscept = suscept; tess->Bx = Bx; tess->By = By; tess->Bz = Bz; tess->cos_a1 = cos(PI/2.0-DEG2RAD*(w+e)*0.5); tess->sin_a1 = sin(PI/2.0-DEG2RAD*(w+e)*0.5); tess->cos_b1 = cos(DEG2RAD*(s+n)*0.5); tess->sin_b1 = sin(DEG2RAD*(s+n)*0.5); return 0; } //ELDAR BAYKIEV//////////////////////////////// MAG_TESSEROID * read_mag_tess_model(FILE *modelfile, int *size) { MAG_TESSEROID *model, *tmp; int buffsize = 300, line, badinput = 0, error_exit = 0; char sbuff[10000]; /* Start with a single buffer allocation and expand later if necessary */ model = (MAG_TESSEROID *)malloc(buffsize*sizeof(MAG_TESSEROID)); if(model == NULL) { log_error("problem allocating initial memory to load tesseroid model."); return NULL; } *size = 0; for(line = 1; !feof(modelfile); line++) { if(fgets(sbuff, 10000, modelfile) == NULL) { if(ferror(modelfile)) { log_error("problem encountered reading line %d.", line); error_exit = 1; break; } } else { /* Check for comments and blank lines */ if(sbuff[0] == '#' || sbuff[0] == '\r' || sbuff[0] == '\n') { continue; } if(*size == buffsize) { buffsize += buffsize; tmp = (MAG_TESSEROID *)realloc(model, buffsize*sizeof(MAG_TESSEROID)); if(tmp == NULL) { /* Need to free because realloc leaves unchanged in case of error */ free(model); log_error("problem expanding memory for tesseroid model.\nModel is too big."); return NULL; } model = tmp; } /* Remove any trailing spaces or newlines */ strstrip(sbuff); if(gets_mag_tess(sbuff, &model[*size])) { log_warning("bad/invalid tesseroid at line %d.", line); badinput = 1; continue; } (*size)++; } } if(badinput || error_exit) { free(model); return NULL; } /* Adjust the size of the model */ if(*size != 0) { tmp = (MAG_TESSEROID *)realloc(model, (*size)*sizeof(MAG_TESSEROID)); if(tmp == NULL) { /* Need to free because realloc leaves unchanged in case of error */ free(model); log_error("problem freeing excess memory for tesseroid model."); return NULL; } model = tmp; } return model; } /* Read a single rectangular prism from a string */