1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ 2: static char rcsid[] = "$Header: save.c,v 2.5 85/08/22 16:07:04 timo Exp $"; 3: 4: /* 5: * B editor -- Save Parse tree on file. 6: */ 7: 8: #include <ctype.h> 9: 10: #include "b.h" 11: #include "feat.h" 12: #include "bobj.h" 13: #include "node.h" 14: #include "gram.h" 15: #include "queu.h" 16: 17: #define Indent " " /* Output for each indentation level */ 18: 19: Hidden int spaces = 0; /* Saved-up spaces; emitted when non-blank found */ 20: 21: #ifdef BTOP 22: #include <setjmp.h> 23: 24: Hidden bool piping; /* Set if output goes to B interpreter */ 25: Hidden jmp_buf alas; /* Where to go when no command prompt gotten */ 26: #endif 27: 28: /* 29: * Write the representation of a node. If it has children, 30: * they are written by recursive calls. 31: */ 32: 33: Hidden Procedure 34: savewalk(n, level, file) 35: node n; 36: int level; 37: FILE *file; 38: { 39: string *rp; 40: string cp; 41: int nch; 42: int i; 43: char c; 44: 45: if (Type(n) == Tex) { 46: for (; spaces > 0; --spaces) 47: putc(' ', file); 48: fputs(Str((value)n), file); 49: return; 50: } 51: nch = nchildren(n); 52: rp = noderepr(n); 53: for (i = 0; i <= nch; ++i) { 54: if (i) 55: savewalk(child(n, i), level, file); 56: cp = rp[i]; 57: if (cp) { 58: for (; c = *cp; ++cp) { 59: switch (c) { 60: 61: case '\n': 62: case '\r': 63: putc('\n', file); 64: #ifdef BTOP 65: if (piping) { 66: if (!expect(">>> ")) 67: longjmp(alas, 1); 68: } 69: #endif BTOP 70: if (c == '\n') 71: for (i = level; i > 0; --i) 72: fputs(Indent, file); 73: spaces = 0; 74: break; 75: 76: case '\b': 77: --level; 78: break; 79: 80: case '\t': 81: ++level; 82: break; 83: 84: case ' ': 85: ++spaces; 86: break; 87: 88: default: 89: for (; spaces > 0; --spaces) 90: putc(' ', file); 91: putc(c, file); 92: break; 93: 94: } 95: } 96: } 97: } 98: } 99: 100: 101: /* 102: * Save the entire Parse tree. 103: */ 104: 105: Visible bool 106: save(p, filename) 107: path p; 108: string filename; 109: { 110: FILE *file = fopen(filename, "w"); 111: 112: if (!file) 113: return No; 114: #ifdef BTOP 115: piping = No; 116: #endif BTOP 117: sendsave(p, file); 118: return fclose(file) != EOF; 119: } 120: 121: 122: Hidden Procedure 123: sendsave(p, file) 124: path p; 125: FILE *file; 126: { 127: p = pathcopy(p); 128: top(&p); 129: spaces = 0; 130: savewalk(tree(p), 0, file); 131: putc('\n', file); 132: pathrelease(p); 133: } 134: 135: #ifdef BTOP 136: 137: /* 138: * Interface to top level. 139: */ 140: 141: Visible bool 142: send(p, pdown) 143: path p; 144: FILE *pdown; 145: { 146: piping = Yes; 147: if (setjmp(alas)) { 148: pathrelease(p); 149: return No; 150: } 151: sendsave(p, pdown); 152: if (expect(">>> ")) 153: putc('\n', pdown); 154: return Yes; 155: } 156: #endif BTOP 157: 158: /* ------------------------------------------------------------------ */ 159: 160: #ifdef SAVEBUF 161: 162: /* 163: * Write a node. 164: */ 165: 166: Hidden Procedure 167: writenode(n, fp) 168: node n; 169: FILE *fp; 170: { 171: int nch; 172: int i; 173: 174: if (!n) { 175: fputs("(0)", fp); 176: return; 177: } 178: if (((value)n)->type == Tex) { 179: writetext((value)n, fp); 180: return; 181: } 182: nch = nchildren(n); 183: fprintf(fp, "(%s", symname(symbol(n))); 184: for (i = 1; i <= nch; ++i) { 185: putc(',', fp); 186: writenode(child(n, i), fp); 187: } 188: fputc(')', fp); 189: } 190: 191: 192: Hidden Procedure 193: writetext(v, fp) 194: value v; 195: FILE *fp; 196: { 197: string str; 198: int c; 199: 200: Assert(v && Type(v) == Tex); 201: putc('\'', fp); 202: str = Str(v); 203: for (str = Str(v); *str; ++str) { 204: c = *str; 205: if (c == ' ' || isprint(c)) { 206: putc(c, fp); 207: if (c == '\'' || c == '`') 208: putc(c, fp); 209: } 210: else if (isascii(c)) 211: fprintf(fp, "`$%d`", c); 212: } 213: putc('\'', fp); 214: } 215: 216: 217: Visible bool 218: savequeue(v, filename) 219: value v; 220: string filename; 221: { 222: register FILE *fp; 223: auto queue q = (queue)v; 224: register node n; 225: register bool ok; 226: register int lines = 0; 227: 228: fp = fopen(filename, "w"); 229: if (!fp) 230: return No; 231: q = qcopy(q); 232: while (!emptyqueue(q)) { 233: n = queuebehead(&q); 234: writenode(n, fp); 235: putc('\n', fp); 236: ++lines; 237: noderelease(n); 238: } 239: ok = fclose(fp) != EOF; 240: if (!lines) 241: /* Try to */ unlink(filename); /***** UNIX! *****/ 242: return ok; 243: } 244: #endif SAVEBUF