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: }

Defined functions

funprd_unit defined in line 232; used 1 times
howto_unit defined in line 224; used 1 times
is_target defined in line 334; used 1 times
main defined in line 96; never used
put_assoc defined in line 322; used 1 times
put_entry defined in line 285; used 7 times
put_key defined in line 302; used 1 times
quit defined in line 88; used 2 times
skip_keyword defined in line 185; used 3 times
skip_open_close defined in line 197; used 1 times
skip_space defined in line 192; used 5 times
skip_tag defined in line 178; used 3 times
skip_to_close defined in line 202; used 2 times
treat_file defined in line 130; used 2 times
treat_line defined in line 207; used 1 times
treat_target defined in line 259; used 1 times
warning defined in line 78; used 5 times

Defined variables

buffer defined in line 70; used 3 times
defargv defined in line 64; used 3 times
filename defined in line 71; used 10 times
first defined in line 71; used 7 times
last defined in line 71; used 9 times
pbuf defined in line 71; used 38 times
progname defined in line 72; used 7 times
status defined in line 73; used 3 times

Defined macros

BPERMFILE defined in line 57; used 2 times
Back_quote defined in line 299; used 1 times
CapLetter defined in line 165; used 3 times
Close defined in line 171; used 1 times
Colon defined in line 169; used 2 times
DELIM defined in line 58; used 2 times
Digit defined in line 167; used 3 times
Double defined in line 300; used 2 times
Dya defined in line 220; used 2 times
How defined in line 221; used 1 times
Keymark defined in line 174; used 1 times
Letter defined in line 166; used 5 times
Mon defined in line 219; used 2 times
Open defined in line 170; used 2 times
Oputc defined in line 75; used 19 times
Quote defined in line 168; used 3 times
Space defined in line 172; used 1 times
Tagmark defined in line 173; used 1 times
Tar defined in line 222; used 1 times
Text_quote defined in line 298; used 5 times
ToLower defined in line 176; used 1 times
Zer defined in line 218; used 1 times
defargc defined in line 65; used 2 times
index defined in line 52; used 5 times
rindex defined in line 53; used 4 times
Last modified: 1985-08-27
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1972
Valid CSS Valid XHTML 1.0 Strict