static char * test_strvdup() { const char *old_strv[] = {"default", "identity", NULL}; char **new_strv = strvdup(old_strv); mu_assert("strvdup() error!", new_strv != NULL); int i; for(i = 0; i < 3; ++i) { if(i < 2) mu_assert("strvdup() error: did not copy deeply!", new_strv[i] != old_strv[i]); mu_assert_strcmp0("strvdup() error: deep copy is incorrect!", new_strv[i], old_strv[i]); } strvfree(new_strv); return NULL; }
/* rnmrtk_read_parms(): read the parameter file corresponding to an RNMRTK * data file. * @fname: the data filename. * @par: pointer to the output parameter structure. */ int rnmrtk_read_parms (const char *fname, struct rnmrtk_parms *par) { /* declare a few required variables: * @pfname: parameter file name. * @buf: buffer holding parameter file lines. * @nfields: number of strings in the fields array. * @fields: string array of space-delimited fields. * @i: general purpose loop counter. * @fh: parameter file handle. */ char *pfname, buf[N_BUF]; unsigned int i, nfields; char **fields; FILE *fh; /* declare variables required for parsing layout lines: * @dim: main dimension index. * @sub: sub-dimension index. * @pts: point count. */ int dim, sub, pts; /* initialize the parameter structure contents. */ memset(par, 0, sizeof(struct rnmrtk_parms)); /* build the parameter filename string. */ pfname = rnmrtk_parfile(fname); /* check that the string was created successfully. */ if (!pfname) throw("failed to allocate parameter filename"); /* open the parameter file. */ fh = fopen(pfname, "rb"); /* check that the file was opened. */ if (!fh) throw("failed to open '%s'", pfname); /* loop until we've read the entire file. */ while (!feof(fh)) { /* read a new line from the file. */ if (fgets(buf, N_BUF, fh)) { /* trim trailing newlines from the string. */ strnltrim((char*) buf); /* split the line by whitespace. */ fields = strsplit(buf, " ", &nfields); /* trim the fields and convert everything to lowercase. */ strvtrim(fields, nfields); strvcompact(fields, &nfields); strvtolower(fields, nfields); /* determine which parameter line we've tokenized. */ if (strcmp(fields[0], RNMRTK_PARLINE_FORMAT) == 0) { /* parse all available format line fields. */ if (nfields >= 2) { /* parse the endianness of the data. */ if (strcmp(fields[1], RNMRTK_ENDIAN_BIG) == 0) par->endian = BYTES_ENDIAN_BIG; else if (strcmp(fields[1], RNMRTK_ENDIAN_LITTLE) == 0) par->endian = BYTES_ENDIAN_LITTLE; else throw("invalid endianness '%s'", fields[1]); } if (nfields >= 3) { /* parse the word style of the data. */ if (strcmp(fields[2], RNMRTK_WTYPE_INT) == 0) par->isflt = 0; else if (strcmp(fields[2], RNMRTK_WTYPE_FLT) == 0) par->isflt = 1; else throw("invalid word type '%s'", fields[2]); } if (nfields >= 4) { /* parse the header size. */ par->nheader = atoi(fields[3]); } if (nfields >= 5) { /* parse the record length. */ par->reclen = atoi(fields[4]); } if (nfields >= 6) { /* parse the padding size. */ par->nbegin = atoi(fields[5]); } if (nfields >= 7) { /* parse the end padding. */ par->nend = atoi(fields[6]); } } else if (strcmp(fields[0], RNMRTK_PARLINE_DOM) == 0) { /* store the number of dimensions. */ par->nd = nfields - 1; /* check the number of dimensions. */ if (par->nd < 1 || par->nd > RNMRTK_MAXDIM) throw("invalid dimension count %u", par->nd); /* parse the 'dom' line fields. */ for (i = 0; i < par->nd; i++) { /* check that the first character is 't'. */ if (fields[i + 1][0] != 't' || strlen(fields[i + 1]) < 2) throw("invalid field '%s' on '%s'", fields[i + 1], fields[0]); /* parse the dimension index. */ par->ord[i] = atoi(fields[i + 1] + 1); } } else if (strcmp(fields[0], RNMRTK_PARLINE_N) == 0) { /* check for correct field count. */ if (nfields != 2 * par->nd + 1) throw("invalid field count of %u on '%s'", nfields, fields[0]); /* parse the 'n' line fields. */ for (i = 0; i < par->nd; i++) { /* parse the size value. */ par->sz[i] = atoi(fields[2 * i + 1]); /* parse the complex flag. */ if (strcmp(fields[2 * i + 2], RNMRTK_NTYPE_REAL) == 0) par->cx[i] = 0; else if (strcmp(fields[2 * i + 2], RNMRTK_NTYPE_COMPLEX) == 0) par->cx[i] = 1; else throw("invalid real/complex field '%s'", fields[2 * i + 2]); } } else if (strcmp(fields[0], RNMRTK_PARLINE_LAYOUT) == 0) { /* parse the 'layout' line fields. */ for (i = 1; i < nfields; i++) { /* attempt to parse each layout field form. */ if (sscanf(fields[i], "t%d-%d:%d", &dim, &sub, &pts) == 3 && dim > 0 && dim <= par->nd) { /* store the parsed point count. */ par->layout[dim - 1][sub] = pts; } else if (sscanf(fields[i], "t%d:%d", &dim, &pts) == 2 && dim > 0 && dim <= par->nd) { /* store the parsed point count. */ par->layout[dim - 1][1] = pts; } else throw("invalid %s field '%s'", fields[0], fields[i]); } } else if (strcmp(fields[0], RNMRTK_PARLINE_SF) == 0) { /* check for correct field count. */ if (nfields != par->nd + 1) throw("invalid field count of %u on '%s'", nfields, fields[0]); /* parse the 'sf' line fields. */ for (i = 0; i < par->nd; i++) par->sf[i] = atof(fields[i + 1]); } else if (strcmp(fields[0], RNMRTK_PARLINE_PPM) == 0) { /* check for correct field count. */ if (nfields != par->nd + 1) throw("invalid field count of %u on '%s'", nfields, fields[0]); /* parse the 'ppm' line fields. */ for (i = 0; i < par->nd; i++) par->ppm[i] = atof(fields[i + 1]); } else if (strcmp(fields[0], RNMRTK_PARLINE_QUAD) == 0) { /* check for correct field count. */ if (nfields != par->nd + 1) throw("invalid field count of %u on '%s'", nfields, fields[0]); /* parse the 'quad' line fields. */ for (i = 0; i < par->nd; i++) { /* determine the quadrature setting. */ if (strcmp(fields[i + 1], RNMRTK_QUADSTR_TPPI) == 0) par->quad[i] = RNMRTK_QUAD_TPPI; else if (strcmp(fields[i + 1], RNMRTK_QUADSTR_STATES) == 0) par->quad[i] = RNMRTK_QUAD_STATES; else if (strcmp(fields[i + 1], RNMRTK_QUADSTR_STATESTPPI) == 0) par->quad[i] = RNMRTK_QUAD_STATESTPPI; else throw("invalid quadrature '%s'", fields[i + 1]); } } else if (strcmp(fields[0], RNMRTK_PARLINE_SW) == 0) { /* check for correct field count. */ if (nfields != par->nd + 1) throw("invalid field count of %u on '%s'", nfields, fields[0]); /* parse the 'sw' line fields. */ for (i = 0; i < par->nd; i++) par->sw[i] = atof(fields[i + 1]); } /* free the fields string array. */ strvfree(fields, nfields); } } /* close the parameter file. */ fclose(fh); /* free the parameter filename. */ free(pfname); /* return success. */ return 1; }