|
|
1.1 ! root 1: # include <stdio.h> ! 2: # include "strfile.h" ! 3: ! 4: /* ! 5: * This program takes a file composed of strings seperated by ! 6: * lines starting with two consecutive delimiting character (default ! 7: * character is '%') and creates another file which consists of a table ! 8: * describing the file (structure from "strfile.h"), a table of seek ! 9: * pointers to the start of the strings, and the strings, each terinated ! 10: * by a null byte. Usage: ! 11: * ! 12: * % strfile [ - ] [ -cC ] [ -sv ] sourcefile [ datafile ] ! 13: * ! 14: * - - Give a usage summary useful for jogging the memory ! 15: * c - Change delimiting character from '%' to 'C' ! 16: * s - Silent. Give no summary of data processed at the end of ! 17: * the run. ! 18: * v - Verbose. Give summary of data processed. (Default) ! 19: * ! 20: * Ken Arnold Sept. 7, 1978 ! 21: * ! 22: * Added method to indicate dividers. A "%-" will cause the address ! 23: * to be added to the structure in one of the pointer elements. ! 24: */ ! 25: ! 26: # define reg register ! 27: ! 28: # define DELIM_CH '-' ! 29: ! 30: char *infile = 0, /* input file name */ ! 31: outfile[100] = "", /* output file name */ ! 32: delimch = '%', /* delimiting character */ ! 33: *usage[] = { /* usage summary */ ! 34: "usage: strfile [ - ] [ -cC ] [ -sv ] inputfile [ datafile ]", ! 35: " - - Give this usage summary", ! 36: " c - Replace delimiting character with 'C'", ! 37: " s - Silent. Give no summary", ! 38: " v - Verbose. Give summary. (default)", ! 39: " Default \"datafile\" is inputfile.dat", ! 40: 0 ! 41: }, ! 42: *fgets(); ! 43: ! 44: short sflag = 0; /* silent run flag */ ! 45: ! 46: long ftell(), *calloc(); ! 47: ! 48: STRFILE tbl; /* statistics table */ ! 49: ! 50: main(ac, av) ! 51: int ac; ! 52: char *av[]; { ! 53: ! 54: reg char *sp, dc; ! 55: reg long *lp; ! 56: char string[257]; ! 57: int curseek, /* number of strings */ ! 58: delim; /* current delimiter number */ ! 59: long *seekpts,li; /* table of seek pointers */ ! 60: FILE *inf, *outf; ! 61: ! 62: getargs(ac, av); /* evalute arguments */ ! 63: ! 64: /* ! 65: * initial counting of input file ! 66: */ ! 67: ! 68: dc = delimch; ! 69: if ((inf = fopen(infile, "r")) == NULL) { ! 70: perror(infile); ! 71: exit(-1); ! 72: } ! 73: for (curseek = 0; (sp = fgets(string, 256, inf)) != NULL; ) ! 74: if (*sp++ == dc && (*sp == dc || *sp == DELIM_CH)) ! 75: curseek++; ! 76: curseek++; ! 77: ! 78: /* ! 79: * save space at begginning of file for tables ! 80: */ ! 81: ! 82: if ((outf = fopen(outfile, "w")) == NULL) { ! 83: perror(outfile); ! 84: exit(-1); ! 85: } ! 86: if ((seekpts = calloc(sizeof *seekpts, curseek)) == NULL) { ! 87: perror("calloc"); ! 88: exit(-1); ! 89: } ! 90: fwrite(&tbl, sizeof tbl, 1, outf); ! 91: fwrite(seekpts, sizeof *seekpts, curseek, outf); ! 92: *seekpts = ftell(outf); ! 93: fseek(inf, (long) 0, 0); /* goto start of input */ ! 94: ! 95: /* ! 96: * write the strings onto the file ! 97: */ ! 98: ! 99: tbl.str_longlen = -1; ! 100: tbl.str_shortlen = 0077777; ! 101: lp = seekpts; ! 102: do { ! 103: sp = fgets(string, 256, inf); ! 104: if (sp == NULL ! 105: || (*sp == dc && (sp[1] == dc || sp[1] == DELIM_CH))) { ! 106: putc('\0', outf); ! 107: lp++; ! 108: if (sp != NULL) ! 109: *lp = ftell(outf); ! 110: li = ftell(outf) - lp[-1] - 1; ! 111: if (tbl.str_longlen < li) ! 112: tbl.str_longlen = li; ! 113: if (tbl.str_shortlen > li) ! 114: tbl.str_shortlen = li; ! 115: if (sp[1] == DELIM_CH && delim < MAXDELIMS) ! 116: tbl.str_delims[delim++] = lp - seekpts; ! 117: } ! 118: else ! 119: fputs(sp, outf); ! 120: } while (sp != NULL); ! 121: ! 122: /* ! 123: * write the tables in ! 124: */ ! 125: ! 126: fclose(inf); ! 127: tbl.str_numstr = curseek; ! 128: fseek(outf, (long) 0, 0); ! 129: fwrite(&tbl, sizeof tbl, 1, outf); ! 130: fwrite(seekpts, sizeof *seekpts, curseek, outf); ! 131: fclose(outf); ! 132: if (!sflag) { ! 133: printf("\"%s\" converted to \"%s\"\n", infile, outfile); ! 134: if (curseek == 1) ! 135: puts("There was 1 string"); ! 136: else ! 137: printf("There were %d strings\n", curseek); ! 138: printf("Longest string: %d byte%s", tbl.str_longlen, tbl.str_longlen == 1 ? "\n" : "s\n"); ! 139: printf("Shortest string: %d byte%s", tbl.str_shortlen, tbl.str_shortlen == 1 ? "\n" : "s\n"); ! 140: } ! 141: } ! 142: /* ! 143: * This routine evaluates arguments from the command line ! 144: */ ! 145: getargs(ac, av) ! 146: int ac; ! 147: char *av[]; { ! 148: ! 149: reg char **argv, *sp; ! 150: reg int i; ! 151: int bad, j; ! 152: ! 153: bad = 0; ! 154: argv = &av[0]; ! 155: for (i = 1; i < ac; i++) ! 156: if (*argv[i] == '-') ! 157: if (argv[i][1]) for (sp = &argv[i][1]; *sp; sp++) ! 158: switch (*sp) { ! 159: case 'c': /* new delimiting char */ ! 160: if ((delimch = *++sp) == '\0') { ! 161: --sp; ! 162: delimch = *argv[++i]; ! 163: } ! 164: if (delimch <= 0 || delimch > '~' || delimch == DELIM_CH) { ! 165: printf("bad delimiting character: \\%o\n", delimch); ! 166: bad++; ! 167: } ! 168: break; ! 169: case 's': /* silent */ ! 170: sflag++; ! 171: break; ! 172: case 'v': /* verbose */ ! 173: sflag = 0; ! 174: break; ! 175: default: /* unknown flag */ ! 176: bad++; ! 177: printf("bad flag: '%c'\n", *sp); ! 178: break; ! 179: } ! 180: else { ! 181: for (j = 0; usage[j]; j++) ! 182: puts(usage[j]); ! 183: exit(0); ! 184: } ! 185: else if (infile) ! 186: strcpy(outfile, argv[i]); ! 187: else ! 188: infile = argv[i]; ! 189: if (!infile) { ! 190: bad++; ! 191: puts("No input file name"); ! 192: } ! 193: if (*outfile == '\0' && !bad) { ! 194: strcpy(outfile, infile); ! 195: strcat(outfile, ".dat"); ! 196: } ! 197: if (bad) { ! 198: puts("use \"strfile -\" to get usage"); ! 199: exit(-1); ! 200: } ! 201: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.