#include #include #include /* for 'free' */ #include "quint.h" #include "macro.h" #include "fileio.h" #include "tm.h" #include "getcmd.h" /* FUNCTIONS */ /* void del_all_mac(struct maclist *mlst, int *status); */ /* this shouldn't be */ /* prepare to write a 'tm' or a 'mac' file */ void write_file(struct qlist *lptr, struct maclist *mptr) { int status; char fname[40]; while(1) { getcmd("what kind? ('mac' or 'tm') ",ans); if ( iscmd(ans,"ex*it")) break; if ( iscmd(ans,"tm")) { getcmd("enter filename: ",fname); if ( !iscmd(fname,"exit") && !iscmd(fname,".") ) { write_tm_file(fname,lptr,&status); if (status != OK) message("",status); } break; } else if ( iscmd(ans,"mac")) { getcmd("enter filename: ",fname); if ( !iscmd(fname,"exit") && !iscmd(fname,".") ) { write_mac_file(fname,mptr,&status); if (status != OK) message("",status); } break; } else if ( iscmd(ans,"#")) flushcmd("","",0); else flushcmd("invalid response -> ",ans,1); } } /* prepare to read a 'tm' or a 'mac' file */ void read_file(struct qlist *lptr, struct maclist *mptr) { int status; while(1) { getcmd("what kind? ('mac' or 'tm') ",ans); if ( iscmd(ans,"ex*it")) break; if (iscmd(ans,"tm") ) { getcmd("enter name of file: ",ans); read_tm_file(ans,lptr,&status); if ( status != OK) message(ans,status); else strcpy(filename,ans); break; } else if (iscmd(ans,"mac") ) { getcmd("enter name of file: ",ans); read_mac_file(ans,mptr,&status); if ( status != OK) message(ans,status); break; } else if (iscmd(ans,"#") ) flushcmd("","",0); else flushcmd("invalid response -> ",ans,1); } } /* Read a quintuple list from disk file. The name of the list will be the filename without extension. */ void read_tm_file( char *fname, struct qlist *ql, int *status ) { FILE *fptr; char ch; char headerbuf[MAX_HEADER]; char linebuf[90]; char cmmt[COMMENT_LENGTH], quint[6]; int line; /* current line in the file*/ int len, i; int counter=0; /* quintuple counter*/ /* if no extension is entered, supply the default:*/ if ( strchr(fname,'.') == NULL ) strcat(fname,".tm"); if((fptr = fopen(fname,"r")) == NULL) { *status = NO_READ_OPEN; return; } /* give a name to the quintuple list*/ if (ql->list_name) free(ql->list_name); ql->list_name = NULL; *strchr(fname, '.') = '\0'; /* We know there was one */ ql->list_name = (char *) malloc (strlen(fname) + 1); strcpy(ql->list_name,fname); /* start reading the file one line at a time */ ch = getline(fptr, linebuf, 90); line = 1; headerbuf[0] = '\0'; while (linebuf[0] != '(' ) /* file has comment header */ { strcat(headerbuf,linebuf); if ( getline(fptr, linebuf, 90) == EOF ) { *status = EMPTY_QFILE; return; } line++; } /* store the header */ ql->header = (char *) malloc (MAX_HEADER + 1); strncpy(ql->header,headerbuf,MAX_HEADER); /* get quintuples and their comments */ quint[5] = '\0'; while( ch != EOF ) { if ( linebuf[0] != '(' ) /* printf("on line %d: no quintuple found\n",line) */; else { strncpy(quint,linebuf+1,5); len = strlen(linebuf); if ( len >= 7 ) { linebuf[len-1] = '\0'; /* eliminate the '\n' */ strncpy(cmmt,linebuf+6,COMMENT_LENGTH); } else cmmt[0] = '\0'; if ( ( new_quint(ql,quint,cmmt,status)) == NULL ) { printf("on line %d: ",line); message(quint,*status); } else counter++; } ch = getline(fptr, linebuf, 90); line++; } fclose(fptr); *status = OK; return; } /* write a quintuple file. */ void write_tm_file( char *fname, struct qlist *ql, int *status ) { FILE *fptr; struct quint *qptr; char ch,lastchar; int j; int counter = 0; /* quintuple counter */ int cptr=0; if (ql->root == NULL) { *status = NO_QLIST; return; } /* if no extension is entered, supply the default: */ if ( strchr(fname,'.') == NULL) strcat(fname,".tm"); if((fptr = fopen(fname,"w")) == NULL) { *status = NO_WRITE_OPEN; return; } if ( ql->header[0] == '\0' ) { getcmd("want to enter comments at the top of the file [n]?: ",ans); if ( iscmd (ans,"y") || iscmd (ans,"Y") ) { lastchar = 0; printf("Type text, terminate input with '.' on a new line.\n"); while ( (ch=getchar()) != EOF ) { if ( ch == '.' && (lastchar == '\n' || lastchar == 0) ) { getchar(); /* empty the from the keyboard buffer */ break; } lastchar = ch; putc(ch,fptr); } putc('\n',fptr); } } else { while ( ql->header[cptr] != '\0' ) putc( ql->header[cptr++], fptr); } qptr = ql->root; qptr = qptr->nextptr; /* first quint is a dummy */ while(1) if (qptr == NULL) break; else { putc('(',fptr); putc(qptr->current_state,fptr); putc(qptr->current_symbol,fptr); putc(qptr->next_symbol,fptr); putc(qptr->next_state,fptr); putc(qptr->move,fptr); counter++; if (qptr->comment != NULL) { /* Comments forced to next tab at column 9. -- DMH. this whole if*/ fprintf(fptr, " %s",qptr->comment); } putc('\n',fptr); qptr = qptr->nextptr; } fclose(fptr); printf("%d quintuples were written to %s\n",counter,fname); *status = OK; return; } /* Read a macro stream from a disk file. The name of the macro will be the filename without extension. */ void read_mac_file (char *macname, struct maclist *ml, int *status) { FILE *fptr; /* char namebuf[MNAME_LENGTH]; */ char linebuf[90]; char wordbuf[MAC_WORD_LENGTH]; char ch, cha; int i,j,gotone=0; /* append the default file type if it is not supplied, and open the file */ if ( strchr(macname,'.') == NULL ) strcat(macname,".mac"); if((fptr = fopen(macname,"r")) == NULL) { *status = NO_READ_OPEN; return; } /* clear out the macro buffer */ del_all_mac(ml,status); if (ml->list_name) free(ml->list_name); ml->list_name = NULL; *strchr(macname, '.') = '\0'; /* We know there was one */ ml->list_name = (char *) malloc (strlen(macname) + 1); strcpy(ml->list_name, macname); #ifdef DEAD /* write the name of the macro in the macro buffer */ /* dsw for ( i=0; ilist_name, namebuf, MNAME_LENGTH); */ #endif /* Dead */ /* read the file one line at a time */ while(1) /* read a line per loop */ { ch = getline(fptr, linebuf, 90); if ( ch == EOF && strlen(linebuf) == 0 ) break; if ( linebuf[0] != '#' && linebuf[0] != '!') /* not a comment line */ { i = 0; /* linebuf character counter */ while(1) /* read a word per loop */ { j = 0; /* wordbuf character counter */ /* skip over white space */ while ( (cha=linebuf[i++])==' ' || cha=='\t' ); if ( cha == 10 || cha == EOF || cha == '\0') break; wordbuf[j++] = cha; /* read a quoted string. Don't let it span lines. */ if ( cha == '\"' ) while (1) { cha = wordbuf[j++] = linebuf[i++]; if (cha == '\"' ) /* end of quoted string. */ { /* get comma or semicolon, etc */ while ( (cha=linebuf[i++])!=' ' && cha!='\t' && cha!=10 && cha!=EOF) wordbuf[j++] = cha; break; } if ( cha == 10 || cha == EOF || cha == '\0') { *status = NO_STR_END; /* error-- no end of string */ del_all_mac(ml,status); /* clear out what has been stored*/ wordbuf[j] = '\0'; return; /* ... and quit */ } } else /* no string, so read a word delimited by white-space */ { while ( (cha=linebuf[i++])!=' ' && cha!='\t' && cha!=10 && cha!=EOF) wordbuf[j++] = cha; } wordbuf[j] = '\0'; /* store the word or quoted string */ new_macword(ml, wordbuf,status); gotone = 1; if ( cha == 10 || cha == EOF ) break; } } } fclose(fptr); if ( gotone ) *status = OK; else *status = EMPTY_MFILE; return; } /* write a macro file. */ void write_mac_file (char *fname, struct maclist *ml, int *status) { FILE *fptr; struct macword *mptr; int linecount=0, i; char ch; if ( ml->root == NULL ) { *status = NO_MACRO; return; } /* if no extension is entered, supply the default: */ if ( strchr(fname,'.') == NULL) strcat(fname,".mac"); if((fptr = fopen(fname,"w")) == NULL) { *status = NO_WRITE_OPEN; return; } mptr = ml->root; while(1) { mptr = mptr->nextptr; /* there is no first word */ if (mptr == NULL) break; i = 0; while( (ch = mptr->word[i++]) != '\0' ) { linecount++; putc(ch,fptr); } linecount++; putc(' ',fptr); if (linecount >= 60) /* wrap to the next line */ { putc('\n',fptr); linecount = 0; } } putc('\n',fptr); fclose(fptr); *status = OK; return; } /* read a line from standard input (from Kernigan and Ritchie) function value is the last character read. */ /**/ char getline(FILE *fptr, char *buff, int lim) { char c; int i; i = 0; while (--lim > 0 && (c=getc(fptr)) != EOF && c != '\n') buff[i++] = c; if (c == '\n') buff[i++] = c; buff[i] = '\0'; return(c); }