|
|
1.1 root 1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2: /* $Header: convert.c,v 1.1 85/08/22 14:33:43 timo Exp $ */
3:
4: /*
5: * Utility to recover the contents of a B workspace.
6: *
7: * Call as: convert [\'\"\<\>=]?* (this should be done by a shell script).
8: *
9: * It constructs a completely new ".b_perm" file with references to all files
10: * mentioned (if they exist).
11: * Files whose name starts with '=' and files with an extension of ".tar"
12: * or ".TAR" are taken to be targets; all others are assumed to contain
13: * units (if they contain garbage, they are ignored). (".tar" and ".TAR"
14: * are used on the IBM-PC.)
15: * For units, the name, type and adicity are extracted from the source;
16: * for targets, the target name is taken to be the file name with all
17: * illegal characters removed (upper case converted to lowercase).
18: *
19: * BUGS:
20: * - should augment the old ".b_perm" file instead of just overwriting it;
21: * - target names can get truncated when the original target name was longer
22: * than what fits in a legal file name.
23: * - doesn't detect multiple files defining the same name
24: * - on the IBM-PC, the file name expansion should be in the program for it to
25: * be of any use, because the MS-DOS "shell" doesn't expand * in file names
26: *
27: * $Log: convert.c,v $
28: * Revision 1.1 85/08/22 14:33:43 timo
29: * Initial revision
30: *
31: * Revision 1.3.2.1 85/06/04 13:36:04 guido
32: * Create consistent branch 1.3.2.
33: *
34: * Revision 1.3 85/06/04 13:35:33 guido
35: * Added MS-DOS support.
36: *
37: * Revision 1.2 85/04/12 22:33:33 guido
38: * added treatment of targets; added warning and fatal error messages.
39: *
40: * Revision 1.1 85/01/29 12:48:09 guido
41: * used given file names instead of constructing file names from unit names.
42: *
43: * Revision --- frank
44: * created.
45: */
46:
47: #include <stdio.h>
48:
49: #ifdef MSDOS
50: #define BPERMFILE "PERM.BIF"
51: #define DELIM '\\'
52: #define index strchr
53: #define rindex strrchr
54: #endif
55:
56: #ifdef unix
57: #define BPERMFILE ".b_perm"
58: #define DELIM '/'
59: #endif
60:
61: char *rindex(), *index();
62:
63: #ifdef MSDOS
64: char *defargv[]= {"convert", "*.how", "*.zer", "*.mon", "*.dya", "*.tar", 0};
65: #define defargc (sizeof defargv/sizeof defargv[0] - 1)
66: #endif
67:
68: FILE *ofile;
69:
70: char buffer[BUFSIZ];
71: char *pbuf, *first, *last, *filename;
72: char *progname = "convert";
73: int status= 0;
74:
75: #define Oputc(c) putc(c, ofile)
76:
77: /*VARARGS1*/
78: warning(fmt, a1, a2)
79: char *fmt;
80: {
81: status= 1;
82: fprintf(stderr, "*** %s: ", progname);
83: fprintf(stderr, fmt, a1, a2);
84: fprintf(stderr, "\n");
85: }
86:
87: /*VARARGS2*/
88: quit(sts, msg, a1, a2)
89: int sts;
90: char *msg;
91: {
92: warning(msg, a1, a2);
93: exit(sts ? sts : status);
94: }
95:
96: main(argc, argv)
97: int argc; char **argv;
98: {
99: #ifndef MSDOS
100: if (argc < 2)
101: quit(2, "Usage: %s file ...", progname);
102: /* Don't do this under MSDOS -- program name is always 'c'... */
103: progname= rindex(*argv, '/');
104: if (progname)
105: ++progname;
106: else
107: progname= *argv;
108: #endif
109:
110: ofile= fopen(BPERMFILE, "w");
111: if (!ofile)
112: quit(2, "%s: can't create %s", progname, BPERMFILE);
113: Oputc('{');
114: #ifdef defargc
115: if (argc <= 1) {
116: argv= defargv;
117: argc= defargc;
118: }
119: #endif
120: while (argc > 1) {
121: --argc; ++argv;
122: treat_file(*argv);
123: }
124: Oputc('}');
125: Oputc('\n');
126: fclose(ofile);
127: exit(status);
128: }
129:
130: treat_file(file)
131: char *file;
132: {
133: FILE *ifile;
134: static int recursive= 0;
135:
136: ifile= fopen(filename= file, "r");
137: if (!ifile) {
138: if (index(filename, '*') && !recursive) {
139: /* Assume failed '*' expansion */
140: /* Ignore on UNIX, expand on MSDOS */
141: #ifdef MSDOS
142: char **list= getfiles(filename);
143: if (list) {
144: recursive= 1;
145: for (; *list; ++list)
146: treat_file(*list);
147: recursive= 0;
148: }
149: #endif
150: }
151: else
152: warning("%s: can't read", filename);
153: }
154: else {
155: if (!fgets(buffer, BUFSIZ, ifile))
156: warning("%s: empty file", filename);
157: else if (is_target(filename))
158: treat_target();
159: else
160: treat_line();
161: fclose(ifile);
162: }
163: }
164:
165: #define CapLetter ('A' <= *pbuf && *pbuf <= 'Z')
166: #define Letter ('a' <= *pbuf && *pbuf <= 'z')
167: #define Digit ('0' <= *pbuf && *pbuf <= '9')
168: #define Quote (*pbuf == '\'' || *pbuf == '"')
169: #define Colon (*pbuf == ':')
170: #define Open (*pbuf == '(')
171: #define Close (*pbuf == ')')
172: #define Space (*pbuf == ' ' || *pbuf == '\t')
173: #define Tagmark (Letter || Digit || Quote)
174: #define Keymark (CapLetter || Digit || Quote)
175:
176: #define ToLower(c) ((c) - 'A' + 'a')
177:
178: skip_tag()
179: {
180: first= pbuf;
181: while (Tagmark) pbuf++;
182: last= pbuf;
183: }
184:
185: skip_keyword()
186: {
187: first= pbuf;
188: while (Keymark) pbuf++;
189: last= pbuf;
190: }
191:
192: skip_space()
193: {
194: while (Space) pbuf++;
195: }
196:
197: skip_open_close()
198: {
199: if (Open) { skip_to_close(); pbuf++; }
200: }
201:
202: skip_to_close()
203: {
204: while (++pbuf, !Close) if (Open) skip_to_close();
205: }
206:
207: treat_line()
208: {
209: pbuf= buffer;
210: switch (*pbuf) {
211: case 'H': howto_unit(); break;
212: case 'Y':
213: case 'T': funprd_unit(); break;
214: default: warning("%s: not a valid B unit", filename); break;
215: }
216: }
217:
218: #define Zer 0
219: #define Mon 1
220: #define Dya 2
221: #define How 3
222: #define Tar 4
223:
224: howto_unit()
225: {
226: skip_keyword();
227: skip_space();
228: skip_keyword();
229: put_entry(How);
230: }
231:
232: funprd_unit()
233: {
234: skip_keyword();
235: skip_space();
236: if (Letter) {
237: skip_tag();
238: skip_space();
239: if (Colon) put_entry(Zer);
240: else if (!Letter) put_entry(Mon);
241: else {
242: char *sv_first= first, *sv_last= last;
243: skip_tag();
244: skip_space();
245: if (Colon) {
246: first= sv_first; last= sv_last;
247: put_entry(Mon);
248: } else
249: put_entry(Dya);
250: }
251: } else {
252: skip_open_close();
253: skip_space();
254: skip_tag();
255: put_entry(Dya);
256: }
257: }
258:
259: treat_target()
260: {
261: pbuf= filename;
262: #ifdef MSDOS
263: if (index(pbuf, ':'))
264: pbuf= index(pbuf, ':') + 1;
265: #endif
266: if (rindex(pbuf, DELIM))
267: pbuf= index(pbuf, DELIM) + 1;
268: first= last= buffer;
269: while (*pbuf && !Letter && !CapLetter)
270: ++pbuf;
271: for (; *pbuf; ++pbuf) {
272: if (CapLetter)
273: *last++= ToLower(*pbuf);
274: else if (Letter || Digit || Quote)
275: *last++= *pbuf;
276: else if (*pbuf == '.')
277: break; /* Stop before extension ".tar" or ".TAR" */
278: }
279: if (last == first)
280: warning("%s: cannot deduce target name", filename);
281: else
282: put_entry(Tar);
283: }
284:
285: put_entry(type)
286: int type;
287: {
288: static int first_elem= 1;
289: if (!first_elem) Oputc(';');
290: else first_elem= 0;
291: Oputc('[');
292: put_key(type);
293: Oputc(']');
294: Oputc(':');
295: put_assoc(type);
296: }
297:
298: #define Text_quote '"'
299: #define Back_quote '`'
300: #define Double(c) if ((c) == Text_quote || (c) == Back_quote) Oputc(c)
301:
302: put_key(type)
303: int type;
304: {
305: char *p= first;
306: Oputc(Text_quote);
307: switch (type) {
308: case Zer: Oputc('0'); break;
309: case Mon: Oputc('1'); break;
310: case Dya: Oputc('2'); break;
311: case How: Oputc('3'); break;
312: case Tar: Oputc('4'); break;
313: default: break;
314: }
315: while (p < last) {
316: Double(*p);
317: Oputc(*p++);
318: }
319: Oputc(Text_quote);
320: }
321:
322: put_assoc(type)
323: int type;
324: {
325: char *p= filename;
326: Oputc(Text_quote);
327: while (*p != '\0') {
328: Double(*p);
329: Oputc(*p++);
330: }
331: Oputc(Text_quote);
332: }
333:
334: is_target(name)
335: char *name;
336: {
337: if (*name == '=')
338: return 1;
339: name= rindex(name, '.');
340: if (!name)
341: return 0;
342: return strcmp(name, ".TAR") == 0 || strcmp(name, ".tar") == 0;
343: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.