|
|
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.