EMHOME = ../../..
INSTALL = $(EMHOME)/modules/install
COMPARE = $(EMHOME)/modules/compare
-INCORE = -DINCORE
CFLAGS = -I$(EMHOME)/h -I$(EMHOME)/modules/h -O
-OBS = failed.o insert.o internerr.o io.o getid.o
+SRC = failed.c insert.c internerr.c getid.c
+OBS = failed.o insert.o internerr.o getid.o
all: libeme.a libemk.a em_code.3
rm -f C_*.c
-sh -c 'tbl < em_code.3X > em_code.3'
-sh -c 'if test -s em_code.3 ; then : ; else cp em_code.3X em_code.3 ; fi '
-libeme.a: make.sh e/em_private.h e/em.c $(OBS)
+libeme.a: make.sh e/em_private.h e/em.c $(OBS) io.c
EMHOME=$(EMHOME); export EMHOME; sh make.sh e
-sh -c 'ranlib libeme.a'
-libemk.a: make.sh k/em_private.h k/em.c $(OBS)
+libemk.a: make.sh k/em_private.h k/em.c $(OBS) io.c
EMHOME=$(EMHOME); export EMHOME; sh make.sh k
-sh -c 'ranlib libemk.a'
make.em.gen $(EMHOME)/etc/em_table > em.gen
pr:
- @pr Makefile make.em.gen make.fun em.nogen e/em_private.h e/em.c k/em_private.h k/em.c
+ @pr Makefile make.em.gen make.fun em.nogen insert.h $(SRC) e/em_private.h e/em.c k/em_private.h k/em.c
opr:
make pr | opr
rm -f *.a em_code.3 em.gen make.sh
lintlib: make.sh
- lint -I../../h -I../../../h -Ie -Ceme *.c e/*.c
- lint -I../../h -I../../../h -Ik -Cemk *.c k/*.c
+ lint -I. -I../../h -I../../../h -Ie -Ceme $(SRC) e/*.c
+ lint -I. -I../../h -I../../../h -Ik -Cemk $(SRC) k/*.c
mv llib-leme.ln llib-lemk.ln $(EMHOME)/modules/lib
insert.o: insert.c insert.h
- $(CC) $(CFLAGS) -c $(INCORE) insert.c
-
-io.o: io.c insert.h
- $(CC) $(CFLAGS) -c $(INCORE) io.c
+ $(CC) $(CFLAGS) -c insert.c
*/
/* EM CODE OUTPUT ROUTINES */
-#include <system.h>
+#include "io.c"
#include "em_private.h"
/*
wrs(s)
register char *s;
{
- while (*s) C_putbyte(*s++);
+ while (*s) {
+ C_putbyte(*s++);
+ }
}
C_pt_dnam(s)
C_putbyte('\'');
p = bts2str(x, (int) y, xbuf);
while (*p) {
- if (*p == '\'')
+ if (*p == '\'') {
C_putbyte('\\');
+ }
C_putbyte(*p++);
}
C_putbyte('\'');
char *v;
arith sz;
{
+ int ch = sp == sp_icon ? 'I' : sp == sp_ucon ? 'U' : 'F';
+
wrs(v);
- C_putbyte(sp == sp_icon ? 'I' : sp == sp_ucon ? 'U' : 'F');
+ C_putbyte(ch);
C_pt_cst(sz);
}
C_pt_nl() { C_putbyte('\n'); }
C_pt_comma() { C_putbyte(','); }
-C_pt_ccend() { wrs(" ?"); }
+C_pt_ccend() { C_putbyte('?'); }
C_inp | char *:s | PS(ps_inp); PNAM(s); NL()
C_bss_cst | arith:n arith:w int:i |
- PS(ps_bss); DCST(n); COMMA(); CST(w); COMMA(); CST((arith) i); NL()
+ PS(ps_bss); CST(n); COMMA(); CST(w); COMMA(); CST((arith) i); NL()
C_bss_icon | arith:n char *:s arith:sz int:i |
- PS(ps_bss); DCST(n); COMMA(); WCON(sp_icon, s, sz); COMMA(); CST((arith) i); NL()
+ PS(ps_bss); CST(n); COMMA(); WCON(sp_icon, s, sz); COMMA(); CST((arith) i); NL()
C_bss_ucon | arith:n char *:s arith:sz int:i |
- PS(ps_bss); DCST(n); COMMA(); WCON(sp_ucon, s, sz); COMMA(); CST((arith) i); NL()
+ PS(ps_bss); CST(n); COMMA(); WCON(sp_ucon, s, sz); COMMA(); CST((arith) i); NL()
C_bss_fcon | arith:n char *:s arith:sz int:i |
- PS(ps_bss); DCST(n); COMMA(); WCON(sp_fcon, s, sz); COMMA(); CST((arith) i); NL()
+ PS(ps_bss); CST(n); COMMA(); WCON(sp_fcon, s, sz); COMMA(); CST((arith) i); NL()
C_bss_dnam | arith:n char *:s arith:offs int:i |
- PS(ps_bss); DCST(n); COMMA(); NOFF(s, offs); COMMA(); CST((arith) i); NL()
+ PS(ps_bss); CST(n); COMMA(); NOFF(s, offs); COMMA(); CST((arith) i); NL()
C_bss_dlb | arith:n label:l arith:offs int:i |
- PS(ps_bss); DCST(n); COMMA(); DOFF(l, offs); COMMA(); CST((arith) i); NL()
+ PS(ps_bss); CST(n); COMMA(); DOFF(l, offs); COMMA(); CST((arith) i); NL()
C_bss_ilb | arith:n label:l int:i |
- PS(ps_bss); DCST(n); COMMA(); ILB(l); COMMA(); CST((arith) i); NL()
+ PS(ps_bss); CST(n); COMMA(); ILB(l); COMMA(); CST((arith) i); NL()
C_bss_pnam | arith:n char *:s int:i |
- PS(ps_bss); DCST(n); COMMA(); PNAM(s); COMMA(); CST((arith) i); NL()
+ PS(ps_bss); CST(n); COMMA(); PNAM(s); COMMA(); CST((arith) i); NL()
C_hol_cst | arith:n arith:w int:i |
- PS(ps_hol); DCST(n); COMMA(); CST(w); COMMA(); CST((arith) i); NL()
+ PS(ps_hol); CST(n); COMMA(); CST(w); COMMA(); CST((arith) i); NL()
C_hol_icon | arith:n char *:s arith:sz int:i |
- PS(ps_hol); DCST(n); COMMA(); WCON(sp_icon, s, sz); COMMA(); CST((arith) i); NL()
+ PS(ps_hol); CST(n); COMMA(); WCON(sp_icon, s, sz); COMMA(); CST((arith) i); NL()
C_hol_ucon | arith:n char *:s arith:sz int:i |
- PS(ps_hol); DCST(n); COMMA(); WCON(sp_ucon, s, sz); COMMA(); CST((arith) i); NL()
+ PS(ps_hol); CST(n); COMMA(); WCON(sp_ucon, s, sz); COMMA(); CST((arith) i); NL()
C_hol_fcon | arith:n char *:s arith:sz int:i |
- PS(ps_hol); DCST(n); COMMA(); WCON(sp_fcon, s, sz); COMMA(); CST((arith) i); NL()
+ PS(ps_hol); CST(n); COMMA(); WCON(sp_fcon, s, sz); COMMA(); CST((arith) i); NL()
C_hol_dnam | arith:n char *:s arith:offs int:i |
- PS(ps_hol); DCST(n); COMMA(); NOFF(s, offs); COMMA(); CST((arith) i); NL()
+ PS(ps_hol); CST(n); COMMA(); NOFF(s, offs); COMMA(); CST((arith) i); NL()
C_hol_dlb | arith:n label:l arith:offs int:i |
- PS(ps_hol); DCST(n); COMMA(); DOFF(l, offs); COMMA(); CST((arith) i); NL()
+ PS(ps_hol); CST(n); COMMA(); DOFF(l, offs); COMMA(); CST((arith) i); NL()
C_hol_ilb | arith:n label:l int:i |
- PS(ps_hol); DCST(n); COMMA(); ILB(l); COMMA(); CST((arith) i); NL()
+ PS(ps_hol); CST(n); COMMA(); ILB(l); COMMA(); CST((arith) i); NL()
C_hol_pnam | arith:n char *:s int:i |
- PS(ps_hol); DCST(n); COMMA(); PNAM(s); COMMA(); CST((arith) i); NL()
+ PS(ps_hol); CST(n); COMMA(); PNAM(s); COMMA(); CST((arith) i); NL()
C_con_cst | arith:l | PS(ps_con); CST(l); CEND(); NL()
C_con_icon | char *:val arith:siz |
.B int id;
.PP
.B int C_getid()
+.PP
+.B char *C_tmpdir;
.fi
.SH DESCRIPTION
This package provides a procedural EM code interface to be used in
However, when
.I C_close
is called, all parts that have been inserted, must also be defined.
+Parts may themselves again have sub-parts.
.PP
The routine
.I C_getid
can be used to obtain a valid and unique part
.IR id .
+.PP
+On implementations with limited memory, the mechanism is implemented with a
+temporary file.
+The directory in which this file resides is indicated by
+.IR C_tmpdir .
+The default is the #define TMP_DIR from ~em/h/em_path.h.
+The user can change this by just changing
+.I C_tmpdir
+before calling
+.IR C_open.
.SH FILES
.nf
~em/modules/h/em.h
#include <alloc.h>
#include "insert.h"
+#ifndef INCORE
+static int
+getbyte(b)
+ long b;
+{
+ /* Get the byte at offset "b" from the start of the
+ temporary file, and try to do so in an efficient way.
+ */
+ static long start_core, curr_pos;
+
+ if (b < start_core || b >= curr_pos) {
+ /* the block wanted is not in core, so get it */
+ long nb = (b & ~(BUFSIZ - 1));
+ int n;
+
+ C_flush();
+ if (nb != curr_pos) {
+ if (sys_seek(tfr, nb, 0, &curr_pos) == 0) {
+ C_failed();
+ }
+ }
+ if (! ibuf) {
+ ibuf = Malloc(BUFSIZ);
+ }
+ if (sys_read(tfr, ibuf, BUFSIZ, &n) == 0) {
+ C_failed();
+ }
+ curr_pos += n;
+ start_core = nb;
+ }
+
+ return ibuf[(int) (b - start_core)];
+}
+#endif
+
+static C_out_parts();
+static Part *C_findpart();
+
+outpart(id)
+ int id;
+{
+ /* Output part "id", if present.
+ */
+ Part *p = C_findpart(id);
+
+ if (p) C_out_parts(p->p_parts);
+}
+
+static
+C_out_parts(pp)
+ register PartOfPart *pp;
+{
+ /* Output the list of chunks started by "pp".
+ The list is build in reverse order, so this routine is
+ recursive.
+ */
+ PartOfPart *prev = 0, *next;
+
+ while (pp) {
+ next = pp->pp_next;
+ pp->pp_next = prev;
+ prev = pp;
+ pp = next;
+ }
+ pp = prev;
+
+ while (pp) {
+ if (pp->pp_type == INSERT) {
+ C_outpart(pp->pp_id);
+ }
+ else {
+ /* copy the chunk to output */
#ifdef INCORE
-#define C_switchtotmp() (C_ontmpfile = 1)
-#define C_switchtoout() (C_ontmpfile = 0)
+ register char *s = C_BASE + pp->pp_begin;
+ char *se = C_BASE + pp->pp_end;
+
+ while (s < se) {
+ put(*s++);
+ }
+#else
+ register long b = pp->pp_begin;
+
+ while (b < pp->pp_end) {
+ put(getbyte(b++));
+ }
+#endif
+ }
+ pp = pp->pp_next;
+ }
+}
+
+static Part *
+C_findpart(part)
+ int part;
+{
+ /* Look for part "part" in the table.
+ Return 0 if not present,
+ */
+ register Part *p = C_stable[part % TABSIZ];
+
+ while (p && p->p_id != part) {
+ p = p->p_next;
+ }
+ return p;
+}
+
+static
+switchtotmp()
+{
+#ifndef INCORE
+ if (C_tmpfile == 0) {
+ static char tmpbuf[64];
+ register char *p = tmpbuf;
+
+ strcpy(p, C_tmpdir);
+ strcat(p, "/CodeXXXXXX");
+ tmpfile = mktemp(p);
+ if (! sys_open(p, OP_WRITE, &C_old_ofp)) {
+ C_failed();
+ }
+ if (! sys_open(p, OP_READ, &C_tfr)) {
+ C_failed();
+ }
+ }
+ if (! C_ontmpfile) {
+ File *p = C_ofp;
+
+ C_flush();
+ C_ofp = C_old_ofp;
+ C_old_ofp = p;
+ C_ontmpfile = 1;
+ }
+#else
+ if (! C_ontmpfile) {
+ char *p;
+
+ p = C_opp;
+ C_opp = C_old_opp;
+ C_old_opp = p;
+
+ p = C_top;
+ C_top = C_old_top;
+ C_old_top = p;
+ C_ontmpfile = 1;
+ }
#endif
+}
+
+static
+switchtoout()
+{
+#ifndef INCORE
+ if (C_ontmpfile) {
+ File *p = C_ofp;
+
+ C_flush();
+ C_ofp = C_old_ofp;
+ C_old_ofp = p;
+ C_ontmpfile = 0;
+ }
+#else
+ if (C_ontmpfile) {
+ char *p;
+
+ p = C_opp;
+ C_opp = C_old_opp;
+ C_old_opp = p;
+
+ p = C_top;
+ C_top = C_old_top;
+ C_old_top = p;
+ C_ontmpfile = 0;
+ }
+#endif
+}
static int
available(part)
if (p) {
register PartOfPart *pp = p->p_parts;
- pp->pp_end = C_current_out;
+ pp->pp_end = C_current_out - C_BASE;
if (pp->pp_begin == pp->pp_end) {
/* nothing in this chunk, so give it back */
p->p_parts = pp->pp_next;
*/
register PartOfPart *pp = (PartOfPart *) Malloc(sizeof(PartOfPart));
- C_switchtotmp();
+ switchtotmp();
C_curr_part = p;
pp->pp_next = p->p_parts;
p->p_parts = pp;
pp->pp_type = TEXT;
- pp->pp_begin = C_current_out;
+ pp->pp_begin = C_current_out - C_BASE;
}
C_insertpart(part)
register Part *p;
register PartOfPart *pp;
+ C_outpart = outpart;
+ C_switchtotmp = switchtotmp;
+ C_switchtoout = switchtoout;
if (C_sequential && available(part)) {
outpart(part);
return;
*/
register Part *p = mkpart(part);
+ C_outpart = outpart;
+ C_switchtotmp = switchtotmp;
+ C_switchtoout = switchtoout;
+
end_partofpart(C_curr_part);
p->p_prevpart = C_curr_part;
if (p->p_prevpart) resume(p->p_prevpart);
else {
C_curr_part = 0;
- C_switchtoout();
+ switchtoout();
}
}
end-pointer.
*/
+#include <system.h>
+
+#define INCORE /* mechanism implemented incore */
+
typedef struct partofpart {
struct partofpart *pp_next;
char pp_type;
int p_id; /* id of this part */
} Part;
-#define outpart(xxx) C_out_parts(C_findpart(xxx)->p_parts)
-
#define TABSIZ 32
extern int
C_ontmpfile, C_sequential;
extern Part
*C_curr_part, *C_stable[];
+#ifdef INCORE
+extern char
+ *C_current_out, *C_BASE;
+#define C_opp C_current_out
+#else
extern long
C_current_out;
-extern Part
- *C_findpart();
+extern char *C_opp;
+#define C_BASE 0
+#endif
+extern int (*C_outpart)(), (*C_switchtoout)(), (*C_switchtotmp)();
+
+extern File *C_ofp;
+
+#ifndef INCORE
+extern File *C_tfr, *C_old_ofp;
+extern char *C_tmpfile;
+#endif
+
+extern char *C_top;
+extern char *C_old_top;
+extern char *C_old_opp;
+
+#define put(c) if (C_opp == C_top) C_flush(); *C_opp++ = (c)
+
/* I/O part of em_code module.
Also contains C_open, C_close
*/
-#include <system.h>
#include <alloc.h>
#include <em_path.h>
#include <em_arith.h>
+#include <local.h>
#include "insert.h"
-int
- C_ontmpfile = 0,
- C_sequential = 1;
-Part
- *C_curr_part, *C_stable[TABSIZ];
-long
- C_current_out;
+int C_ontmpfile = 0;
+int C_sequential = 1;
+Part *C_curr_part;
+Part *C_stable[TABSIZ];
+char *C_tmpdir = TMP_DIR;
+int (*C_outpart)(), (*C_switchtoout)(), (*C_switchtotmp)();
#ifdef INCORE
-static char *BASE;
+char *C_BASE;
#endif
-static File *ofp;
+
+File *C_ofp;
#ifndef INCORE
-static File *tfr, *old_ofp;
-static char *tmpfile;
+File *C_tfr, *C_old_ofp;
+char *C_tmpfile;
char *strcpy(), *strcat(), *mktemp();
static char *ibuf = 0;
+long C_current_out;
#endif
-static char obuf[BUFSIZ];
-static char *opp = obuf;
-
-static
-flush() {
- if (opp != obuf && sys_write(ofp, obuf, opp - obuf) == 0) {
- C_failed();
- }
- opp = obuf;
-}
+#if BUFSIZ <= 1024 && BIGMACHINE
+#define BUFFERSIZ 8*BUFSIZ
+#else
+#define BUFFERSIZ BUFSIZ
+#endif
-#define put(c) if (opp == &obuf[BUFSIZ]) flush(); *opp++ = (c)
+static char obuf[BUFFERSIZ];
+char *C_top = &obuf[BUFFERSIZ];
+char *C_old_top;
+char *C_old_opp;
+#ifdef INCORE
+char *C_current_out = obuf;
+#endif
-C_putbyte(c)
- int c;
-{
- if (C_ontmpfile) {
+C_flush() {
#ifdef INCORE
- static unsigned sz;
+ static unsigned int bufsiz;
- if (BASE == 0) {
- BASE = Malloc(BUFSIZ);
- sz = BUFSIZ;
+ if (C_ontmpfile) {
+ if (C_BASE == 0) {
+ C_BASE = Malloc(BUFFERSIZ);
+ bufsiz = BUFFERSIZ;
+ C_current_out = C_BASE;
}
- else if (C_current_out >= sz) {
- BASE = Srealloc(BASE, (sz <<= 1));
+ else {
+ C_BASE = Srealloc(C_BASE, (bufsiz << 1));
+ C_current_out = C_BASE + bufsiz;
+ bufsiz <<= 1;
}
- *(BASE + C_current_out) = c;
-#endif
- C_current_out++;
-#ifdef INCORE
+ C_top = C_BASE + bufsiz;
return;
+ }
#endif
+ if (C_opp != obuf && sys_write(C_ofp, obuf, C_opp - obuf) == 0) {
+ C_failed();
}
- put(c);
+ C_opp = obuf;
}
#ifndef INCORE
-C_switchtotmp()
-{
- if (tmpfile == 0) {
- static char tmpbuf[64];
- register char *p = tmpbuf;
-
- strcpy(p, TMP_DIR);
- strcat(p, "/CodeXXXXXX");
- tmpfile = mktemp(p);
- if (! sys_open(p, OP_WRITE, &old_ofp)) {
- C_failed();
- }
- if (! sys_open(p, OP_READ, &tfr)) {
- C_failed();
- }
- }
- if (! C_ontmpfile) {
- File *p = ofp;
-
- flush();
- ofp = old_ofp;
- old_ofp = p;
- C_ontmpfile = 1;
- }
-}
+#define Xputbyte(c) if (C_ontmpfile) C_current_out++; put(c)
+#else
+#define Xputbyte(c) put(c)
+#endif
-C_switchtoout()
+C_putbyte(c)
+ int c;
{
- if (C_ontmpfile) {
- File *p = ofp;
-
- flush();
- ofp = old_ofp;
- old_ofp = p;
- C_ontmpfile = 0;
- }
+ Xputbyte(c);
}
-#endif
+
+#define C_putbyte Xputbyte
C_init(w, p)
arith w, p;
*/
if (nm == 0)
- ofp = STDOUT; /* standard output */
+ C_ofp = STDOUT; /* standard output */
else
- if (sys_open(nm, OP_WRITE, &ofp) == 0)
+ if (sys_open(nm, OP_WRITE, &C_ofp) == 0)
return 0;
return 1;
}
*/
#ifndef INCORE
- flush();
+ C_flush();
if (tmpfile) {
- C_switchtotmp();
- sys_close(ofp);
- ofp = old_ofp;
+ (*C_switchtotmp)();
+ sys_close(C_ofp);
#else
- if (BASE) {
+ if (C_BASE) {
#endif
if (C_curr_part) {
- C_curr_part->p_parts->pp_end = C_current_out;
+ C_curr_part->p_parts->pp_end = C_current_out - C_BASE;
}
+ (*C_switchtoout)();
if (! C_sequential) {
- outpart(0);
+ (*C_outpart)(0);
}
#ifndef INCORE
- sys_close(tfr);
+ sys_close(C_tfr);
sys_remove(tmpfile);
if (ibuf) free(ibuf);
#else
- free(BASE);
+ free(C_BASE);
#endif
}
- flush();
- if (ofp != STDOUT)
- sys_close(ofp);
- ofp = 0;
+ C_flush();
+ if (C_ofp != STDOUT)
+ sys_close(C_ofp);
+ C_ofp = 0;
}
C_busy()
{
- return ofp != 0; /* true if code is being generated */
+ return C_ofp != 0; /* true if code is being generated */
}
-
-#ifndef INCORE
-static int
-getbyte(b)
- long b;
-{
- /* Get the byte at offset "b" from the start of the
- temporary file, and try to do so in an efficient way.
- */
- static long start_core, curr_pos;
-
- if (b < start_core || b >= curr_pos) {
- /* the block wanted is not in core, so get it */
- long nb = (b & ~(BUFSIZ - 1));
- int n;
-
- flush();
- if (nb != curr_pos) {
- if (sys_seek(tfr, nb, 0, &curr_pos) == 0) {
- C_failed();
- }
- }
- if (! ibuf) {
- ibuf = Malloc(BUFSIZ);
- }
- if (sys_read(tfr, ibuf, BUFSIZ, &n) == 0) {
- C_failed();
- }
- curr_pos += n;
- start_core = nb;
- }
-
- return ibuf[(int) (b - start_core)];
-}
-#endif
-
-C_out_parts(pp)
- register PartOfPart *pp;
-{
- /* Output the list of chunks started by "pp".
- The list is build in reverse order, so this routine is
- recursive.
- */
-
- if (!pp) return;
- if (pp->pp_next) C_out_parts(pp->pp_next);
-
- if (pp->pp_type == INSERT) {
- outpart(pp->pp_id);
- }
- else {
- /* copy the chunk to output */
-#ifdef INCORE
- register char *s = BASE + pp->pp_begin;
- char *se = BASE + pp->pp_end;
-
- while (s < se) {
- put(*s++);
- }
-#else
- register long b = pp->pp_begin;
-
- while (b < pp->pp_end) {
- put(getbyte(b++));
- }
-#endif
- }
-}
-
-Part *
-C_findpart(part)
- int part;
-{
- /* Look for part "part" in the table.
- Return 0 if not present,
- */
- register Part *p = C_stable[part % TABSIZ];
-
- while (p && p->p_id != part) {
- p = p->p_next;
- }
- return p;
-}
-
/* $Header$ */
/* EM CODE OUTPUT ROUTINES */
-#include <system.h>
+#include "io.c"
#include "em_private.h"
#define put8(x) C_putbyte(x)
1,/^$/d
1,/^$/d
1,$s/^\(...\) \(.\).*/\1:\2/
-g/:d/s/^\(...\):\(.\).*/C_\1 | arith:\2 | OP(op_\1); DCST(\2); NL()/
+g/:d/s/^\(...\):\(.\).*/C_\1 | arith:\2 | OP(op_\1); CST(\2); NL()/
g/:[cslnfzor]/s/^\(...\):\(.\).*/C_\1 | arith:\2 | OP(op_\1); CST(\2); NL()/
g/:w/s/^\(...\).*/C_\1 | arith:w | OP(op_\1); CST(w); NL()\
C_\1_narg | | OP(op_\1); CCEND(); NL()/
.
$a
rm -f libem$1.a
-cc -c -O -I$1 -I$EMHOME/modules/h -I$EMHOME/h $1/em.c
+cc -c -O -I. -I$1 -I$EMHOME/modules/h -I$EMHOME/h $1/em.c
mv em.o em$1.o
-ar rc libem$1.a C_*.o em$1.o insert.o io.o failed.o internerr.o getid.o
+ar rc libem$1.a C_*.o em$1.o insert.o failed.o internerr.o getid.o
rm -f C_*.o
--EOF--
.