|
|
1.1 ! root 1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ ! 2: /* $Header: b2fil.c,v 1.1 84/06/28 00:49:11 timo Exp $ */ ! 3: ! 4: /* Facilities supplied by the file system */ ! 5: ! 6: #include "b.h" ! 7: #include "b0con.h" ! 8: #include <sys/types.h> ! 9: #include <sys/stat.h> ! 10: #include "b1obj.h" ! 11: #include "b2fil.h" ! 12: #include "b2scr.h" ! 13: ! 14: /*This file defines the facilities needed for dealing with files, ! 15: apart from C's standard I/O facilities which are used throughout the system. ! 16: ! 17: Units are held on files in a 'workspace', which on Unix is modelled ! 18: using directories. The function 'f_uname' converts a unit name into a ! 19: unique filename. On Unix this is done by prepending a character to the unit ! 20: name to indicate the kind of unit (for how'to ', and for tests and yields ! 21: < for zeroadic, " for monadic and > for dyadic; these have been chosen as ! 22: characters that are not usually used in filenames), and truncating the ! 23: name if necessary. If the name does have to be truncated, then it is ! 24: hashed to produce a character that is appended to the filename, in an attempt ! 25: to produce a unique filename. Even so, it is still possible for different ! 26: unit names to produce the same filename, and in the unlikely event of this ! 27: happening you get an error message that the unit already exists when you ! 28: try to create the clashing unit name. ! 29: ! 30: Filenames are at most SAFEFNLEN characters long, which on standard Unix ! 31: systems gives you one spare character for making backups or whatever. ! 32: ! 33: It would be better if the B system effectively maintained its own directories ! 34: that mapped units onto files in the real file system, as is done for targets. ! 35: With operating systems with a more limited file system (eg even shorter ! 36: filenames) this is the only possibility. ! 37: ! 38: */ ! 39: ! 40: #define COML 60 ! 41: char com_line[COML]; ! 42: #define At_eos(s) ((s)+= strlen(s)) ! 43: ! 44: Visible Procedure f_edit(fname, errline) value fname; intlet errline; { ! 45: /*The default editor is called with a first parameter of the line number ! 46: and a second parameter of the file name*/ ! 47: string cl= com_line; ! 48: int c; ! 49: if (filtered) { ! 50: ignsigs(); ! 51: printf("\001: +%d %s\n", errline, strval(fname)); ! 52: fflush(stdout); ! 53: do { c= fgetc(stdin); } while (c != '\n' && c != EOF); ! 54: re_sigs(); ! 55: return; ! 56: } ! 57: if (getenv("BEDITOR") == NULL) strcpy (cl, DEDI); ! 58: else strcpy(cl, getenv("BEDITOR")); ! 59: if (*(cl+strlen(cl)-1) == '+') { ! 60: if (errline != 0) sprintf(At_eos(cl), "%d", errline); ! 61: else *(cl+strlen(cl)-1)= ' '; ! 62: } ! 63: app_fname(At_eos(cl), fname); ! 64: system(com_line); ! 65: } ! 66: ! 67: Visible value f_save(fname) value fname; { ! 68: /* saves the file in a temporary file, whose name is returned */ ! 69: /* Here the OS does the copy: you may have to do this yourself */ ! 70: string cl; value sname= mk_text(SAVEFILE); ! 71: strcpy(cl= com_line, "cp"); ! 72: app_fname(At_eos(cl), fname); ! 73: app_fname(At_eos(cl), sname); ! 74: system(com_line); ! 75: return sname; ! 76: } ! 77: ! 78: Visible Procedure f_rename(fname, nfname) value fname, nfname; { ! 79: string cl; ! 80: strcpy(cl= com_line, "mv"); ! 81: app_fname(At_eos(cl), fname); ! 82: app_fname(At_eos(cl), nfname); ! 83: system(com_line); ! 84: /* what if mv fails??? */ ! 85: } ! 86: ! 87: Visible Procedure f_delete(fname) value fname; { ! 88: string cl; ! 89: strcpy(cl= com_line, "rm"); ! 90: app_fname(At_eos(cl), fname); ! 91: system(com_line); ! 92: } ! 93: ! 94: Visible bool f_exists(fname) value fname; { ! 95: FILE *f= fopen(strval(fname), "r"); ! 96: if (f==NULL) return No; ! 97: fclose(f); ! 98: return Yes; ! 99: } ! 100: ! 101: #define SAFEFNLEN 13 ! 102: ! 103: Hidden double f_hash(v) value v; { ! 104: int len= length(v), k; double d= '"'+.404*len; ! 105: /*That '"' is strange I know, but it's necessary for compatibility*/ ! 106: value ch; ! 107: k_Over_len { ! 108: ch= thof(k+1, v); ! 109: d= .987*d+.277*charval(ch); ! 110: release(ch); ! 111: } ! 112: return d; ! 113: } ! 114: ! 115: Visible value f_uname(name, type) value name; literal type; { ! 116: static char fname[SAFEFNLEN+1]; string sfn= fname; ! 117: *sfn= type; ! 118: if (length(name) < SAFEFNLEN) strcpy(sfn+1, strval(name)); ! 119: else { ! 120: double hh= f_hash(name)*321.987; char h; ! 121: strncpy(sfn+1, strval(name), SAFEFNLEN-2); ! 122: hh= hh-floor(hh); h= (char) floor(hh*29) + '!'; ! 123: if (h >= '"') h++; ! 124: if (h >= '\'') h++; ! 125: if (h >= '/') h++; ! 126: if (h >= '0') h+= 10; ! 127: if (h >= 'A') h+= 26; ! 128: if (h >= 'a') h+= 26; ! 129: *(sfn+SAFEFNLEN-1)= h; *(sfn+SAFEFNLEN)= '\0'; ! 130: } ! 131: return mk_text(fname); ! 132: } ! 133: ! 134: Hidden value try(t, n) value t; intlet n; { ! 135: value eq= mk_text("="), fn, a, b, c; ! 136: int len= length(t); ! 137: if (n == 0) fn= concat(eq, t); ! 138: else { /* PUT "="^(n<<1)^t IN fn */ ! 139: fn= concat(eq, a= concat(b= convert(c= mk_integer(n), No, No), t)); ! 140: release(a); release(b); release(c); ! 141: } ! 142: release(eq); ! 143: if (len > SAFEFNLEN) { ! 144: fn= trim(a= fn, 0, len-SAFEFNLEN); ! 145: release(a); ! 146: } ! 147: return(fn); ! 148: } ! 149: ! 150: Visible value f_tname(t) value t; { ! 151: value fn= try(t, 0); ! 152: intlet i= 0; ! 153: while (f_exists(fn)) { ! 154: release(fn); ! 155: fn= try(t, ++i); ! 156: } ! 157: return(fn); ! 158: } ! 159: ! 160: Hidden Procedure app_fname(ceos, fname) string ceos; value fname; { ! 161: string fp= strval(fname); intlet k, len= strlen(fp); ! 162: *ceos++= ' '; ! 163: k_Over_len { ! 164: *ceos++= '\\'; ! 165: *ceos++= *fp++; /*should really use charval(thof(...))*/ ! 166: } ! 167: *ceos= '\0'; ! 168: } ! 169: ! 170: Visible unsigned f_size(ifile) FILE *ifile; { ! 171: struct stat sb; ! 172: if (fstat(fileno(ifile), &sb) != 0) syserr("can't stat file"); ! 173: return( (unsigned) (sb.st_size) ); ! 174: } ! 175: ! 176: Visible bool f_interactive(ifile) FILE *ifile; { ! 177: return isatty(fileno(ifile)); ! 178: } ! 179: ! 180: Visible Procedure lst_uhds() { ! 181: /*List the headings of the units in this workspace*/ ! 182: system("for i in \\'* \\<* \\\"* \\>*; do head -1 $i 2>/dev/null; done"); ! 183: /*just for now, you understand*/ ! 184: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.