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