static char rcsver[] = "$Id: vanilla.c,v 1.1.1.1 1999/10/15 19:30:36 gorelick Exp $"; static char source_path[] = "$Source: /tes/cvs/vanilla/vanilla.c,v $"; /** ** $Source: /tes/cvs/vanilla/vanilla.c,v $ ** ** $Log: vanilla.c,v $ ** Revision 1.1.1.1 1999/10/15 19:30:36 gorelick ** Version 3.0 ** ** Revision 2.2 1999/07/12 23:14:08 gorelick ** *** empty log message *** ** ** Revision 2.1 1999/02/10 04:00:50 gorelick ** *** empty log message *** ** ** Revision 2.0 1998/12/22 22:47:04 gorelick ** release version ** ** Revision 2.0 1998/12/18 01:31:40 gorelick ** release version ** ** Revision 1.13 1998/12/18 01:04:48 gorelick ** *** empty log message *** ** ** Revision 1.12 1998/12/01 22:42:06 gorelick ** *** empty log message *** ** ** Revision 1.11 1998/11/18 00:13:47 gorelick ** exit on error now. ** ** Revision 1.10 1998/11/12 22:58:55 gorelick ** first release version ** **/ #include #include #include "header.h" #include "version.h" void OutputHeader(LIST *olist); void fix_path(char *p); void CollectTables(DATASET *dataset, LIST *olist); int usage(char *prog); char *big_endian = "This executable was compiled using the _LITTLE_ENDIAN flag\n" "but is actually running on a big endian machine. You need\n" "to recompile without this flag.\n\n" "Execution Aborted.\n"; char *little_endian = "This executable was compiled without using the _LITTLE_ENDIAN flag\n" "but is actually running on a little endian machine. You need\n" "to recompile with this flag.\n\n" "Execution Aborted.\n"; /** ** Procedure order: ** ** load dataset ** set up selects ** set up engine slices ** set up output structs (needs slices) ** set up buffers **/ LIST *olist; int main(int ac, char **av) { char *d=NULL, *fields = NULL, *select = NULL; int i, j; OSTRUCT *o; DATASET *dataset; TABLE *t; char *index = NULL; /* cli option to just make an index */ SLICE **slice; SEQ keyseq; /* sequenced keys */ /** ** Test for endian-ness **/ { int i = 0x12345678; char *p = (char *)&i; if (p[0] != 0x12) { #ifndef _LITTLE_ENDIAN exit(fprintf(stderr, little_endian)); #endif } else { #ifdef _LITTLE_ENDIAN exit(fprintf(stderr, big_endian)); #endif } } if (ac == 1) { exit(usage(av[0])); } for (i = 1 ; i < ac ; i++) { if (av[i] == NULL) continue; if (av[i][0] == '-') { if (!strcmp(av[i], "-fields")) { fields = av[i+1]; av[i+1] = NULL; } else if (!strcmp(av[i], "-select")) { select = av[i+1]; av[i+1] = NULL; } else if (!strcasecmp(av[i], "-v")) { printf("%s\n", version); exit(1); } else if (!strcasecmp(av[i], "-index")) { index = av[i+1]; av[i+1] = NULL; } } else { d = av[i]; } } /** ** Load the specified dataset **/ if (d == NULL) exit(fprintf(stderr, "No directory specified\n")); fix_path(d); if ((dataset = LoadDataset(NULL, d)) == NULL) exit(fprintf(stderr, "Unable to load dataset: %s\n", d)); if (dataset->tables->number == 0) { exit(fprintf(stderr, "No tables in dataset.\n")); } if (index) { /* ** Just index the specified field(s) and move on. */ Make_Index(index, dataset->tables); exit(1); } /** ** Convert and user specified select strings **/ if (select != NULL) { if (ConvertSelect(dataset, select) == 0) exit(1); } /** ** init the output structures **/ olist = ConvertOutput(fields, dataset->tables); /** ** Limit tables to be only those we care about (selects & output) **/ CollectTables(dataset, olist); if (olist->number == 0) { exit(1); } sequence_keys(&keyseq, (TABLE **)dataset->tables->ptr, dataset->tables->number); slice = init_slices((TABLE **)dataset->tables->ptr, dataset->tables->number, keyseq); setup_output_parameters((OSTRUCT **)olist->ptr, olist->number, 0); /* ** Give each field a handle to it's data slice */ for (i = 0 ; i < olist->number ; i++) { o = olist->ptr[i]; if (o->table == NULL) { /* ** FakeFields have no table; just continue; */ continue; } else { for (j = 0 ; j < dataset->tables->number ; j++) { t = dataset->tables->ptr[j]; if (o->table == t) { o->slice = &slice[keyseq.count][j]; } } } } OutputHeader(olist); search(0, keyseq.count, slice, (TABLE **)dataset->tables->ptr, dataset->tables->number); return 0; } void generate_output() { output_rec((OSTRUCT **)olist->ptr, olist->number); fflush(stdout); } /** ** CollectTables() ** ** Flag list of tables that have either a select or at least 1 output field ** Replace the dataset's list of tables with the new list **/ void CollectTables(DATASET *dataset, LIST *olist) { LIST *list = new_list(); LIST *t = dataset->tables; int *x; int i,j; TABLE *t1, *t2; OSTRUCT *o; x = calloc(t->number, sizeof(int)); for (i = 0 ; i < t->number ; i++) { if (((TABLE **)t->ptr)[i]->selects) x[i]++; } for (i = 0 ; i < t->number ; i++) { t1 = ((TABLE **)(t->ptr))[i]; for (j = 0 ; j < olist->number ; j++) { o = ((OSTRUCT **)(olist->ptr))[j]; /* ** In the case of a fake field, all its constituent fields ** follow right after it, so skip this one */ if (o->field->fakefield) { continue; } t2 = o->field->label->table; if (t2 == t1) { x[i]++; break; } } } for (i = 0 ; i < t->number ; i++) { if (x[i]) { list_add(list, ((TABLE **)t->ptr)[i]); } } list_free(dataset->tables); dataset->tables = list; } char *usage_str = "%s\n" "usage: %s [options] directory\n" "\n" "Options:\n" "-fields 'field1 field2 ...' (required)\n" "-select 'field1 low high field2 low high ...' (required)\n"; int usage(char *prog) { fprintf(stderr, usage_str, version, prog); return(-1); } void OutputHeader(LIST *olist) { int i,j; int n = olist->number; OSTRUCT *o; for (j = 0 ; j < n ; j++) { o = ListElement(OSTRUCT *, olist, j); if (o->field->dimension > 0 || o->field->vardata) { /* An array field */ if (o->cooked.range.end < 0) { printf("%s[...]", o->text); } else { for (i = o->cooked.range.start; i <= o->cooked.range.end; i++){ printf("%s[%d]", o->text, i); if (i != o->cooked.range.end) printf("%c", O_DELIM); } } } else { printf("%s", o->text); } /* ** Skip dependents of fakefields */ if (o->field->fakefield) { j+= o->field->fakefield->nfields; } if (j != n) printf("%c", O_DELIM); } printf("\n"); } void fix_path(char *p) { while(p && *p) { if (*p == '\\') *p = '/'; p++; } }