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