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