Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!cbatt!ucbvax!ULKYVX.BITNET!RDROYA01 From: RDROYA01@ULKYVX.BITNET.UUCP Newsgroups: comp.sys.atari.st Subject: Uemail source (2 of 12) Message-ID: <8702051840.AA11841@ucbvax.Berkeley.EDU> Date: Wed, 4-Feb-87 23:29:00 EST Article-I.D.: ucbvax.8702051840.AA11841 Posted: Wed Feb 4 23:29:00 1987 Date-Received: Sat, 7-Feb-87 12:48:28 EST Sender: daemon@ucbvax.BERKELEY.EDU Organization: University of Louisville Lines: 858 # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # file.c # fileio.c # print.c # This archive created: Tue Feb 3 17:51:53 1987 cat << \SHAR_EOF > file.c /* * The routines in this file * handle the reading and writing of * disk files. All of details about the * reading and writing of the disk are * in "fileio.c". */ #include #include "ed.h" unsigned char insflag = FALSE; /* Flag for C mode in newline() */ /* * Read a file into the current * buffer. This is really easy; all you do it * find the name of the file, and call the standard * "read a file into the current buffer" code. * Bound to "C-X C-R". */ fileread(f, n) register int f, n; { register int s; char fname[NFILEN]; if ((s=mlreply("Read file: ", fname, NFILEN)) != TRUE) return (s); return (readin(fname)); } /* * Select a file for editing. * Look around to see if you can find the * file in another buffer; if you can find it * just switch to the buffer. If you cannot find * the file, create a new buffer, read in the * text, and switch to the new buffer. * Bound to C-X C-V. */ filevisit(f, n) register int f, n; { register BUFFER *bp; register WINDOW *wp; register LINE *lp; register int i; register int s; char bname[NBUFN]; char fname[NFILEN]; if ((s=mlreply("Visit file: ", fname, NFILEN)) != TRUE) return (s); strcpy(lastbuf, curbp->b_bname); for (bp=bheadp; bp!=NULL; bp=bp->b_bufp) { if ((bp->b_flag&BFTEMP)==0 && strcmp(bp->b_fname, fname)==0) { if (--curbp->b_nwnd == 0) { curbp->b_dotp = curwp->w_dotp; curbp->b_doto = curwp->w_doto; curbp->b_markp = curwp->w_markp; curbp->b_marko = curwp->w_marko; } curbp = bp; curwp->w_bufp = bp; if (bp->b_nwnd++ == 0) { curwp->w_dotp = bp->b_dotp; curwp->w_doto = bp->b_doto; curwp->w_markp = bp->b_markp; curwp->w_marko = bp->b_marko; } else { wp = wheadp; while (wp != NULL) { if (wp!=curwp && wp->w_bufp==bp) { curwp->w_dotp = wp->w_dotp; curwp->w_doto = wp->w_doto; curwp->w_markp = wp->w_markp; curwp->w_marko = wp->w_marko; break; } wp = wp->w_wndp; } } lp = curwp->w_dotp; i = curwp->w_ntrows/2; while (i-- && lback(lp)!=curbp->b_linep) lp = lback(lp); curwp->w_linep = lp; curwp->w_flag |= WFMODE|WFHARD; mlwrite("[Old buffer]"); return (TRUE); } } makename(bname, fname); /* New buffer name. */ while ((bp=bfind(bname, FALSE, 0)) != NULL) { s = mlreply("Buffer name: ", bname, NBUFN); if (s == ABORT) /* ^G to just quit */ return (s); if (s == FALSE) { /* CR to clobber it */ makename(bname, fname); break; } } if (bp==NULL && (bp=bfind(bname, TRUE, 0))==NULL) { mlwrite("Cannot create buffer"); return (FALSE); } if (--curbp->b_nwnd == 0) { /* Undisplay. */ curbp->b_dotp = curwp->w_dotp; curbp->b_doto = curwp->w_doto; curbp->b_markp = curwp->w_markp; curbp->b_marko = curwp->w_marko; } curbp = bp; /* Switch to it. */ curwp->w_bufp = bp; curbp->b_nwnd++; return (readin(fname)); /* Read it in. */ } /* * Read file "fname" into the current * buffer, blowing away any text found there. Called * by both the read and visit commands. Return the final * status of the read. Also called by the mainline, * to read in a file specified on the command line as * an argument. */ readin(fname) char fname[]; { register LINE *lp1; register LINE *lp2; register int i; register WINDOW *wp; register BUFFER *bp; register int s; register int nbytes; register int nline; char line[NLINE]; bp = curbp; /* Cheap. */ if ((s=bclear(bp)) != TRUE) /* Might be old. */ return (s); bp->b_flag &= ~(BFTEMP|BFCHG); if (fname[0] == '~') /* an alias request */ if ((s=parsefn(fname))==FALSE) s = FIOFNF; strcpy(bp->b_fname, fname); if ((s=ffropen(fname)) == FIOERR) /* Hard file open. */ goto out; if (s == FIOFNF) { /* File not found. */ mlwrite("[New file]"); goto out; } mlwrite("[Reading %s]",fname); nline = 0; while ((s=ffgetline(line, NLINE)) == FIOSUC) { nbytes = strlen(line); if ((lp1=lalloc(nbytes)) == NULL) { s = FIOERR; /* Keep message on the */ break; /* display. */ } lp2 = lback(curbp->b_linep); lp2->l_fp = lp1; lp1->l_fp = curbp->b_linep; lp1->l_bp = lp2; curbp->b_linep->l_bp = lp1; for (i=0; iw_wndp) { if (wp->w_bufp == curbp) { wp->w_linep = lforw(curbp->b_linep); wp->w_dotp = lforw(curbp->b_linep); wp->w_doto = 0; wp->w_markp = curwp->w_dotp; wp->w_marko = 0; wp->w_flag |= WFMODE|WFHARD; } } if (s == FIOERR) /* False if error. */ return (FALSE); return (TRUE); } /* * Take a file name, and from it * fabricate a buffer name. This routine knows * about the syntax of file names on the target system. * I suppose that this information could be put in * a better place than a line of code. */ makename(bname, fname) char bname[]; char fname[]; { register char *cp1; register char *cp2; if (fname[0] == '~') parsefn(fname); cp1 = &fname[0]; while (*cp1 != 0) ++cp1; #if VMS while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!=']') --cp1; #endif #if CPM while (cp1!=&fname[0] && cp1[-1]!=':') --cp1; #endif #if ST while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!='\\') --cp1; #endif #if V7 while (cp1!=&fname[0] && cp1[-1]!='/') --cp1; #endif cp2 = &bname[0]; while (cp2!=&bname[NBUFN-1] && *cp1!=0 && *cp1!=';') *cp2++ = *cp1++; *cp2 = 0; } /* * Ask for a file name, and write the * contents of the current buffer to that file. * Update the remembered file name and clear the * buffer changed flag. This handling of file names * is different from the earlier versions, and * is more compatable with Gosling EMACS than * with ITS EMACS. Bound to "C-X C-W". */ filewrite(f, n) register int f, n; { register int s; char fname[NFILEN]; if ((s=mlreply("Write file: ", fname, NFILEN)) != TRUE) return (s); if ((s=writeout(fname)) == TRUE) { strcpy(curbp->b_fname, fname); curbp->b_flag &= ~BFCHG; upmode(); /* Update mode lines. */ } return (s); } /* * Save the contents of the current * buffer in its associatd file. No nothing * if nothing has changed (this may be a bug, not a * feature). Error if there is no remembered file * name for the buffer. Bound to "C-X C-S". May * get called by "C-Z". */ filesave(f, n) register int f, n; { register int s; if ((curbp->b_flag&BFCHG) == 0) /* Return, no changes. */ return (TRUE); if (curbp->b_fname[0] == 0) { /* Must have a name. */ filename(f,n); /* prompt user for a name */ if (curbp->b_fname[0] == 0) /* still no name */ return (FALSE); } if ((s=writeout(curbp->b_fname)) == TRUE) { curbp->b_flag &= ~BFCHG; upmode(); /* Update mode lines. */ } return (s); } /* * This function performs the details of file * writing. Uses the file management routines in the * "fileio.c" package. The number of lines written is * displayed. Sadly, it looks inside a LINE; provide * a macro for this. Most of the grief is error * checking of some sort. */ writeout(fn) char fn[]; { register int s; register LINE *lp; register int nline; if (fn[0] == '~') /* an alias request */ if ((s=parsefn(fn))==FALSE) return(FALSE); if ((s=ffwopen(fn)) != FIOSUC) /* Open writes message. */ return (FALSE); mlwrite("[Writing: %s]", fn); lp = lforw(curbp->b_linep); /* First line. */ nline = 0; /* Number of lines. */ while (lp != curbp->b_linep) { if ((s=ffputline(&lp->l_text[0], llength(lp))) != FIOSUC) break; ++nline; lp = lforw(lp); } if (s == FIOSUC) { /* No write error. */ s = ffclose(); if (s == FIOSUC) { /* No close error. */ if (nline == 1) mlwrite("[Wrote %d line]",nline); else mlwrite("[Wrote %d lines]", nline); } } else /* Ignore close error */ ffclose(); /* if a write error. */ if (s != FIOSUC) /* Some sort of error. */ return (FALSE); return (TRUE); } /* * The command allows the user * to modify the file name associated with * the current buffer. It is like the "f" command * in UNIX "ed". The operation is simple; just zap * the name in the BUFFER structure, and mark the windows * as needing an update. You can type a blank line at the * prompt if you wish. */ filename(f, n) register int f, n; { register int s; char fname[NFILEN]; if ((s=mlreply("Name: ", fname, NFILEN)) == ABORT) return (s); if (fname[0] == '~') /* an alias request */ s=parsefn(fname); if (s == FALSE) strcpy(curbp->b_fname, ""); else strcpy(curbp->b_fname, fname); upmode(); return (TRUE); } /* WRITEREG eXtended command Write defined region to file. Prompt * for filename. Error if any sub-function returns failure. Bound to * CTLX-R. */ writereg(f, n) register int f, n; { register int s; char buf[NLINE]; char fname[NFILEN]; n = 0; f = 0; if ((s=mlreply("Write region: ", fname, NFILEN)) == ABORT || s == FALSE) return(s); if (copyregion(NULL, NULL) != TRUE) return (FALSE); if ((s=ffwopen(fname)) != FIOSUC) return (s); while ((s=kremove(n++)) != EOF) { if (s != '\n' && f < NLINE) buf[f++] = s; else { ffputline(buf, f); f=0; } } if ((s=ffclose()) == FIOERR) return(s); else mlwrite("[Region written to %s]",fname); return(TRUE); } /* FILEINSERT eXtended command insert existing file at point. All of the * necessary updating is done by the usual insert commands. Bound to ^X-I. */ fileinsert(f, n) register int f, n; { char fname[NFILEN]; char line[NLINE]; register int c; register int nline; register int omarko; register LINE *omarkp; nline = 0; if ((f=mlreply("Insert file: ", fname, NFILEN)) == ABORT || f == FALSE) return(f); if (fname[0] == '~') if ((f=parsefn(fname))==FALSE) return(f); if (ffropen(fname) == FIOFNF) { mlwrite("File: %s not found", fname); return (FALSE); } insflag = TRUE; /* save current place in buffer */ if ((omarkp=lback(curwp->w_dotp)) == curbp->b_linep) omarkp = NULL; omarko = curwp->w_doto; mlwrite("[Mark set]"); /* the standard routines take care of update */ while ((f=ffgetline(line, NLINE)) == FIOSUC) { n = 0; ++nline; while ((c=line[n++]) !=NULL) if (linsert(1, c) == FALSE) { insflag = FALSE; return (FALSE); } if (newline(FALSE, 1) == FALSE) { insflag = FALSE; return (FALSE); } } ffclose(); if (f == FIOEOF) { if (nline == 1) mlwrite("[Inserted %d line]",nline); else mlwrite("[Inserted %d lines]", nline); } insflag = FALSE; /* The following code is needed if we want to insert a file * the way GNU does (returning to the point of insertion * when done). The problem is with files inserted when the * current point is at the end or beginning of the buffer. */ if (omarkp == NULL) /* inserted at beginning */ { curwp->w_markp = curwp->w_dotp; curwp->w_marko = curwp->w_doto; gotobob(FALSE,TRUE); curwp->w_doto = omarko; } else /* inserted at end or in the midst */ { curwp->w_markp = omarkp; curwp->w_marko = omarko; swapmark(FALSE,TRUE); forwline(NULL,1); } if (f == FIOERR) return (FALSE); return (TRUE); } parsefn(fname) char fname[]; { register char *ptr; char *index(), *alias(); char template[NFILEN]; if ((ptr=index(fname,'\\'))!=(char *)NULL) { *ptr = '\0'; /* ptr++==file; fname==alias */ if (alias(&template[0],&fname[1])==(char *)NULL) return(FALSE); strcat(template,++ptr); strcpy(fname,template); } else return(FALSE); return(TRUE); } SHAR_EOF cat << \SHAR_EOF > fileio.c /* * The routines in this file * read and write ASCII files from the * disk. All of the knowledge about files * are here. A better message writing * scheme should be used. */ #include #include "ed.h" FILE *ffp; /* File pointer, all functions. */ /* * Open a file for reading. */ ffropen(fn) char *fn; { if ((ffp=fopen(fn, "r")) == NULL) return (FIOFNF); return (FIOSUC); } /* * Open a file for writing. * Return TRUE if all is well, and * FALSE on error (cannot create). */ ffwopen(fn) char *fn; { #if VMS register int fd; if ((fd=creat(fn, 0666, "rfm=var", "rat=cr")) < 0 || (ffp=fdopen(fd, "w")) == NULL) { #else if ((ffp=fopen(fn, "w")) == NULL) { #endif mlwrite("Cannot open file for writing"); return (FIOERR); } return (FIOSUC); } /* * Close a file. * Should look at the status in all systems. */ ffclose() { #if ALCYON if (fclose(ffp) != FALSE) { mlwrite("Error closing file"); return(FIOERR); } return(FIOSUC); #endif fclose(ffp); return (FIOSUC); } /* * Write a line to the already * opened file. The "buf" points to the * buffer, and the "nbuf" is its length, less * the free newline. Return the status. * Check only at the newline. */ ffputline(buf, nbuf) register char buf[]; register int nbuf; { register int i; for (i=0; i= nbuf-1) { mlwrite("File has long line"); return (FIOERR); } buf[i++] = c; } if (c == EOF) { if (ferror(ffp) != FALSE) { mlwrite("File read error"); return (FIOERR); } if (i != 0) { mlwrite("File has funny line at EOF"); return (FIOERR); } return (FIOEOF); } buf[i] = 0; return (FIOSUC); } /* Function to handle printing file pageheaders. Needs access to ffp, * so it's here rather than in print.c where it probably belongs. Two * lines of top margin and three lines between header and text are wired in. */ prhdg(f, pagenum, rm) int f; int pagenum; int rm; { fflush(ffp); if (f == TRUE) fprintf(ffp, "\f\n\n%*s\n%*s\n%*d\n\n\n", rm, &prnhdr[0], rm, &prndate[0], rm, pagenum); else fprintf(ffp, "\n\n%*s\n%*s\n\n\n\n", rm, &prnhdr[0], rm, &prndate[0]); return(TRUE); } SHAR_EOF cat << \SHAR_EOF > print.c /* Output is only to the printer. We need to test for printer * connect before doing anything. If no connect, return FALSE. * These functions should allow line height and header selection * via a menu. */ #include #include #include "ed.h" #include "printer.h" /* PRINT eXtended command Handles the print buffer function. Gets user * parameters, calls printer init, and reports errors. Bound to ^X . */ static char prnfin[NFILEN]; print(f, n) register int f; register int n; { register int s,i; register int lm, rm, cw; char buf[MYBUF]; lm = 6; /* for now use 6 char left margins */ cw = 12; /* for now use 12 char pitch */ i = 0; if (n > 1) pagelen = n; /* pagelen is set by routine in page.c */ /* Eventually change these mode line questions into a window */ /* on the screen using the cursor keys to select options */ if (isnprint || (PRNRDY == NULL)) { mlwrite("Device LST: is being used"); return(FALSE); } if((s = readpattern("What is your name? ", &prnhdr[0])) != TRUE) return(s); if((s = readpattern("What is today's date? ", &prndate[0])) != TRUE) return(s); if((s = mlyesno("Do you want double spacing? ")) == FALSE) spacing = 1; else spacing = 2; strcpy(prnfin,"~temp\\prn.fin"); parsefn(prnfin); mlwrite("[Writing buffer file: %s page length = %d]", prnfin,pagelen); if(! tabsize) temptab = 8; else temptab = tabsize; rm = 80; printout(prnfin, rm); /* Temp file for buffer */ if((in = open(prnfin, 0)) == EOF) { mlwrite("OPEN failure on buffer file"); return(FALSE); } setprn(cw, spacing, temptab, lm, rm); /* Initialize printer */ isnprint = TRUE; /* We are printing */ /* Initially fill printer buffer */ if ((s = read(in, buf, MYBUF)) > NULL) while (s--) { if (buf[i] == '\n') Cprnout('\r'); if (!(int)gemdos(0x5,buf[i++])) { mlwrite("Write error on LST:"); return(FIOERR); } } return(TRUE); } /* SETPRN Local function to set printer parameters. Mostly uses macros from * printer.h */ static int setprn(pitch, lheight, tabstop, lmarg, rmarg) register int pitch, lheight, tabstop, lmarg, rmarg; { register int i; pitch -= 2; lheight = (lheight * 5) + 4; /* this sort of gives single and */ /* double spacing @ 6 per inch */ RESET; for(i=0;ib_linep); /* First line. */ nline = 0; /* Number of lines. */ linecnt = 0; pagecnt = 1; while (lp != curbp->b_linep) { if (linecnt == 0) { if((s=prhdg(f, pagecnt++, marg)) != TRUE) break; f = TRUE; /* Each new page gets \f */ linecnt += 9; } if ((s=ffputline(&lp->l_text[0], llength(lp))) != FIOSUC) break; ++nline; lp = lforw(lp); if(linecnt > pagelen - 3) { linecnt = 0; continue; } ++linecnt; } if (s == FIOSUC) /* No write error. */ s = ffclose(); if (s != FIOSUC) /* Some sort of error. */ return (FALSE); return (TRUE); } /* This function reads the temp file written above and writes the file to * the list device. It then deletes the temp file. */ prnbuf() { register int stat; register int i; char buf[BUFSIZE]; i = 0; if ((stat = read(in, buf, BUFSIZE)) > NULL) { while(stat--) { if (buf[i] == '\n') Cprnout('\r'); if (!(int)gemdos(0x5,buf[i++])) { mlwrite("Write error on LST:"); return(FIOERR); } } return(TRUE); } isnprint = FALSE; close(in); unlink(prnfin); NEWPAGE; mlwrite("[Printing completed]"); update(); return(TRUE); } SHAR_EOF # End of shell archive exit 0 %NONAME-W-NOMSG, Message number 00000000