home *** CD-ROM | disk | FTP | other *** search
- Path: j.cc.purdue.edu!mentor.cc.purdue.edu!purdue!bu.edu!rpi!julius.cs.uiuc.edu!wuarchive!uunet!papaya.bbn.com!rsalz
- From: rsalz@bbn.com (Rich Salz)
- Newsgroups: comp.sources.unix
- Subject: v23i056: Line oriented macro processor, Part06/09
- Message-ID: <3031@litchi.bbn.com>
- Date: 29 Nov 90 17:43:56 GMT
- Organization: BBN Systems and Technologies, Cambridge MA
- Lines: 1894
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Darren New <new@ee.udel.edu>
- Posting-number: Volume 23, Issue 56
- Archive-name: lome/part06
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 5 (of 9)."
- # Contents: LOME/Comp1.c LOME/LOME8.c LOME/Rubin.mac PPL/PPLAmiga.c
- # TFS/TFSAmiga.c
- # Wrapped by new@estelle.ee.udel.edu on Tue Aug 14 16:09:59 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'LOME/Comp1.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'LOME/Comp1.c'\"
- else
- echo shar: Extracting \"'LOME/Comp1.c'\" \(9022 characters\)
- sed "s/^X//" >'LOME/Comp1.c' <<'END_OF_FILE'
- X/*
- X * Comp1.c
- X * Macro Compiler code file
- X * Copyright 1988, 1990 Darren New.
- X * All rights reserved.
- X */
- X
- X#include "PPL.h"
- X#include "MacroIO.h"
- X
- X#define MacStream 1 /* stream where macros are stored */
- X#define PrgStream 2 /* stream where program to be expanded is stored */
- X#define ExpStream 3 /* stream where expansions written */
- X#define ErrStream 4 /* stream where errors written */
- X
- X#define BUFSIZE 15000
- X
- Xint AssertExit()
- X{
- X MStopIO();
- X PLExit(PLsev_bomb);
- X return 0;
- X }
- X
- Xint BombExit()
- X{
- X return AssertExit();
- X }
- X
- Xint FaultExit()
- X{
- X return AssertExit();
- X }
- X
- Xshort DoIt()
- X{
- X int status;
- X short buf[BUFSIZE];
- X short zero, HeadParm, HeadEOL, BodyParm, BodyEOL;
- X short param[10];
- X int symgen = 100;
- X int FirstToUse = 0;
- X int NextToUse = FirstToUse;
- X char inpline[BIGLINE];
- X
- X /* DEBUG_SETDEFS("RAW:0/190/640/200/Debug window", "T:DBugOut"); */
- X /* DEBUG_ENTER("DoIt", NULL); */
- X
- X MStartIO(PLargcnt, PLarglist);
- X
- X /* Read macro stream until a blank line is encountered */
- X while (M_OK == (status = MGetBuff(MacStream)) && MGetChar() > 0)
- X ;
- X
- X /* Read program stream until a blank line is encountered */
- X while (M_OK == (status = MGetBuff(PrgStream)) && MGetChar() > 0)
- X ;
- X
- X PLStatus(6, "Reading macros...");
- X
- X /* Read special character line from macro stream */
- X if (M_OK != MGetBuff(MacStream)) {
- X PLStatus(1, "Read of special character line failed");
- X MStopIO();
- X /* DEBUG_RETURN(NULL); */
- X PLExit(PLsev_badform);
- X }
- X zero = MGetChar();
- X HeadParm = MGetChar();
- X HeadEOL = MGetChar();
- X BodyParm = MGetChar();
- X BodyEOL = MGetChar();
- X if (zero == 0 || HeadParm == 0 || HeadEOL == 0 ||
- X BodyParm == 0 || BodyEOL == 0 || MGetChar() != 0) {
- X PLStatus(1, "Special character line malformed");
- X MStopIO();
- X /* DEBUG_RETURN(NULL); */
- X PLExit(PLsev_badform);
- X }
- X /* DEBUGF(5, "z=%d, HP=%d, HE=%d, BP=%d, BE=%d" C zero C HeadParm C
- X HeadEOL C BodyParm C BodyEOL); */
- X
- X /* read macros into buf[NextToUse]. Format:
- X buf[k] = start of next macro def line.
- X buf[k+1] = number of symgens used or -1 if none used.
- X buf[k+2] ... buf[k+n] =
- X text of macro template, terminate by 0.
- X buf[k+n+1] ... =
- X lines of macro bodies, each terminated by 0.
- X A PrgParm followed by two digits is replaced by a PrgParam
- X followed by two integers.
- X */
- X while (M_OK == (status = MGetBuff(MacStream))) {
- X int k, c;
- X bool donebody;
- X /* check for enuf room to store line */
- X if (NextToUse + BIGLINE + 10 > BUFSIZE) {
- X PLStatus(1, "Out of memory for macros");
- X MStopIO();
- X /* DEBUG_RETURN(NULL); */
- X PLExit(PLsev_oores);
- X }
- X /* Read template */
- X k = NextToUse;
- X buf[++k] = -1; /* adjusted when symgens found */
- X while ((c = MGetChar()) != 0 && c != HeadEOL) {
- X buf[++k] = c;
- X }
- X buf[++k] = 0;
- X /* Read macro body */
- X donebody = FALSE;
- X while (! donebody && M_OK == (status = MGetBuff(MacStream))) {
- X /* check for enuf room to store line */
- X if (k + BIGLINE + 10 > BUFSIZE) {
- X PLStatus(1, "Out of memory for macros");
- X MStopIO();
- X /* DEBUG_RETURN(NULL); */
- X PLExit(PLsev_oores);
- X }
- X /* copy in body line */
- X c = MGetChar();
- X if (c == 0 || c == BodyEOL) {
- X donebody = TRUE;
- X }
- X else {
- X while (c != 0 && c != BodyEOL) {
- X assert(-1 <= k && k < BUFSIZE);
- X buf[++k] = c;
- X if (c == BodyParm) {
- X short parm, form;
- X parm = MGetChar() - zero;
- X form = MGetChar() - zero;
- X if (parm == -zero || form == -zero) {
- X PLStatus(1, "Unexpected EOL in macro body!");
- X if (fault("Unexpected EOL in macro body!"))
- X break;
- X else
- X bomb("Translation cancelled");
- X }
- X if (parm == 0 && buf[NextToUse + 1] < form)
- X buf[NextToUse + 1] = form;
- X buf[++k] = parm;
- X buf[++k] = form;
- X }
- X c = MGetChar();
- X }
- X buf[++k] = 0;
- X }
- X }
- X buf[NextToUse] = ++k;
- X NextToUse = k;
- X if (NextToUse + BIGLINE + 10 > BUFSIZE) {
- X PLStatus(1, "Out of memory for macros");
- X MStopIO();
- X /* DEBUG_RETURN(NULL); */
- X PLExit(PLsev_oores);
- X }
- X }
- X
- X if (status != M_EOF) {
- X PLStatus(1, "I/O Error reading macros");
- X MStopIO();
- X /* DEBUG_RETURN("Status=%d" C status); */
- X PLExit(PLsev_badform);
- X }
- X
- X/* DEBUGF(7, "NextToUse=%d" C NextToUse); */
- X/* for (status = 0; status < NextToUse; status++)
- XDEBUGF(8, "buf[%4d] = %4d = %c" C status C buf[status] C buf[status]); */
- X
- X PLStatus(6, "Translating program...");
- X
- X while (M_OK == (status = MGetBuff(PrgStream))) {
- X int offset, machead;
- X int paraminx = 0; /* assigned to shut up GCC */
- X bool found;
- X
- X /* Read a line to be expanded */
- X offset = 0;
- X do {
- X inpline[offset] = MGetChar();
- X if (inpline[offset] == HeadEOL)
- X inpline[offset] = 0;
- X } while (inpline[offset++] != 0);
- X
- X /* Search for matching template */
- X machead = FirstToUse; found = FALSE;
- X while (machead < NextToUse && ! found) {
- X bool done;
- X offset = 0; done = FALSE; paraminx = 1;
- X while (!done) {
- X if (buf[machead + 2 + offset] == HeadParm &&
- X inpline[offset] != 0) {
- X param[paraminx++] = inpline[offset++];
- X }
- X else if (inpline[offset] == buf[machead + 2 + offset]) {
- X if (inpline[offset] == 0)
- X done = found = TRUE;
- X else
- X offset += 1;
- X }
- X else if (inpline[offset] != buf[machead + 2 + offset]) {
- X done = TRUE;
- X }
- X }
- X if (! found)
- X machead = buf[machead];
- X }
- X
- X /* Make sure line was found */
- X if (! found) {
- X MPutChar(0); /* clear buffer */
- X MPutChar(zero); /* error zero - not matched */
- X for (offset = 0; inpline[offset]; offset++)
- X MPutChar(inpline[offset]);
- X MPutChar(0); /* terminate buffer */
- X if (M_OK != MPutBuff(ErrStream) || M_OK != MPutBuff(ExpStream)) {
- X PLStatus(1, "Error while writing error message");
- X MStopIO();
- X /* DEBUG_RETURN(NULL); */
- X PLExit(PLsev_badform);
- X }
- X }
- X else {
- X /* Expand the line */
- X offset += 1; /* skip past HeadEOL */
- X MPutChar(0); /* clear output buffer */
- X offset += machead + 2; /* let offset point directly to body */
- X while (offset < buf[machead]) {
- X if (buf[offset] == 0) { /* BodyEOL */
- X MPutChar(0); /* terminate buffer */
- X if (M_OK != MPutBuff(ExpStream)) {
- X PLStatus(1, "Error while writing expansion");
- X MStopIO();
- X /* DEBUG_RETURN(NULL); */
- X PLExit(PLsev_badform);
- X }
- X offset += 1;
- X }
- X else if (buf[offset] == BodyParm) {
- X int parm, form, convnum;
- X parm = buf[offset + 1];
- X form = buf[offset + 2];
- X offset += 3;
- X if (parm < 0 || paraminx <= parm) {
- X MPutChar(0); /* clear buffer */
- X MPutChar(zero + 1); /* error 1 - bad param number */
- X for (offset = 0; inpline[offset]; offset++)
- X MPutChar(inpline[offset]);
- X MPutChar(0); /* terminate buffer */
- X if (M_OK != MPutBuff(ErrStream) ||
- X M_OK != MPutBuff(ExpStream)) {
- X PLStatus(1, "Error while writing error message");
- X MStopIO();
- X /* DEBUG_RETURN(NULL); */
- X PLExit(PLsev_badform);
- X }
- X offset = BUFSIZE;
- X }
- X if (parm == 0) {
- X if (form < 0 || 9 < form) {
- X MPutChar(0); /* clear buffer */
- X MPutChar(zero + 2); /* error 2 - bad digit */
- X for (offset = 0; inpline[offset]; offset++)
- X MPutChar(inpline[offset]);
- X MPutChar(0); /* terminate buffer */
- X if (M_OK != MPutBuff(ErrStream) ||
- X M_OK != MPutBuff(ExpStream)) {
- X PLStatus(1, "Error while writing error message");
- X MStopIO();
- X /* DEBUG_RETURN(NULL); */
- X PLExit(PLsev_badform);
- X }
- X offset = BUFSIZE;
- X }
- X convnum = symgen + form;
- X if (99 < convnum)
- X MPutChar(((convnum / 100) % 10) + zero);
- X if (9 < convnum)
- X MPutChar(((convnum / 10) % 10) + zero);
- X MPutChar((convnum % 10) + zero);
- X }
- X else {
- X if (form == 0)
- X MPutChar(param[parm]);
- X else if (form == 1) {
- X convnum = param[parm];
- X if (99 < convnum)
- X MPutChar(((convnum / 100) % 10) + zero);
- X if (9 < convnum)
- X MPutChar(((convnum / 10) % 10) + zero);
- X MPutChar((convnum % 10) + zero);
- X }
- X else if (form == 2) {
- X convnum = param[parm];
- X MPutChar(((convnum / 100) % 10) + zero);
- X MPutChar(((convnum / 10) % 10) + zero);
- X MPutChar((convnum % 10) + zero);
- X }
- X else {
- X MPutChar(0); /* clear buffer */
- X MPutChar(zero + 3); /* error 3 - bad conv */
- X for (offset = 0; inpline[offset]; offset++)
- X MPutChar(inpline[offset]);
- X MPutChar(0); /* terminate buffer */
- X if (M_OK != MPutBuff(ErrStream) ||
- X M_OK != MPutBuff(ExpStream)) {
- X PLStatus(1, "Error while writing error message");
- X MStopIO();
- X /* DEBUG_RETURN(NULL); */
- X PLExit(PLsev_badform);
- X }
- X offset = BUFSIZE;
- X }
- X }
- X }
- X else {
- X MPutChar(buf[offset++]);
- X }
- X }
- X
- X /* expansion complete - bump symgen */
- X symgen += 1 + buf[machead + 1];
- X }
- X }
- X
- X MStopIO();
- X
- X PLStatus(6, "Translation complete!");
- X
- X /* DEBUG_RETURN(NULL); */
- X
- X return 0;
- X }
- X
- END_OF_FILE
- if test 9022 -ne `wc -c <'LOME/Comp1.c'`; then
- echo shar: \"'LOME/Comp1.c'\" unpacked with wrong size!
- fi
- # end of 'LOME/Comp1.c'
- fi
- if test -f 'LOME/LOME8.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'LOME/LOME8.c'\"
- else
- echo shar: Extracting \"'LOME/LOME8.c'\" \(7966 characters\)
- sed "s/^X//" >'LOME/LOME8.c' <<'END_OF_FILE'
- X/*
- X * LOME8.c
- X * Line Oriented Macro Expander - DoMath()
- X * Copyright 1989 Darren New
- X *
- X */
- X
- X#include "LOME.h"
- X
- X#ifdef HIDPROTS
- XHIDDEN void ConvErr ARGS((str expr));
- XHIDDEN long ConvLetter ARGS((char ch));
- XHIDDEN void StrSubs ARGS((str r, int from, int to, str new));
- XHIDDEN bool GetToken ARGS((str r,int p,int* first,int* last));
- XHIDDEN bool GetParams ARGS((str r, int p, long * p1, long * p2, int * first));
- X#endif
- X
- XHIDDEN void ConvErr ARGS1(str,expr)
- X{
- X char * t = "Intermediate expression causing error:";
- X
- X Message("CONV");
- X
- X MPutChar(0);
- X while (*t) MPutChar(*t++);
- X MPutChar(0);
- X MPutBuff(outstream);
- X
- X t = expr;
- X while (*t) MPutChar(*t++);
- X MPutChar(0);
- X MPutBuff(outstream);
- X
- X TraceBack();
- X /* quitting = TRUE; */
- X }
- X
- XHIDDEN long ConvLetter ARGS1(char,ch)
- X{
- X long valch = -1L;
- X if (0 <= ch - params[O_ZERO] &&
- X ch - params[O_ZERO] <= 9)
- X valch = ch - params[O_ZERO];
- X else if (0 <= ch - params[O_LCA] &&
- X ch - params[O_LCA] <= params[O_UCZ] - params[O_UCA] + 1)
- X valch = 10 + ch - params[O_LCA];
- X else if (0 <= ch - params[O_UCA] &&
- X ch - params[O_UCA] <= params[O_UCZ] - params[O_UCA] + 1)
- X valch = 10 + ch - params[O_UCA];
- X return valch;
- X }
- X
- XHIDDEN void StrSubs ARGS4(str,r,int,from,int,to,str,new)
- X{
- X /* This replaces the section of 'r' from 'r[from]' up to but not
- X including 'r[to]' with 'new' */
- X
- X char newstr[BIGLINE];
- X
- X assert(r != NULL);
- X assert(new != NULL);
- X assert(0 <= from);
- X assert(0 <= to);
- X assert(from <= strlen(r));
- X assert(to <= strlen(r));
- X assert(from <= to);
- X
- X assert(strlen(r) - (to - from) + strlen(new) < BIGLINE);
- X
- X strcpy(newstr, r);
- X newstr[from] = EOS;
- X strcat(newstr, new);
- X strcat(newstr, &r[to]);
- X strcpy(r, newstr);
- X }
- X
- XHIDDEN bool GetToken ARGS4(str,r,int,p,int*,first,int*,last)
- X{
- X /* This simply finds the token preceding r[p] and returns
- X pointers to the first and one-past-the-last characters in
- X *first and *last, respectively. returns TRUE if found, FALSE if not.
- X */
- X
- X assert(r != NULL);
- X assert(first != NULL);
- X assert(last != NULL);
- X assert(0 <= p);
- X assert(p < strlen(r));
- X
- X if (p == 0)
- X return FALSE;
- X
- X p--; /* back up to before operator */
- X
- X while (0 <= p && r[p] == params[O_SPACE])
- X p--;
- X
- X *last = p + 1;
- X if (*last == 0)
- X return FALSE;
- X
- X while (0 < p && r[p] != params[O_SPACE])
- X p--;
- X
- X *first = p + 1;
- X
- X return TRUE;
- X }
- X
- X
- X
- XHIDDEN bool GetParams ARGS5(str,r,int,p,long*,p1,long*,p2,int*,first)
- X{
- X /* This finds the values of the immediately preceeding two
- X tokens (as integers). It returns them in *p1 and *p2.
- X It returns TRUE if both could be parsed as radix-10
- X integers and FALSE if they could not be so parsed (or if
- X there were not two tokens). It returns the index of the first
- X character of the first token in *first (to allow the caller
- X to replace the entire expression with the result).
- X p must be the index of the operator within the string r.
- X */
- X
- X char * paramend;
- X int endofparam;
- X long val;
- X
- X assert(p1 != NULL);
- X assert(p2 != NULL);
- X assert(r != NULL);
- X assert(first != NULL);
- X assert(0 <= p);
- X assert(p < strlen(r));
- X
- X if (p == 0)
- X return FALSE;
- X
- X p--; /* back up to before operator */
- X
- X while (0 <= p && r[p] == params[O_SPACE])
- X p--;
- X endofparam = p + 1;
- X while (0 <= p && r[p] != params[O_SPACE])
- X p--;
- X if (p < 0)
- X return FALSE; /* second param at start of line */
- X val = StrToIntErr(&r[p+1], ¶mend);
- X if (paramend != &r[endofparam])
- X return FALSE;
- X *p2 = val;
- X
- X while (0 <= p && r[p] == params[O_SPACE])
- X p--;
- X endofparam = p + 1;
- X if (p < 0)
- X return FALSE; /* no first parameter found */
- X while (0 <= p && r[p] != params[O_SPACE])
- X p--;
- X val = StrToIntErr(&r[p+1], ¶mend);
- X if (paramend != &r[endofparam])
- X return FALSE;
- X *p1 = val;
- X
- X *first = p+1;
- X
- X return TRUE;
- X }
- X
- X
- X
- Xvoid DoMath ARGS1(int,p /* the parameter number */)
- X{
- X char r[BIGLINE+2];
- X int i, j;
- X
- X assert(0 < tstacksize);
- X assert(0 <= p && p <= 9);
- X
- X if (Sp[p] == NULL || *Sp[p] == 0) {
- X return;
- X }
- X
- X assert(strlen(Sp[p]) < BIGLINE);
- X
- X i = j = 0;
- X r[i++] = ' ';
- X while (Sp[p][j]) {
- X if (Sp[p][j] != params[O_SPACE] || r[i-1] != params[O_SPACE])
- X r[i++] = Sp[p][j];
- X j++;
- X }
- X r[i] = EOS;
- X while (0 < i && r[i-1] == params[O_SPACE])
- X r[--i] = EOS;
- X
- X loop {
- X for (i = 0; i < strlen(r); i++) {
- X if ( (
- X r[i] == params[O_PLUS] ||
- X r[i] == params[O_MINUS] ||
- X r[i] == params[O_MULT] ||
- X r[i] == params[O_DIV] ||
- X r[i] == params[O_FETCH] ||
- X r[i] == params[O_RADIX]
- X ) &&
- X (r[i+1] == EOS || r[i+1] == params[O_SPACE]) ) {
- X break;
- X }
- X }
- X
- X if (r[i] == EOS) {
- X for (j = 1; r[j]; j++)
- X ADDTOLINE(r[j]);
- X ENDLINE();
- X return;
- X }
- X else if (r[i] == params[O_PLUS] || r[i] == params[O_MINUS] ||
- X r[i] == params[O_MULT] || r[i] == params[O_DIV]) {
- X long p1, p2;
- X long answer = 0; /* assign to shut up GCC */
- X int first;
- X bool good;
- X char strbuf[BIGLINE];
- X good = GetParams(r, i, &p1, &p2, &first);
- X if (!good) {
- X ConvErr(r);
- X return;
- X }
- X else {
- X if (r[i] == params[O_PLUS])
- X answer = p1 + p2;
- X
- X if (r[i] == params[O_MINUS])
- X answer = p1 - p2;
- X
- X if (r[i] == params[O_MULT])
- X answer = p1 * p2;
- X
- X if (r[i] == params[O_DIV]) {
- X if (p2 != 0)
- X answer = p1 / p2;
- X else {
- X ConvErr(r);
- X return;
- X }
- X }
- X
- X IntToStr(answer, strbuf);
- X StrSubs(r, first, i+1, strbuf);
- X }
- X }
- X else if (r[i] == params[O_FETCH]) {
- X int first, last;
- X char varname[BIGLINE];
- X char * varvalue;
- X bool good;
- X good = GetToken(r, i, &first, &last);
- X if (!good) {
- X ConvErr(r);
- X return;
- X }
- X else {
- X for (j = first; j < last; j++)
- X varname[j-first] = r[j];
- X varname[last-first] = EOS;
- X varvalue = VarLookup(varname);
- X if (varvalue == NULL) {
- X ConvErr(r);
- X return;
- X }
- X else {
- X StrSubs(r, first, i+1, varvalue);
- X }
- X }
- X }
- X else if (r[i] == params[O_RADIX]) {
- X int f1, l1, f2, l2, f3, l3;
- X int j, k;
- X long sign, val, valch, from, to;
- X bool good;
- X char newstr[BIGLINE];
- X char revstr[BIGLINE];
- X
- X good = GetToken(r, i, &f3, &l3);
- X if (!good || f3 != l3 - 1) {
- X ConvErr(r);
- X return;
- X }
- X
- X good = GetToken(r, f3, &f2, &l2);
- X if (!good || f2 != l2 - 1) {
- X ConvErr(r);
- X return;
- X }
- X
- X good = GetToken(r, f2, &f1, &l1);
- X if (!good) {
- X ConvErr(r);
- X return;
- X }
- X
- X from = ConvLetter(r[f2]);
- X if (from < 1) {
- X ConvErr(r);
- X return;
- X }
- X
- X to = ConvLetter(r[f3]);
- X if (to < 1) {
- X ConvErr(r);
- X return;
- X }
- X
- X sign = 1L; val = 0L;
- X for (j = f1; j < l1; j++) {
- X if (r[j] == params[O_MINUS] && j == f1) {
- X sign = -1L;
- X valch = 0;
- X continue;
- X }
- X else if (r[j] == params[O_PLUS] && j == f1) {
- X sign = 1L;
- X valch = 0;
- X continue;
- X }
- X else {
- X valch = ConvLetter(r[j]);
- X if (valch < 0 || from < valch) {
- X ConvErr(r);
- X return;
- X }
- X val = val * (from + 1) + valch;
- X }
- X }
- X
- X j = 0;
- X if (sign < 0L) {
- X newstr[0] = params[O_MINUS];
- X newstr[j = 1] = EOS;
- X }
- X
- X if (val == 0) {
- X newstr[0] = params[O_ZERO];
- X newstr[j = 1] = EOS;
- X }
- X else {
- X while (val != 0) {
- X valch = val % (to + 1);
- X val /= (to + 1);
- X if (valch < 10)
- X newstr[j++] = valch + params[O_ZERO];
- X else
- X newstr[j++] = valch - 10 + params[O_UCA];
- X }
- X }
- X newstr[j] = EOS;
- X
- X if (newstr[0] == params[O_MINUS]) {
- X revstr[0] = newstr[0];
- X for (k = 1, j--; 1 <= j; j--, k++)
- X revstr[k] = newstr[j];
- X }
- X else {
- X for (k = 0, j--; 0 <= j; j--, k++)
- X revstr[k] = newstr[j];
- X }
- X revstr[k] = EOS;
- X
- X StrSubs(r, f1, i + 1, revstr);
- X
- X }
- X else {
- X bomb("You can't get there from here");
- X }
- X /* end of infinite loop */
- X }
- X }
- X
- END_OF_FILE
- if test 7966 -ne `wc -c <'LOME/LOME8.c'`; then
- echo shar: \"'LOME/LOME8.c'\" unpacked with wrong size!
- fi
- # end of 'LOME/LOME8.c'
- fi
- if test -f 'LOME/Rubin.mac' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'LOME/Rubin.mac'\"
- else
- echo shar: Extracting \"'LOME/Rubin.mac'\" \(8668 characters\)
- sed "s/^X//" >'LOME/Rubin.mac' <<'END_OF_FILE'
- XFILE: Rubin&.mac
- XThe following message describes a fairly complex translation that is
- Xdesired by the sender. This file contains my solution, along with a
- Xdescription of how to use it. The basic operation is to recognise one
- Xcomponent of the assember-like line, handle it, and remove it. Very
- Xlittle complexity is present except for the large number of options,
- Xso only a small number of different substitutions are used and no file
- Xor control operations are needed.
- X--------------------------------------------------------------
- X>>From: Herman Rubin <cik@l.cc.purdue.edu>
- X>>To: new@ee.udel.edu
- X>>Date: Mon, 16 Jul 90 09:50:54 -0500
- X>>Subject: Re: It looks like he's at it again!
- X>>>I still cannot figure it out. Maybe if you can show me how to do one
- X>>>example, it might help. The way I want to write the macro is
- X>>>
- X>>> c{'z} ={tc} {-}{|}{ta}a{'x} OP{mod} {|}{tb}b{'y} {/\{~}w}
- X>>>
- X>>>with the usual convention that fields in braces are optional. If knowing
- X>>>what the fields mean will help, I will provide this information. It is
- X>>>desired to write this either as an assembler instruction or a s CALLQ8
- X>>>instruction to be inserted in a Fortran program. The types of the
- X>>>a, b, and c are relevant.
- X>>
- X>>The code is for the CYBER 205/ETA 10. I will illustrate the conversion
- X>>desired not to assembler, which I have not written, but to inserted
- X>>instructions in Fortran, which is very similar. This does use symbolic
- X>>names mostly, with a few exceptions. However, if I can manage this, I
- X>>should be able to manage the assembler as well.
- X>>
- X>>The format of the output instruction is (I will use small letters, although
- X>>Fortran normally uses capitals)
- X>>
- X>> callq8 mnemonic(g,x,a,y,b,w,c)
- X>>
- X>>A field omitted is the same as that field being 0, but the commas must still
- X>>be there. A vector is indicated by its descriptor, which is a full word
- X>>having the length and starting address. A length 0 vector is useful, as
- X>>the offset can move before the start. The type of the vector (linguistic)
- X>>is full or half, integer or float. There are also bit vectors. A scalar
- X>>also has the same type possibilities. I may have some details wrong, but
- X>>they can easily be fixed up. An offset value must be in a full word register.
- X>>Fortran normally has all its descriptors and variables in registers, but not
- X>>any of the vectors. The g field in this usage is given by a hex number, and
- X>>the various bits will be explained.
- X>>
- X>>The a, b, and c fields are either the descriptors (vector) or the locations
- X>>(scalar). The x, y, and z fields, if present, are full-word registers. The
- X>>w field, if present, is the address of the beginning of a bit vector. If z
- X>>is present, c must be in an even numbered register and z in the next register.
- X>>Register 0 is unusable, and address 0 means not present.
- X>>
- X>>mnemonic refers to the operation and type. Given the type of c and the
- X>>operation, this is translated normally (+ becomes add, etc.) except that
- X>>the default modification of the instruction for the type of c can be changed
- X>>by the mod field. For example, for add the mod fields are u,l,n, and x.
- X>>For floats, n would be the default, and for integers, u.
- X>>
- X>>The bits of g are
- X>>
- X>> 80 half tc can be used to override the default.
- X>> 40 complement the bit vector w (the ~)
- X>> 20 use z for an offset to c and w ('z present)
- X>> 10 a is scalar, not vector. ta overrides the default
- X>> 08 b is scalar, not vector. tb overrides the default
- X>> 04 the absolute value of a is taken (the | before a)
- X>> 02 negate a (the -).
- X>> 01 the absolute value of b is taken (the | before b)
- X>>
- X>>I hope this gives you a better idea of what I am trying to do. It is
- X>>possible that if I can see how to do this, I might know how to handle
- X>>other cases.
- X--------------------------------------------------------------
- XSince distinguishing between legal FORTRAN and this assembler-like
- Xsyntax would be difficult, each assembler line must start with exactly
- Xone asterisk followed by one space. Lines that start with two
- Xasterisks are reserved for this use. This has the added benefit of
- Xmaking such programs illegal to the FORTRAN compiler before being run
- Xthrough LOME.
- X------
- XNote also that in Dr. Rubin's description, the "z" parameter is never
- Xpassed to the FORTRAN function, no explaination of how to distinguish
- Xhex addresses from variable names is given, and that results of the
- Xoperation depend on the type of variables. The first is solved by
- Xpassing "z" as the last argument. The second is "solved" by ignoring
- Xthe possibility of hex numbers as arguments. The last is impossible to
- Xsolve without either explicitly passing types as separate
- Xassembler-like statements or parsing some of the FORTRAN source and is
- Xhence ignored. This is, after all, tutorial.
- X
- X&@.@$0AaZFC`'()+-*/?!XXXX 000000000000
- X* @. Match anything that starts with one star and a space
- X$ This just sets up the variables to their default values.
- X$ The arguments to the callq8 statement (g,x,y,w,z)
- X$ are initialized here and set as they are matched in later productions.
- X$ This is probably not the best way to do it, but it does illustrate
- X$ some points.
- XG@970@98$ set variable G to zero
- XX@970@98$ set variable X to zero
- XY@970@98$ set variable Y to zero
- XZ@970@98$ set variable Z to zero
- XW@970@98$ set variable W to zero
- XC @00$ output the original line as a comment
- X**@00$ reparse the line without reinitializing
- X$$
- X***GenFormat(@,@,@).
- X$ 0 1 2
- X$ This generates the instruction from the LOME variables stored
- X$ in G, X, Y, Z, W, and OP
- XOP@47G@57X@67Y@77Z@87W@97$ set up variable names
- X@53@57$ replace param 5 with contents of G
- X@52@57$ replace param 5 with contents of G evaluated as math
- X CALLQ8 @43(@50,@63,@00,@73,@10,@93,@20,@83)
- X$ Z@F6$ Debugging dump if needed
- X$$
- X
- X**@ =@ @ @ @ /\~@. see if ~w is present
- X$ 0 1 2 3 4 5
- XW@97@50@98$ set variable W to the contents of parameter five
- XG@97@93 64 +@98$ add 64 to G
- X**@00 =@10 @20 @30 @40$ resubmit
- X$$
- X**@ =@ @ @ @ /\@. see if w is present
- X$ 0 1 2 3 4 5
- XW@97@50@98$ set variable W to the contents of parameter five
- X**@00 =@10 @20 @30 @40$ resubmit
- X$$
- X
- X**@ =@ -@ @ @. see if "a" is negated
- X$ 0 1 2 3 4
- XG@97@93 2 +@98$ add 2 to G
- X**@00 =@10 @20 @30 @40$ resubmit
- X$$
- X**@ =@ |@ @ @. see if "a" is abs'ed
- X$ 0 1 2 3 4
- XG@97@93 4 +@98$ add 2 to G
- X**@00 =@10 @20 @30 @40$ resubmit
- X$$
- X**@ =@ @ @ |@. see if "b" is abs'ed
- X$ 0 1 2 3 4
- XG@97@93 1 +@98$ add 1 to G
- X**@00 =@10 @20 @30 @40$ resubmit
- X$$
- X
- X**@'@ =@ @ @ @. see if z is present
- X$ 0 1 2 3 4 5
- XZ@97@10@98$ set variable Z to the contents of parameter one
- XG@97@93 32 +@98$ add 32 to G
- X**@00 =@20 @30 @40 @50$ resubmit
- X$$
- X**@ =@ @'@ @ @. see if x is present
- X$ 0 1 2 3 4 5
- XX@97@30@98$ set variable X to the contents of parameter 3
- X**@00 =@10 @20 @40 @50$ resubmit
- X$$
- X**@ =@ @ @'@. see if y is present
- X$ 0 1 2 3 4
- XY@97@40@98$ set variable Y to the contents of parameter 4
- X**@00 =@10 @20 @30$ resubmit
- X$$
- X
- X**@ =(half) @ @ @. check if tc is half-length
- X$ 0 1 2 3
- X$ Since I can't really figure out what tc, ta, tb and mod are supposed
- X$ to mean, this is kind of a guess.
- XG@97@93 128 +@98$ add 128 to G
- X**@00 = @10 @20 @30 @40$ resubmit
- X$$
- X**@ =(full) @ @ @. check if tc is full-length
- X$ 0 1 2 3
- X$ This is here for completeness.
- X**@00 = @10 @20 @30 @40$ resubmit
- X$$
- X
- X**@ = (scalar)@ @ @. check if a should be scalar
- X$ 0 1 2 3
- XG@97@93 16 +@98$ add 16 to G
- X**@00 = @10 @20 @30$ resubmit
- X$$
- X**@ = (vector)@ @ @. check if a should be vector
- X$ 0 1 2 3
- X$ This is here for completeness
- X**@00 = @10 @20 @30$ resubmit
- X$$
- X**@ = @ @ (scalar)@. check if b should be scalar
- X$ 0 1 2 3
- XG@97@93 8 +@98$ add 8 to G
- X**@00 = @10 @20 @30$ resubmit
- X$$
- X**@ = @ @ (vector)@. check if b should be scalar
- X$ 0 1 2 3
- X$ This is here for completeness
- X**@00 = @10 @20 @30$ resubmit
- X$$
- X
- X**@ = @ +@ @. check for addition
- X$ 0 1 2 3
- XOP@97ADD@20@98$ store "ADD" and modifier in OP
- X***GenFormat(@00,@10,@30)$ output instruction
- X$$
- X**@ = @ -@ @. check for subtraction
- X$ 0 1 2 3
- XOP@97SUB@20@98$ store "SUB" and modifier in OP
- X***GenFormat(@00,@10,@30)$ output instruction
- X$$
- X**@ = @ *@ @. check for multiplication
- X$ 0 1 2 3
- XOP@97MULT@20@98$ store "MULT" and modifier in OP
- X***GenFormat(@00,@10,@30)$ output instruction
- X$$
- X**@ = @ /@ @. check for division
- X$ 0 1 2 3
- XOP@97DIV@20@98$ store "DIV" and modifier in OP
- X***GenFormat(@00,@10,@30)$ output instruction
- X$$
- X
- X**@. check if I didn't reformat something correctly
- XUnrecognised text: @00@C0
- X$$
- END_OF_FILE
- if test 8668 -ne `wc -c <'LOME/Rubin.mac'`; then
- echo shar: \"'LOME/Rubin.mac'\" unpacked with wrong size!
- fi
- # end of 'LOME/Rubin.mac'
- fi
- if test -f 'PPL/PPLAmiga.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'PPL/PPLAmiga.c'\"
- else
- echo shar: Extracting \"'PPL/PPLAmiga.c'\" \(8753 characters\)
- sed "s/^X//" >'PPL/PPLAmiga.c' <<'END_OF_FILE'
- X/*
- X * PPLAmiga.c
- X * Portable Programmer's Library General Host Code
- X * Amiga version
- X * Copyright 1988, 1990 Darren New. All Rights Reserved.
- X *
- X * Started 19-Feb-88 DHN
- X * LastMod 20-jul-90 DHN
- X *
- X */
- X
- X#include "PPL.h"
- X
- X#include "proto/dos.h"
- X
- X#define MAXARGC 20 /* max # args we are willing to remember */
- X
- X
- XHIDDEN long memcount;
- X
- XHIDDEN long OutHand; /* file hand for PLPutChar() */
- XHIDDEN long InHand; /* file hand for PLGetChar() */
- X
- Xvoid PLExit(severity)
- X short severity;
- X{
- X /*
- X if (memcount != 0)
- X DEBUGF(1, "%ld blocks of allocated memory remain!" C memcount);
- X DEBUG_EXIT();
- X */
- X
- X exit((int) severity);
- X }
- X
- Xptr PLAllocMem(size, flags)
- X long size;
- X int flags;
- X{
- X
- X#ifdef CHECKALLOC
- X
- X /* Note that this has some debugging stuff in it */
- X /**** OLD -- MUST BE CHECKED!! ****/
- X ptr retval;
- X inx i;
- X assert(size < BIGMEM);
- X retval = (ptr) malloc(size + sizeof(long) + sizeof(long) + (size & 1));
- X if (retval == NULL) {
- X if (flags & PLalloc_die) {
- X bomb("Out of Memory");
- X PLExit(PLsev_oores);
- X }
- X else
- X return retval;
- X }
- X else {
- X if (flags & PLalloc_zero)
- X for (i = size + 2 * sizeof(long) + (size & 1) - 1; 0 <= i; i--)
- X retval[i] = '\0';
- X memcount += 1;
- X (* (long *) retval) = 0xA5A55A5A;
- X (* (long *) (retval + sizeof(long) + size + (size & 1))) = 0x5A5AA5A5;
- X return retval + sizeof(long);
- X }
- X
- X#else
- X
- X extern void * malloc(unsigned);
- X char * retval;
- X inx i;
- X assert(size < BIGMEM);
- X assert(size < 65530L);
- X assert(0 < size);
- X retval = malloc((unsigned) size);
- X if (retval == NULL) {
- X if (flags & PLalloc_die) {
- X bomb("Out of Memory");
- X PLExit(PLsev_oores);
- X }
- X else {
- X return NULL;
- X }
- X }
- X else {
- X if (flags & PLalloc_zero) {
- X for (i = 0; i < size; i++) {
- X retval[i] = '\0';
- X }
- X }
- X memcount += 1;
- X return (ptr) retval;
- X }
- X
- X#endif
- X
- X }
- X
- X
- Xvoid PLFreeMem(where)
- X ptr where;
- X{
- X
- X#ifdef CHECKALLOC
- X
- X /* note that this has some debugging stuff in it */
- X assert(where != NULL);
- X where -= sizeof(long);
- X if (* (long *) where == 0x19919119)
- X bomb("Freed memory twice!");
- X if (* (long *) where != 0xA5A55A5A)
- X bomb("Freed non-malloced memory!");
- X (* (long *) where) = 0x19919119;
- X free(where);
- X memcount -= 1;
- X
- X#else
- X
- X extern void free(void *);
- X assert(where != NULL);
- X free(where);
- X memcount -= 1;
- X
- X#endif
- X
- X }
- X
- Xstr PLStrDup(s)
- X str s;
- X{
- X str t;
- X t = PLAllocMem(strlen(s)+1, PLalloc_die);
- X strcpy((char *) t, (char *) s);
- X return t;
- X }
- X
- Xvoid PLCopyMem(to, from, siz)
- X ptr to;
- X ptr from;
- X long siz;
- X{
- X /* be lazy and use lattice function here */
- X extern void *memcpy(void *, void *, unsigned);
- X assert(0 < siz);
- X assert(siz < BIGMEM);
- X assert(NULL != to);
- X assert(NULL != from);
- X (void) memcpy((char *) to, (char *) from, (unsigned) siz);
- X }
- X
- Xvoid PLFillMem(where, siz, chr)
- X ptr where;
- X long siz;
- X char chr;
- X{
- X char * whr = where;
- X assert(whr != NULL);
- X assert(0 < siz);
- X assert(siz < 32760);
- X assert(siz < BIGMEM);
- X
- X /* setmem((char *) where, (unsigned) siz, chr); */
- X
- X /* I don't trust Lattice at this point... */
- X while (0 < siz--)
- X *whr++ = chr;
- X }
- X
- Xptr PLFindMem(where, siz, chr)
- X ptr where;
- X long siz;
- X char chr;
- X{
- X extern void *memchr(void *, int, unsigned);
- X assert(where != NULL);
- X assert(0 < siz);
- X assert(siz < BIGMEM);
- X return (ptr) memchr((char *) where, chr, (unsigned) siz);
- X }
- X
- X
- X/* The error strings: */
- XHIDDEN str PLerrstrs[] = {
- X /* 0*/ "No Error",
- X /* 1*/ "DOS error (retryable)",
- X /* 2*/ "DOS error (wait/retry)",
- X /* 3*/ "DOS error (please fix)",
- X /* 4*/ "DOS error (failure)",
- X /* 5*/ "Program fault",
- X /* 6*/ "End of data during input",
- X /* 7*/ "Out of resource during output",
- X /* 8*/ "Multiple errors occured without being cleared",
- X /* 9*/ "Item does not exist",
- X /*10*/ "Item already exists",
- X /*11*/ "You are not allowed to do that",
- X /*12*/ "That opperation is not supported here",
- X /*13*/ "Item is busy",
- X /*14*/ "Item name missing or incorrectly formed",
- X /*15*/ "Not Yet Implemented",
- X /*16*/ "Cannot be Implemented",
- X /*17*/ "Argument to internal function semantically invalid",
- X /*18*/ "Overflow error",
- X /*19*/ "Underflow error",
- X /*20*/ "User break or interrupted system call",
- X /*21*/ "Error number out of range",
- X NULL
- X };
- X
- XPLerr_enum PLerr;
- X
- XHIDDEN char * OSerrstrs[] = {
- X "103: insufficient free store",
- X "105: task table full",
- X "120: argument line invalid or too long",
- X "121: file is not an object module",
- X "122: invalid resident library during load",
- X "202: object in use",
- X "203: object already exists",
- X "204: directory not found",
- X "205: object not found",
- X "206: invalid window description",
- X "209: packet request type unknown",
- X "210: stream name component invalid",
- X "211: invalid object lock",
- X "212: object not of required type",
- X "213: disk not validated",
- X "214: disk write-protected",
- X "215: rename across devices attempted",
- X "216: directory not empty",
- X "218: device (or volume) not mounted",
- X "219: seek failure",
- X "220: comment too big",
- X "221: disk full",
- X "222: file is protected from deletion",
- X "223: file is write protected",
- X "224: file is read protected",
- X "225: not a valid DOS disk",
- X "226: no disk in drive",
- X "232: no more entries in directory",
- X NULL
- X };
- X
- Xint OSerr;
- X
- X/* The file and line of the last error (mainly for debugging) */
- Xstr PLerr_file;
- Xlong PLerr_line;
- X
- Xstr PLErrText()
- X{
- X if ( PLerr < 0 || PLerr_last < PLerr )
- X PLerr = PLerr_last;
- X return PLerrstrs[PLerr];
- X }
- X
- Xstr PLOSErrText()
- X{
- X inx i;
- X char t[4];
- X static char buf[64];
- X
- X t[0] = (char) (OSerr / 100 % 10);
- X t[1] = (char) (OSerr / 10 % 10);
- X t[2] = (char) (OSerr / 1 % 10);
- X t[3] = EOS;
- X strcpy(buf, "Fault ");
- X
- X for (i = 0; OSerrstrs[i] != NULL; i++)
- X if (t[0] == OSerrstrs[i][0] && t[1] == OSerrstrs[i][1] &&
- X t[2] == OSerrstrs[i][2])
- X break;
- X
- X if (OSerrstrs[i] != NULL) {
- X strcat(buf, OSerrstrs[i]);
- X }
- X else {
- X strcat(buf, t);
- X }
- X
- X return buf;
- X }
- X
- Xshort PLstatuslevel = 6;
- X
- Xvoid PLStatus(level, message)
- X short level;
- X str message;
- X{
- X /* char lev = PLtodig(level); */
- X if (PLstatuslevel < level)
- X return;
- X if (PLcmdname && *PLcmdname) {
- X Write(Output(), PLcmdname, strlen(PLcmdname));
- X Write(Output(), ": ", 2);
- X }
- X /* Write(Output(), "(", 1);
- X Write(Output(), &lev, 1);
- X Write(Output(), ") ", 2);
- X */
- X Write(Output(), message, (long) strlen(message));
- X Write(Output(), "\n", 1);
- X }
- X
- Xvoid PLDelay(secs)
- X short secs;
- X{
- X assert(0 <= secs);
- X if (secs != 0)
- X Delay((long) secs * 50L);
- X }
- X
- Xvoid PLBeep(how)
- X short how;
- X{
- X /* for now, always just flash */
- X /* later, we will open the audio.device and so on... */
- X
- X /* extern void DisplayBeep(void); */
- X /* DisplayBeep(); */
- X Write(Output(), "\007", 1L);
- X }
- X
- X/* get the next character from "standard input" */
- X
- Xshort PLGetChar()
- X{
- X char ch;
- X int res;
- X if (InHand)
- X res = Read(InHand, &ch, 1);
- X else
- X res = -1;
- X if (res == 0)
- X return -1;
- X else if (res < 0)
- X return -2;
- X else
- X return (short) ch;
- X }
- X
- X/* This should send the indicated character to the "standard output". */
- Xvoid PLPutChar(short ch)
- X{
- X char chr = (char) ch;
- X if (OutHand)
- X Write(OutHand, &chr, 1);
- X }
- X
- Xvoid PLResetInput()
- X{
- X InHand = Open("*", MODE_OLDFILE);
- X }
- X
- Xvoid PLResetOutput()
- X{
- X OutHand = Open("*", MODE_OLDFILE);
- X }
- X
- X
- X
- X
- X/* This gives the name of the command, if available.
- X */
- Xstr PLcmdname;
- X
- X/* This gives the host-syntax filename for the executable file,
- X * if available.
- X */
- Xstr PLcmdfile;
- X
- X/* This tells how many command-line arguments there were, excluding
- X * the command name.
- X */
- Xshort PLargcnt;
- X
- X/* This is the array of command-line argument strings.
- X */
- Xstr PLarglist[MAXARGC];
- X
- X/* These are the flags describing the command-line parameters.
- X */
- Xlong PLargflags;
- X
- X/* Here is the main() that sets all this up, calls DoIt() and exits.
- X */
- X
- X#if HIDPROTS
- Xvoid main ARGS((int argc, char * argv[]));
- X#endif
- X
- Xvoid main(argc, argv)
- X int argc;
- X char * argv[];
- X{
- X /* Eventually, we will want to init PLstatuslevel from an env var,
- X or something similar. */
- X
- X OutHand = Output();
- X InHand = Input();
- X
- X if (0 < argc) {
- X char * cp;
- X inx i;
- X cp = argv[0] + strlen(argv[0]) - 1;
- X while (argv[0] < cp && *cp != '/' && *cp != ':')
- X cp -= 1;
- X PLcmdname = cp;
- X PLargcnt = argc - 1;
- X for (i = 1; i < argc && i < MAXARGC; i++)
- X PLarglist[i-1] = argv[i];
- X }
- X PLExit(DoIt());
- X }
- X
- X
- X/************* END OF FILE ***************/
- X
- X
- X
- END_OF_FILE
- if test 8753 -ne `wc -c <'PPL/PPLAmiga.c'`; then
- echo shar: \"'PPL/PPLAmiga.c'\" unpacked with wrong size!
- fi
- # end of 'PPL/PPLAmiga.c'
- fi
- if test -f 'TFS/TFSAmiga.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'TFS/TFSAmiga.c'\"
- else
- echo shar: Extracting \"'TFS/TFSAmiga.c'\" \(9122 characters\)
- sed "s/^X//" >'TFS/TFSAmiga.c' <<'END_OF_FILE'
- X/*
- X * TFSAmiga.c
- X * Portable Programmer's Library Text File Subsystem Code File
- X * Copyright 1988 Darren New. All Rights Reserved.
- X *
- X * Started: 26-Feb-88 DHN
- X * LastMod: 04-dec-88 DHN
- X *
- X * Version One for Amiga -- Simple, just to get running
- X *
- X */
- X
- X#include "PPL.h"
- X#include "TFS.h"
- X
- X#include "libraries/dos.h"
- X#include "proto/dos.h"
- X
- X#define MAXTFS 15 /* max # TFSfiles open at once */
- X
- XHIDDEN struct { /* one open file */
- X str name;
- X long fhand;
- X str modes;
- X } ftab[MAXTFS];
- X
- XHIDDEN bool TFShbi = FALSE; /* has been init */
- XHIDDEN short TFSfree; /* number of free ftab entries */
- X
- XHIDDEN struct FileInfoBlock * fib; /* cuts down allocation overhead */
- X
- X
- X
- X#define HND (handle - 1) /* for convenience */
- X
- X
- Xvoid TFSInit()
- X{
- X inx i;
- X assert(TFShbi == FALSE);
- X TFShbi = TRUE;
- X for (i = 0; i < MAXTFS; i++)
- X ftab[i].name = ftab[i].modes = NULL;
- X /* fib = AllocMem(sizeof(struct FileInfoBlock), MEMF_PUBLIC);
- X if (fib == NULL) bomb("Out of Memory!"); */
- X fib = (struct FileInfoBlock *)
- X PLAllocMem(sizeof(struct FileInfoBlock), PLalloc_die);
- X assert((((long) fib) & 3) == 0);
- X TFSfree = MAXTFS;
- X PLErrClr();
- X }
- X
- Xbool TFSHasBeenInit()
- X{
- X return TFShbi;
- X }
- X
- Xvoid TFSTerm()
- X{
- X int i;
- X assert(TFShbi);
- X for (i = 0; i < MAXTFS; i++) {
- X if (ftab[i].modes != NULL) {
- X Close(ftab[i].fhand);
- X PLFreeMem(ftab[i].modes);
- X PLFreeMem(ftab[i].name);
- X }
- X }
- X PLFreeMem((ptr) fib);
- X TFSfree = 0;
- X TFShbi = FALSE;
- X PLErrClr();
- X }
- X
- X
- XTFSfile TFSOpen(fname, mode)
- X str fname;
- X str mode;
- X{
- X
- X /**** NOTE THIS MUST BE CHANGED TO REMEMBER NAMES IN FULL LENGTH
- X OR RELATIVE TO A LOCK! ****/
- X
- X BPTR flock;
- X BPTR fhand;
- X bool mL, mC, mT, mA, mR, mW, mP, mD;
- X long t; /* temp value */
- X inx i;
- X
- X#define setup(a,b) {a = (NULL != strchr(mode, b));}
- X
- X assert(TFShbi);
- X#if CHKARGS
- X if (fname == NULL || mode == NULL || *fname == EOS || *mode == EOS ||
- X BIGFNAME <= strlen(fname) ) {
- X PLErrSet(PLerr_badarg);
- X return 0;
- X }
- X#endif
- X
- X setup(mL, 'L'); setup(mC, 'C'); setup(mT, 'T');
- X setup(mA, 'A'); setup(mR, 'R'); setup(mW, 'W');
- X setup(mP, 'P'); setup(mD, 'D');
- X
- X#if CHKARGS
- X if ( (mR && mW) || (mP && !mR && !mC) || (mW && !mA && !mT) ||
- X (mA && mT) || (mA && !mW) || (mT && !mW) ) {
- X PLErrSet(PLerr_badarg);
- X return 0;
- X }
- X#endif
- X
- X if (TFSfree == 0 && ! mL) {
- X PLErrSet(PLerr_oores);
- X return 0;
- X }
- X
- X flock = Lock(fname, mR ? ACCESS_READ : ACCESS_WRITE);
- X if (flock == 0 && !mC) {
- X OSerr = IoErr();
- X PLErrSet(PLerr_exist);
- X return 0;
- X }
- X
- X if (flock != 0) {
- X /* file exists -- check it out */
- X
- X if (0 == Examine(flock, fib)) {
- X OSerr = IoErr();
- X UnLock(flock);
- X PLErrSet(PLerr_opsysF);
- X return 0;
- X }
- X
- X t = fib->fib_Protection; /* bits indicate denied permisions */
- X if ( ((t & FIBF_READ) && mR) || ((t & FIBF_WRITE) && mW) ||
- X ((t & FIBF_DELETE) && mD) ) {
- X PLErrSet(PLerr_permit);
- X UnLock(flock);
- X return 0;
- X }
- X
- X if ((mR || mW) && (fib->fib_DirEntryType > 0)) {
- X PLErrSet(PLerr_unsup);
- X UnLock(flock);
- X return 0;
- X }
- X
- X UnLock(flock);
- X fhand = Open(fname, mT ? MODE_NEWFILE : MODE_OLDFILE);
- X if (fhand == 0) {
- X OSerr = IoErr();
- X PLErrSet(PLerr_opsysF);
- X return 0;
- X }
- X if (IsInteractive(fhand) && mP) {
- X Close(fhand);
- X PLErrSet(PLerr_unsup);
- X return 0;
- X }
- X
- X if (mL) {
- X Close(fhand);
- X PLErrClr();
- X return 1;
- X }
- X
- X for (i = 0; i < MAXTFS && ftab[i].modes; i++)
- X ;
- X assert(i < MAXTFS);
- X ftab[i].fhand = fhand;
- X ftab[i].modes = PLStrDup(mode);
- X ftab[i].name = PLStrDup(fname);
- X
- X if (mA) Seek(fhand, 0, OFFSET_END);
- X
- X return (TFSfile) (i + 1);
- X }
- X else {
- X /* file does not exist -- create it */
- X
- X fhand = Open(fname, MODE_NEWFILE);
- X if (fhand == 0) {
- X OSerr = IoErr();
- X PLErrSet(PLerr_opsysU);
- X return 0;
- X }
- X
- X if (mL) {
- X Close(fhand);
- X DeleteFile(fname);
- X PLErrClr();
- X return 1;
- X }
- X
- X for (i = 0; i < MAXTFS && ftab[i].modes; i++)
- X ;
- X assert(i < MAXTFS);
- X ftab[i].fhand = fhand;
- X ftab[i].modes = PLStrDup(mode);
- X ftab[i].name = PLStrDup(fname);
- X
- X return (TFSfile) (i + 1);
- X }
- X }
- X
- Xbool TFSClose(handle)
- X TFSfile handle;
- X{
- X assert(TFShbi);
- X#if CHKARGS
- X if (HND < 0 || MAXTFS <= HND || ftab[HND].modes == NULL) {
- X PLErrSet(PLerr_badarg);
- X return FALSE;
- X }
- X#endif
- X assert(ftab[HND].fhand != NULL);
- X assert(ftab[HND].name != NULL);
- X assert(ftab[HND].modes != NULL);
- X
- X Close(ftab[HND].fhand);
- X PLFreeMem((ptr) ftab[HND].modes);
- X PLFreeMem((ptr) ftab[HND].name);
- X ftab[HND].name = ftab[HND].modes = NULL;
- X PLErrClr();
- X return TRUE;
- X }
- X
- Xbool TFSDestroy(handle)
- X TFSfile handle;
- X{
- X char fn[BIGLINE];
- X bool flag;
- X int err;
- X
- X assert(TFShbi);
- X#if CHKARGS
- X if (HND < 0 || MAXTFS <= HND || ftab[HND].modes == NULL) {
- X PLErrSet(PLerr_badarg);
- X return FALSE;
- X }
- X#endif
- X strcpy(fn, ftab[HND].name);
- X flag = (NULL != strchr(ftab[HND].modes, 'D'));
- X
- X Close(ftab[HND].fhand);
- X PLFreeMem(ftab[HND].name);
- X PLFreeMem(ftab[HND].modes);
- X ftab[HND].modes = NULL;
- X
- X if (flag) {
- X err = DeleteFile(fn); /* permission checked during open */
- X if (err == 0) {
- X OSerr = IoErr();
- X PLErrSet(PLerr_opsysF);
- X return FALSE;
- X }
- X else {
- X PLErrClr();
- X return TRUE;
- X }
- X }
- X else {
- X PLErrSet(PLerr_badarg);
- X return FALSE;
- X }
- X }
- X
- X/* @$@$
- XTFSInfo() - Determine file parameters. This may return various
- Xparameters about the given file. The description of the information
- Xreturned is given in the TFS.h file.
- X*/
- X
- X
- Xshort TFSRead(handle, buf)
- X TFSfile handle;
- X str buf;
- X{
- X long prevseek;
- X long l;
- X inx i;
- X char c;
- X
- X /* see TFSUnix.c for character-by-character version */
- X
- X assert(TFShbi);
- X assert(buf != NULL);
- X#if CHKARGS
- X /*
- X printf("handle=%d\n", handle);
- X printf("buf=%x\n", buf);
- X printf("HND=%d\n", HND);
- X printf("&ftab[HND]=%x\n", &ftab[HND]);
- X printf("&ftab[HND].modes=%x\n", &ftab[HND].modes);
- X printf("ftab[HND].modes=\"%s\"\n", ftab[HND].modes);
- X */
- X if (HND < 0 || MAXTFS <= HND || ftab[HND].modes == NULL) {
- X PLErrSet(PLerr_badarg);
- X buf[0] = EOS;
- X return S -1;
- X }
- X if (NULL == strchr(ftab[HND].modes, 'R')) {
- X PLErrSet(PLerr_badarg);
- X buf[0] = EOS;
- X return S -1;
- X }
- X#endif
- X
- X do {
- X prevseek = Seek(ftab[HND].fhand, 0, OFFSET_CURRENT);
- X } while (prevseek < 0 && fault("Could not seek text file!"));
- X if (prevseek < 0)
- X PLExit(PLsev_fault);
- X l = Read(ftab[HND].fhand, buf, BIGLINE);
- X if (l == -1) {
- X PLErrSet(PLerr_opsysF);
- X OSerr = IoErr();
- X buf[0] = EOS;
- X return S -1;
- X }
- X else if (l == 0) {
- X PLErrSet(PLerr_eod);
- X buf[0] = EOS;
- X return S -1;
- X }
- X else {
- X i = l;
- X while (i < BIGLINE)
- X buf[i++] = '\n';
- X for (i = 0; buf[i] != '\n' && i < BIGLINE; i++)
- X ;
- X if (buf[i] == '\n') {
- X buf[i] = EOS;
- X Seek(ftab[HND].fhand, prevseek + i + 1, OFFSET_BEGINNING);
- X while (0 < i && isspace(buf[i-1]))
- X buf[--i] = EOS;
- X assert(strlen(buf) < BIGLINE);
- X return (short) i;
- X }
- X else {
- X i = BIGLINE;
- X buf[BIGLINE-1] = EOS;
- X while (0 < i && isspace(buf[i-1]))
- X buf[--i] = EOS;
- X do {
- X l = Read(ftab[HND].fhand, &c, 1);
- X } while (l == 1 && c != '\n');
- X PLErrClr();
- X PLErrSet(PLerr_overflow);
- X assert(strlen(buf) < BIGLINE);
- X return (short) -1;
- X }
- X }
- X }
- X
- X
- Xbool TFSWrite(handle, buf)
- X TFSfile handle;
- X str buf;
- X{
- X int i; /* must be able to handle negative numbers */
- X
- X assert(buf != NULL);
- X#if CHKARGS
- X if (HND < 0 || MAXTFS <= HND || ftab[HND].modes == NULL) {
- X PLErrSet(PLerr_badarg);
- X return FALSE;
- X }
- X if (NULL == strchr(ftab[HND].modes, 'W')) {
- X PLErrSet(PLerr_badarg);
- X return FALSE;
- X }
- X#endif
- X
- X i = strlen(buf);
- X while (0 < i && isspace(buf[i - 1]))
- X i -= 1;
- X if ( ( (0 < i) && (i != Write(ftab[HND].fhand, buf, i)) ) ||
- X 1 != Write(ftab[HND].fhand, "\n", 1)) {
- X OSerr = IoErr();
- X PLErrSet(PLerr_opsysF);
- X return FALSE;
- X }
- X PLErrClr();
- X return TRUE;
- X }
- X
- Xlong TFSNote(handle)
- X TFSfile handle;
- X{
- X long retval;
- X#if CHKARGS
- X if (HND < 0 || MAXTFS <= HND || ftab[HND].modes == NULL) {
- X PLErrSet(PLerr_badarg);
- X return -1L;
- X }
- X if (NULL == strchr(ftab[HND].modes, 'P') ||
- X NULL == strchr(ftab[HND].modes, 'R')) {
- X PLErrSet(PLerr_badarg);
- X return -1L;
- X }
- X#endif
- X
- X retval = Seek(ftab[HND].fhand, 0, OFFSET_CURRENT );
- X if (retval == -1) {
- X OSerr = IoErr();
- X PLErrSet(PLerr_opsysF);
- X OSerr = IoErr();
- X return 0L;
- X }
- X else {
- X PLErrClr();
- X return retval + 1L;
- X }
- X }
- X
- Xbool TFSPoint(handle, pos)
- X TFSfile handle;
- X TFSnote pos;
- X{
- X long newpos;
- X#if CHKARGS
- X if (HND < 0 || MAXTFS <= HND || ftab[HND].modes == NULL) {
- X PLErrSet(PLerr_badarg);
- X return -1L;
- X }
- X if (pos <= 0L || NULL == strchr(ftab[HND].modes, 'P') ||
- X NULL == strchr(ftab[HND].modes, 'R')) {
- X PLErrSet(PLerr_badarg);
- X return -1L;
- X }
- X#endif
- X
- X newpos = Seek(ftab[HND].fhand, pos - 1L, OFFSET_BEGINNING );
- X if (newpos == -1L) {
- X OSerr = IoErr();
- X PLErrSet(PLerr_opsysF);
- X OSerr = IoErr();
- X return FALSE;
- X }
- X else {
- X PLErrClr();
- X return TRUE;
- X }
- X }
- X
- X
- X
- END_OF_FILE
- if test 9122 -ne `wc -c <'TFS/TFSAmiga.c'`; then
- echo shar: \"'TFS/TFSAmiga.c'\" unpacked with wrong size!
- fi
- # end of 'TFS/TFSAmiga.c'
- fi
- echo shar: End of archive 5 \(of 9\).
- cp /dev/null ark5isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 9 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- --- Darren New --- Grad Student --- CIS --- Univ. of Delaware ---
-
- exit 0 # Just in case...
- --
- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
- Use a domain-based address or give alternate paths, or you may lose out.
-