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

Defined functions

app_fname defined in line 160; used 6 times
f_delete defined in line 87; used 4 times
f_edit defined in line 44; used 2 times
f_exists defined in line 94; used 8 times
f_hash defined in line 103; used 1 times
f_rename defined in line 78; used 2 times
lst_uhds defined in line 180; used 1 times
try defined in line 134; used 2 times

Defined variables

com_line defined in line 41; used 8 times

Defined macros

At_eos defined in line 42; used 7 times
COML defined in line 40; used 1 times
  • in line 41
SAFEFNLEN defined in line 101; used 7 times
Last modified: 1985-08-27
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3479
Valid CSS Valid XHTML 1.0 Strict