/* 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);
}
}