|
|
1.1 ! root 1: /* Copyright Bell Telephone Laboratories Whippany, N.J. ! 2: ! 3: * *********************************** ! 4: * *********************************** ! 5: * ***** BITE INPUT TEXT EDITOR ****** ! 6: * *** R. B. Drake WH 8C-005 X4163 *** ! 7: * **** Fri Aug 24 15:21:32 1979 ***** ! 8: * *********************************** ! 9: * *********************************** ! 10: * This routine handles all text input to bite. Text may originate from ! 11: * a tty or from a UNIX file or data placed in a string array. Certain ! 12: * syntax error messages are issued and all housekeeping having to do ! 13: * with line numbers and the page index is handled here. ! 14: ! 15: */ ! 16: /* "@(#) bed.c: V 1.3 11/12/81" */ ! 17: ! 18: #include "bas.h" ! 19: char *linptr; /* ALWAYS points to the next available ! 20: byte in the program txtbuf */ ! 21: char *endob = txtbuf + (NMPAG * PGSIZ); ! 22: char _string[LINMAX]; ! 23: union bascmd local; ! 24: union bascmd inst; ! 25: char linbuf[LINMAX]; ! 26: char ascno[NOMAX],ascop[OPMAX]; ! 27: struct pages index[NMPAG+1]; ! 28: int pg; ! 29: static int size; ! 30: char *curptr; /* fetch sets this to point to the beginning of the ! 31: current line. Other routines may change it */ ! 32: char *lbdptr; /* fetch sets this to point to the beginning ! 33: of the next sequential line in the txtbuf */ ! 34: extern int singflg; ! 35: extern int tv; ! 36: /* This table is used to encode and decode certain key-worde for ! 37: storage compression and for ease of recognition by the execution ! 38: software */ ! 39: char *keyword[] = ! 40: { ! 41: "goto", /* 1 */ ! 42: "go to", /* 2 */ ! 43: "then", /* 3 */ ! 44: "to", /* 4 */ ! 45: "step", /* 5 */ ! 46: "<>", /* 6 */ ! 47: "<=", /* 7 */ ! 48: "=<", /* 10 */ ! 49: "<", /* 11 */ ! 50: ">=", /* 12 */ ! 51: "=>", /* 13 */ ! 52: ">", /* 14 */ ! 53: "=", /* 15 */ ! 54: "gosub", /* 16 */ ! 55: "more", /* 17 */ ! 56: 0 }; ! 57: extern int rem; ! 58: extern int _sub; ! 59: extern int tel; ! 60: extern int stpflg; ! 61: extern int autflg,aut,inc; ! 62: bed(fp) ! 63: FILE *fp; ! 64: { ! 65: register char *to,*from; ! 66: int i,j,k,nlflg,quoflg,parflg,bflg; ! 67: int erflg; ! 68: char c,*strptr; ! 69: char *pt,*save; ! 70: char *isthere(); ! 71: ! 72: /* zero the working txtbufs */ ! 73: strptr=_string; ! 74: for(i=0;i<NOMAX;ascno[i++]=0); ! 75: for(i=0;i<OPMAX;ascop[i++]=0); ! 76: for(i=0;i<LINMAX;linbuf[i++]=0); ! 77: local.thing.opcode.lobyte=local.thing.opcode.hibyte='\0'; ! 78: local.thing.linno=nlflg=stpflg=0; ! 79: expr = linbuf; ! 80: if(autflg != 0) /* if auto line numbering in affect */ ! 81: { ! 82: aut += inc; ! 83: sprintf(ascno,"%d",aut); ! 84: } ! 85: /* print the prompt character */ ! 86: if(fp != 0) ! 87: if(isatty(fileno(fp))) ! 88: printf("*%s",ascno); ! 89: if(fp != 0) ! 90: if(fgets(_string,LINMAX,fp) == 0) return(-1); /* EOF */ ! 91: /* get a line of input from the user and store it in compressed ! 92: * source form unless the line number is zero in which case ! 93: * execute the instruction immediately ! 94: */ ! 95: /* get the line number if any */ ! 96: while(*strptr == ' ' || *strptr == ' ') ! 97: strptr++; /* ignore leading white space */ ! 98: for(i=0,k=0;num((c= *strptr++)) && i < (NOMAX-1);i++) ! 99: { ! 100: ascno[i]=c; ! 101: aut = atoi(ascno); ! 102: } ! 103: if(ascno[0] != '\0') ! 104: if((local.thing.linno = aut) == 0) ! 105: { ! 106: error(0,0); ! 107: return(0); ! 108: } ! 109: if(c== '\n') ! 110: { ! 111: if(local.thing.linno == 0 || autflg) ! 112: { ! 113: if(fetch(-1,&lbdptr) != 0) ! 114: { ! 115: if(fetch(0,&lbdptr) != 0) ! 116: { ! 117: error(0,1); ! 118: return(0); ! 119: } ! 120: } ! 121: prin(); ! 122: if(autflg) aut -= inc; ! 123: return(0); ! 124: } ! 125: /*a line number was entered ! 126: * but nothing followed which implies ! 127: *delete ! 128: */ ! 129: delete(); ! 130: return(0); ! 131: } ! 132: /* if no blank was used as a delimiter, then insure ! 133: * that we don't lose the first character of the opcode.lobyte ! 134: */ ! 135: if( c == '.') /* if auto line num to be tuned off */ ! 136: { ! 137: autflg=0; ! 138: aut -= inc; ! 139: return(0); ! 140: } ! 141: if(c== '\t') ! 142: { ! 143: local.thing.opcode.hibyte = '\201'; ! 144: while(*strptr == '\t') ! 145: { ! 146: local.thing.opcode.hibyte = (local.thing.opcode.hibyte&0377) + 1; ! 147: strptr++; ! 148: } ! 149: } ! 150: if( c != ' ' && c != '\t') ! 151: { ! 152: ascop[0] = c; ! 153: k=1; ! 154: } ! 155: /* get the operation statement */ ! 156: bflg=0; ! 157: for(j=0,i=k;(c= *strptr);i++) ! 158: { ! 159: if((c== ' ') && (strcmp("go",ascop) != 0)) ! 160: { ! 161: bflg=1; ! 162: while((c= *strptr) == ' ' || c== '\014') ! 163: strptr++; ! 164: } ! 165: /* if an "=" is present here then the ! 166: *opcode.lobyte is "let" by default */ ! 167: if(c== '=' || (c== '(' && bflg != 1)) ! 168: { ! 169: ascop[i]=c; ! 170: strcpy(linbuf,ascop); ! 171: strcpy(ascop,"\010"); ! 172: j=i+1; ! 173: strptr++; ! 174: break; ! 175: } ! 176: /* If a new line is present here then ! 177: * we have an operation with ! 178: * no following expression ! 179: */ ! 180: if(c== '\n') ! 181: { ! 182: nlflg=1; ! 183: ascop[i]='\0'; ! 184: break; ! 185: } ! 186: if( i< (OPMAX -1)) ! 187: { ! 188: if( bflg == 1) break; ! 189: ascop[i]=c; ! 190: } ! 191: strptr++; ! 192: } ! 193: if(ascop[0] !=0) ! 194: { ! 195: int xxx = encode(ascop); ! 196: ! 197: local.thing.opcode.lobyte = xxx; ! 198: if(xxx == -1) ! 199: { ! 200: error(local.thing.linno,1); ! 201: local.thing.opcode.lobyte=tel; ! 202: pt = strcat(linbuf,ascop); ! 203: pt = carcat(linbuf,' '); ! 204: erflg=1; ! 205: j = pt - linbuf; ! 206: } ! 207: else erflg=0; ! 208: } ! 209: if(!nlflg) ! 210: { ! 211: /* put any expression in "linbuf" */ ! 212: for(i=j;(c= *strptr++) != '\n';i++) ! 213: { ! 214: if(i < (LINMAX -1)) ! 215: linbuf[i]=c; ! 216: } ! 217: /* encode keywords in the expression field */ ! 218: while(1) ! 219: { ! 220: if(!nocode(local.thing.opcode.lobyte) && erflg == 0) ! 221: { ! 222: /* first strip any blanks and control characters ! 223: * out of the expression unless they are quoted */ ! 224: quoflg = 1; ! 225: parflg= 0; ! 226: for(i=0,j=0;linbuf[i] != '\0';i++) ! 227: if(linbuf[i] > '\040' || quoflg== -1) ! 228: { ! 229: linbuf[j++]=linbuf[i]; ! 230: switch (linbuf[i]) ! 231: { ! 232: case '"' : quoflg *= -1; ! 233: break; ! 234: case '(' : parflg += 1; ! 235: break; ! 236: case ')' : parflg -= 1; ! 237: break; ! 238: } ! 239: } ! 240: linbuf[j]='\0'; ! 241: if(quoflg == -1) ! 242: { ! 243: error(local.thing.linno,11); ! 244: } ! 245: if(parflg != 0) ! 246: { ! 247: error(local.thing.linno,16); ! 248: } ! 249: for(i=0;keyword[i] != 0;i++) ! 250: while((pt=isthere(keyword[i],linbuf,1)) != 0) ! 251: { ! 252: *pt++='\001'+i; ! 253: shrink(pt); ! 254: } ! 255: } ! 256: break; ! 257: } ! 258: } ! 259: /* If the line number is zero then we have ! 260: * a command for immediate execution ! 261: */ ! 262: if( k != 0) ! 263: { ! 264: inst.thing.linno = 0; ! 265: expr=linbuf; ! 266: if(local.thing.opcode.lobyte == tv) ! 267: list(1); ! 268: else ! 269: { ! 270: bascall(local.thing.opcode.lobyte); ! 271: if(autflg) ! 272: aut -= inc; ! 273: } ! 274: return(0); ! 275: } ! 276: /* if a ligitimate line number has been entered ! 277: *put it in the program txtbuf ! 278: */ ! 279: if(singflg != 0) /* don't permit txtbuf editing in single step */ ! 280: { ! 281: error(0,12); ! 282: return(0); /* not fatal */ ! 283: } ! 284: if(fetch(local.thing.linno,&lbdptr) == -1) inst.thing.linno = 0; ! 285: save=curptr; ! 286: /* if local.thing.linno is greater than inst.thing.linno (returned by fetch) ! 287: * then fetch has returned the last line of the program ! 288: * and the action is to add the new line to the end of the ! 289: * program */ ! 290: if(local.thing.linno > inst.thing.linno) ! 291: { ! 292: pg=(linptr-txtbuf)/PGSIZ; /* calculate page number*/ ! 293: if(index[pg].maxlin == 0) ! 294: { ! 295: index[pg].maxlin = local.thing.linno; /*first line*/ ! 296: index[pg].begin=linptr; ! 297: } ! 298: if(local.thing.linno > index[pg].maxlin) ! 299: index[pg].maxlin=local.thing.linno; ! 300: for(i=0;i<4;i++) ! 301: *linptr++=local.byte[i]; ! 302: expr = linptr; ! 303: for(i=0;linbuf[i] != 0;i++) ! 304: *linptr++=linbuf[i]; ! 305: *linptr++='\0'; /* end the expression string */ ! 306: linptr[0]='\0'; /* make it an eof mark */ ! 307: linptr[1]= '\0'; ! 308: } ! 309: /* if local.thing.linno is less than inst.thing.linno, then the new ! 310: * line must be inserted into the program txtbuf. In order ! 311: * to do that, the current line and all lines above it ! 312: * must be slid up to make room for the new line */ ! 313: if(local.thing.linno < inst.thing.linno) /* insert case */ ! 314: { ! 315: /* make room */ ! 316: clear(); /*clear page index from current page up */ ! 317: from = linptr; ! 318: linptr += strlen(linbuf) + 5; ! 319: to = linptr; ! 320: *linptr = '\0'; /*insure an eof mark*/ ! 321: linptr[1] = '\0'; ! 322: linptr[2] = '\0'; /* eof requires one 0 to end an expression ! 323: string and two to mark eof */ ! 324: while(from != curptr) ! 325: *--to = *--from; ! 326: put(); ! 327: update(); /* rebuild page index */ ! 328: lbdptr=curptr=save; ! 329: return(0); ! 330: } ! 331: /* if we arrive at this place in the program, local.thing.linno is ! 332: * by default equal to inst.thing.linno and the action is to replace ! 333: * the current line with the new one. There are three possible ! 334: * vvariations in the replacement algorithm. 1) the new line ! 335: * and the old one are the same size in which case the action ! 336: * is a simple replacement. 2) the new line is shorter than the ! 337: * old one in which case the action is to replace the old line ! 338: * and slide the remaining txtbuf down to reclaim the left over ! 339: * space. 3) the new line is longer than the old one in which ! 340: * case the txtbuf above the current line must be slid up by ! 341: * an amount equal to the difference in length to make room ! 342: * for the new line */ ! 343: ! 344: size = strlen(expr) - strlen(linbuf); ! 345: if(size == 0) /*case 1 */ ! 346: { ! 347: put(); ! 348: lbdptr=curptr=save; ! 349: return(0); ! 350: } ! 351: if(size > 0) /* case 2 */ ! 352: { ! 353: put(); ! 354: cover(lbdptr,curptr); ! 355: lbdptr=curptr=save; ! 356: return(0); ! 357: ! 358: } ! 359: clear(); /* case 3 by default of not being either 1 or 2 */ ! 360: from = linptr; ! 361: linptr -= size; ! 362: to = linptr; ! 363: while(from != curptr) ! 364: *--to = *--from; ! 365: put(); ! 366: update(); ! 367: lbdptr=curptr=save; ! 368: return(0); ! 369: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.