|
|
1.1 ! root 1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ ! 2: ! 3: /* ! 4: $Header: b3fil.c,v 1.4 85/08/27 10:56:00 timo Exp $ ! 5: */ ! 6: ! 7: /* Facilities supplied by the file system */ ! 8: ! 9: #include "b.h" ! 10: #include "b0con.h" ! 11: #include "b0fea.h" ! 12: #include "b0fil.h" ! 13: #include "b1obj.h" ! 14: #include "b3scr.h" ! 15: #include "b3err.h" ! 16: #include "b3fil.h" ! 17: ! 18: #ifndef INTEGRATION ! 19: ! 20: /*This file defines the facilities needed for dealing with files, ! 21: apart from C's standard I/O facilities which are used throughout the system. ! 22: ! 23: Units are held on files in a 'workspace', which on Unix is modelled ! 24: using directories. The function 'f_uname' converts a unit name into a ! 25: unique filename. On Unix this is done by prepending a character to the unit ! 26: name to indicate the kind of unit (for how'to ', and for tests and yields ! 27: < for zeroadic, " for monadic and > for dyadic; these have been chosen as ! 28: characters that are not usually used in filenames), and truncating the ! 29: name if necessary. If the name does have to be truncated, then it is ! 30: hashed to produce a character that is appended to the filename, in an attempt ! 31: to produce a unique filename. Even so, it is still possible for different ! 32: unit names to produce the same filename, and in the unlikely event of this ! 33: happening you get an error message that the unit already exists when you ! 34: try to create the clashing unit name. ! 35: ! 36: Filenames are at most SAFEFNLEN characters long, which on standard Unix ! 37: systems gives you one spare character for making backups or whatever. ! 38: ! 39: It would be better if the B system effectively maintained its own directories ! 40: that mapped units onto files in the real file system, as is done for targets. ! 41: With operating systems with a more limited file system (eg even shorter ! 42: filenames) this is the only possibility. ! 43: ! 44: The B system can operate in two ways: with the interpreter in command, ! 45: and then the editor is called from the interpreter to edit units; ! 46: and with the editor in command, when the editor calls the interpreter to ! 47: execute commands. The variable 'filtered' is Yes when the editor is in ! 48: command, and No otherwise. ! 49: */ ! 50: ! 51: #define COML 60 ! 52: Hidden char com_line[COML]; ! 53: #define At_eos(s) ((s)+= strlen(s)) ! 54: ! 55: Visible Procedure f_edit(fname, errline) value fname; intlet errline; { ! 56: /*The default editor is called with a first parameter of the line number ! 57: and a second parameter of the file name*/ ! 58: string cl= com_line; char c; ! 59: #ifdef unix ! 60: if (filtered) { ! 61: printf("\001: +%d %s\n", errline, strval(fname)); ! 62: fflush(stdout); ! 63: do { c= fgetc(stdin); } while (c != '\n'); ! 64: still_ok= Yes; /*ignore interrupts that occurred*/ ! 65: } else { ! 66: strcpy(cl, editorfile); ! 67: if (*(cl+strlen(cl)-1) == '+') { ! 68: if (errline != 0) sprintf(At_eos(cl), "%d", errline); ! 69: else *(cl+strlen(cl)-1)= ' '; ! 70: } ! 71: app_fname(At_eos(cl), fname); ! 72: system(com_line); ! 73: } ! 74: #else !unix ! 75: fprintf(stderr, "*** Editing units not yet implemented\n"); ! 76: #endif unix ! 77: } ! 78: ! 79: #else INTEGRATION ! 80: ! 81: Visible Procedure ! 82: f_edit(fname, errline, prompt) ! 83: value fname; intlet errline; literal prompt; ! 84: { ! 85: string filename= Str(fname); ! 86: btop(&filename, errline, prompt, 0); ! 87: still_ok= Yes; ! 88: } ! 89: ! 90: #endif ! 91: ! 92: Visible bool ws_writable() { ! 93: FILE *f= fopen(tempfile, "w"); ! 94: if (f == NULL) return No; ! 95: fclose(f); ! 96: return Yes; ! 97: } ! 98: ! 99: Hidden bool f_copy(fname, sname) value fname, sname; { ! 100: string fn= strval(fname), sn; ! 101: FILE *fp= fopen(fn, "r"), *sp; int c; bool ok; ! 102: if (fp == NULL) return No; ! 103: sn= strval(sname); ! 104: sp= fopen(sn, "w"); ! 105: if (sp == NULL) { ! 106: fclose(fp); ! 107: return No; ! 108: } ! 109: while ((c= getc(fp)) != EOF) ! 110: putc(c, sp); ! 111: fclose(fp); ! 112: ok= fflush(sp) != EOF; ! 113: if (fclose(sp) == EOF) ! 114: ok= No; ! 115: return ok; ! 116: } ! 117: ! 118: Visible value f_save(fname) value fname; { ! 119: /* saves the file in a temporary file, whose name is returned */ ! 120: value sname= mk_text(tempfile); ! 121: VOID f_copy(fname, sname); ! 122: return sname; ! 123: } ! 124: ! 125: Visible Procedure f_rename(fname, nfname) value fname, nfname; { ! 126: char *f1, f2[100]; ! 127: strcpy(f2, strval(nfname)); ! 128: unlink(f2); ! 129: f1= strval(fname); ! 130: #ifndef RENAME ! 131: link(f1, f2); ! 132: unlink(f1); ! 133: #else ! 134: rename(f1, f2); ! 135: #endif ! 136: /* what if it fails??? */ ! 137: } ! 138: ! 139: Visible Procedure f_delete(fname) value fname; { ! 140: unlink(strval(fname)); ! 141: } ! 142: ! 143: Visible bool ! 144: f_exists(file) ! 145: string file; ! 146: { ! 147: FILE *f= fopen(file, "r"); ! 148: if (f==NULL) return No; ! 149: fclose(f); ! 150: return Yes; ! 151: } ! 152: ! 153: #ifndef INTEGRATION ! 154: ! 155: Hidden Procedure app_fname(ceos, fname) string ceos; value fname; { ! 156: string fp= strval(fname); intlet k, len= strlen(fp); ! 157: *ceos++= ' '; ! 158: k_Over_len { ! 159: *ceos++= '\\'; ! 160: *ceos++= *fp++; /*should really use charval(thof(...))*/ ! 161: } ! 162: *ceos= '\0'; ! 163: } ! 164: ! 165: #endif ! 166: ! 167: Visible unsigned f_size(ifile) FILE *ifile; { ! 168: long size, ftell(); ! 169: fseek(ifile, 0l, 2); ! 170: size= ftell(ifile); ! 171: fseek(ifile, 0l, 0); /* rewind */ ! 172: return size; ! 173: } ! 174: ! 175: Visible Procedure f_close(ofile) FILE *ofile; { ! 176: bool ok= fflush(ofile) != EOF; ! 177: if (fclose(ofile) == EOF || !ok) ! 178: error(MESS(3203, "write error (disk full?)")); ! 179: } ! 180: ! 181: Visible bool f_interactive(ifile) FILE *ifile; { ! 182: #ifdef ISATTY ! 183: return isatty(fileno(ifile)); ! 184: #else ! 185: return fileno(ifile) < 3; ! 186: #endif ! 187: } ! 188: ! 189: #ifdef IBMPC ! 190: ! 191: #define FNMLEN 8 ! 192: #define TYPLEN 3 ! 193: #define SPCLEN 1 ! 194: ! 195: #define FHW "how" ! 196: #define FZR "zer" ! 197: #define FMN "mon" ! 198: #define FDY "dya" ! 199: #define FTR "tar" ! 200: ! 201: Hidden string ! 202: filetype(type) ! 203: literal type; ! 204: { ! 205: switch (type) { ! 206: case Zer: return FZR; ! 207: case Mon: return FMN; ! 208: case Dya: return FDY; ! 209: case How: return FHW; ! 210: case Tar: return FTR; ! 211: default: syserr(MESS(3200, "filetype()")); ! 212: /* NOTREACHED */ ! 213: } ! 214: } ! 215: ! 216: Hidden Procedure ! 217: cr_fname(name, type, fname, len, pname) ! 218: value name; string fname, *pname; literal type; int len; ! 219: { ! 220: *pname= fname; ! 221: strncpy(*pname, strval(name), len); ! 222: sprintf(fname + len, ".%s", filetype(type)); ! 223: } ! 224: ! 225: #endif IBMPC ! 226: ! 227: #ifdef unix ! 228: ! 229: #define FNMLEN 12 ! 230: #define TYPLEN 1 ! 231: #define SPCLEN 0 ! 232: ! 233: #define FHW '\'' ! 234: #define FZR '<' ! 235: #define FMN '"' ! 236: #define FDY '>' ! 237: #define FTR '=' ! 238: ! 239: Hidden literal ! 240: filetype(type) ! 241: literal type; ! 242: { ! 243: switch (type) { ! 244: case Zer: return FZR; ! 245: case Mon: return FMN; ! 246: case Dya: return FDY; ! 247: case How: return FHW; ! 248: case Tar: return FTR; ! 249: default: syserr(MESS(3201, "filetype()")); ! 250: /* NOTREACHED */ ! 251: } ! 252: } ! 253: ! 254: Hidden Procedure ! 255: cr_fname(name, type, fname, len, pname) ! 256: value name; string fname, *pname; literal type; int len; ! 257: { ! 258: *fname= filetype(type); ! 259: fname[1]= '\0'; ! 260: *pname= fname + 1; ! 261: strncat(fname, strval(name), len); ! 262: } ! 263: ! 264: #endif unix ! 265: ! 266: Hidden bool ! 267: exists(name) ! 268: string name; ! 269: { ! 270: value v= mk_text(name); ! 271: bool exist= in(v, file_names); ! 272: release(v); ! 273: return exist; ! 274: } ! 275: ! 276: Visible value ! 277: new_fname(name, type) ! 278: value name; literal type; ! 279: { ! 280: char fname[FNMLEN + TYPLEN + SPCLEN + 1]; ! 281: intlet len= length(name); ! 282: string pname; ! 283: if (len > FNMLEN) len= FNMLEN; ! 284: cr_fname(name, type, fname, len, &pname); ! 285: while (exists(fname)) new(pname, len-1); ! 286: return mk_text(fname); ! 287: } ! 288: ! 289: #include <ctype.h> ! 290: ! 291: Hidden Procedure ! 292: new(name, n) ! 293: string name; int n; ! 294: { ! 295: if (n < 1) error(MESS(3202, "too many units")); ! 296: else if (!isdigit(name[n])) name[n]= '1'; ! 297: else if (name[n] != '9') ++name[n]; ! 298: else { ! 299: name[n]= '0'; ! 300: new(name, --n); ! 301: } ! 302: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.