/* qi_make - convert a sequential file to a format suitable for a qi build */ /* 1993/08/30 release for beta testing */ /* 1993/09/13 added long input records & fields, "\n" newline token in fields */ #include stdio #include string #include ctype #include "qi.h" #define MAX_PARAMS 100 int recsz, fldsz; struct param { int pos; int size; int field; int cap; int bz; char *pre; char *post; } params[MAX_PARAMS + 1]; void cap(char *); void trim(char *); main(int argc, char *argv[]) { FILE *in, *out; char *record, *field, *new_field; char filename[256], temp[256], *cp, *fld; int pidx, index, sequence; if (argc < 3) { printf("Usage: make input output [base]\n"); exit(); } strcpy(filename, argv[1]); if (cp = strchr(filename, '.')) *cp = '\0'; strcat(filename, ".qi_make"); if (read_params(filename) == FALSE) { sprintf(temp, "can't open parameter file %s", filename); perror(temp); exit(); } record = malloc(++recsz); field = malloc(fldsz); new_field = malloc(fldsz); if ((in = fopen(argv[1], "r")) == NULL) { perror("Can't open input file"); exit(); } if ((out = fopen(argv[2], "w")) == NULL) { perror("Can't open output file"); exit(); } if (argc == 4) index = atoi(argv[3]); else index = 0; printf("Convert qi data from %s to %s\n", argv[1], argv[2]); printf("ID base set to %d\n", index); while (fgets(record, recsz, in)) { index++; /* it really starts at 1 */ if ((index % 100) == 0) printf("%d\n", index); for (pidx = 0; params[pidx].size >= 0; pidx++) { strncpy(field, "", fldsz); strncpy(field, record + params[pidx].pos, params[pidx].size); if (params[pidx].cap) cap(field); trim(field); if ((params[pidx].size == 0) || ((strlen(field) > 0) && (!params[pidx].bz || (atoi(field) > 0)))) { strcpy(new_field, params[pidx].pre); strcat(new_field, field); strcat(new_field, params[pidx].post); sequence = 0; fld = new_field; for (;;) { if (cp = strstr(fld, "\\n")) *cp = '\0'; fprintf(out, "%0*d%0*d%0*d%0*d%s\n", ID_SIZE, index, FIELD_SIZE, params[pidx].field, SEQ_SIZE, sequence++, ATTR_SIZE, 0, fld); if (cp == NULL) break; fld = cp + 2; } } } } fclose(in); fclose(out); } void strxcpy(char *dest, char *src, int cnt) { if (cnt == 0) return; for (;*src; src++) { if ((*src != '\\') || (*(src + 1) != ',')) *dest++ = *src; if (--cnt == 0) break; } } int read_params(char *name) { FILE *fp; int ind = 0; char *cp, *cp2, val[10], line[256]; fp = fopen(name, "r"); if (fp == NULL) return (FALSE); while (fgets(line, sizeof(line), fp)) { if (line[0] == '#') continue; cp = line; cp2 = strchr(cp,','); strncpy(val, "", sizeof(val)); strncpy(val, cp, cp2 - cp); params[ind].pos = atoi(val) - 1; /* origin 0 into field */ cp = cp2 + 1; cp2 = strchr(cp,','); strncpy(val, "", sizeof(val)); strncpy(val, cp, cp2 - cp); params[ind].size = atoi(val); cp = cp2 + 1; cp2 = strchr(cp,','); strncpy(val, "", sizeof(val)); strncpy(val, cp, cp2 - cp); params[ind].field = atoi(val); cp = cp2 + 1; cp2 = strchr(cp,','); if (cp2 == NULL) cp2 = strchr(cp, '\0'); strncpy(val, "", sizeof(val)); strncpy(val, cp, cp2 - cp); params[ind].cap = atoi(val); cp = cp2 + 1; cp2 = strchr(cp,','); if (cp2 == NULL) cp2 = strchr(cp, '\0'); strncpy(val, "", sizeof(val)); strncpy(val, cp, cp2 - cp); params[ind].bz = atoi(val); cp = cp2 + 1; /* find comma, but skip over '\,' */ for (cp2 = cp; *cp2; cp2++) if ((*cp2 == '\\') && (*(cp2 + 1) == ',')) cp2++; else if (*cp2 == ',') break; params[ind].pre = calloc((cp2 - cp) + 1, sizeof(char)); strxcpy(params[ind].pre, cp, cp2 - cp); cp = cp2 + 1; for (cp2 = cp; *cp2; cp2++) if ((*cp2 == '\\') && (*(cp2 + 1) == ',')) cp2++; else if (*cp2 == ',') break; params[ind].post = calloc((cp2 - cp) + 1, sizeof(char)); strxcpy(params[ind].post, cp, cp2 - cp); cp = cp2 + 1; if (recsz < (params[ind].pos + params[ind].size + 1)) recsz = (params[ind].pos + params[ind].size + 1); if (fldsz < (params[ind].size + strlen(params[ind].pre) + strlen(params[ind].post) + 1)) fldsz = (params[ind].size + strlen(params[ind].pre) + strlen(params[ind].post) + 1); if (++ind == MAX_PARAMS) { printf("Parameter file contains more than %d rules\n", MAX_PARAMS); break; } } params[ind].size = -1; fclose(fp); return (TRUE); } void trim(char *s) { while ((strlen(s) > 0) && (s[strlen(s)-1] == ' ')) s[strlen(s)-1] = '\0'; } void cap(char *s) { char *ptr; *s = _toupper(*s); for (ptr = s + 1; *ptr; ptr++) { *ptr = _tolower(*ptr); if (*ptr == ',') *ptr = ' '; if (!isalnum(*(ptr - 1))) *ptr = _toupper(*ptr); if ((*(ptr - 1) == 'I') && (*ptr == 'i')) *ptr = _toupper(*ptr); } } .