summaryrefslogtreecommitdiff
path: root/dviware/umddvi/h/binding.h
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /dviware/umddvi/h/binding.h
Initial commit
Diffstat (limited to 'dviware/umddvi/h/binding.h')
-rw-r--r--dviware/umddvi/h/binding.h194
1 files changed, 194 insertions, 0 deletions
diff --git a/dviware/umddvi/h/binding.h b/dviware/umddvi/h/binding.h
new file mode 100644
index 0000000000..330ff2c170
--- /dev/null
+++ b/dviware/umddvi/h/binding.h
@@ -0,0 +1,194 @@
+/* C-TeX function and variable bindings */
+
+/*
+ * Copyright (c) 1987 University of Maryland Department of Computer Science.
+ * All rights reserved. Permission to copy for any purpose is hereby granted
+ * so long as this copyright notice remains intact.
+ */
+
+#ifdef StringSizeof
+/*
+ * If StringSizeof is defined, we assume that (sizeof "string_const") is
+ * equal to (strlen("string_const") + 1); see the DefXXX macros below.
+ */
+#endif
+
+/*
+ * Here are the various flags that can be in the b_flags field of a struct
+ * BoundName.
+ */
+#define BIsSpecial 1 /* a special int or dimen, or a font;
+ assignments to these are always
+ global */
+#define BIsOuter 2 /* \outer, may not appear in macro def'n */
+#define BIsLong 4 /* \long, may contain \outer s anyway */
+#define BIsUndef 8 /* not defined anymore - used when a def'n
+ local to a group is destroyed by exiting
+ the group */
+
+/*
+ * SPECIAL
+ * 1. Integers:
+ * \spacefactor \prevgraf \deadcycles \insertpenalties
+ * 2. Dimens:
+ * \prevdepth \pagegoal \pagetotal \pagestretch \pagefilstretch
+ * \pagefillstretch \pagefilllstretch \pageshrink \pagedepth
+ */
+
+enum BindingKind {
+ ProcBound, VarBound, IntBound, DimenBound, CodeBound,
+ FontBound
+};
+
+union BindUnion {
+ int (*b_proc)(); /* iff ProcBound */
+ struct node *b_var; /* iff VarBound */
+ i32 *b_int; /* iff IntBound */
+ scaled *b_dimen; /* iff DimenBound */
+ i32 b_code; /* iff CodeBound */
+ struct FontInfo *b_font; /* iff FontBound */
+};
+
+/*
+ * The basic entity of C-TeX is the `BoundName'. It is either a wired-in
+ * procedure (e.g. \let, \def, \vskip) or variable (\hsize, \parskip), or a
+ * user-defined macro/variable/whatnot. These are indistinguishable from
+ * one another (except that only wired procedures are ProcBound).
+ *
+ * There are also `CodeBound' things, which have no b_name and no b_flags.
+ * In fact, they are really BoundNameCodes, but they need similar treatment,
+ * so they get a similar structure.
+ */
+struct BoundName {
+ enum BindingKind b_binding; /* the kind of thing it is */
+ union BindUnion b_bound; /* the current binding */
+ struct SavedVal *b_AfterGroupRst;
+ /* The saved value for restoration
+ after the current group. This
+ is a pointer into the current
+ AfterGroupRst list. */
+ struct string b_name; /* the name of this thing */
+ int b_flags; /* various flags */
+};
+
+/*
+ * \catcodes, \lccodes, etc are CodeBound, and are really arrays of these:
+ */
+struct BoundNameCode {
+ enum BindingKind b_binding;
+ union BindUnion b_bound;
+ struct SavedVal *b_AfterGroupRst;
+};
+
+/*
+ * Saved values (changes that are local to a group) are stored in a doubly
+ * linked list; this is so that constructs like
+ * {\advance\count0 by1 \global\advance\count0 by1}
+ * can easily delete restorations that are no longer needed (having been
+ * overridden by a \global operation). In other words, we never have
+ * any `save stack buildup'. This requires the `spaghetti' below: a
+ * current group level (so if b_AfterGroupRst is set, we can tell whether
+ * the saved val is for this level) and moreover any inner saves for this
+ * BoundName.
+ *
+ * To illustrate what is going on, suppose that we have count1==0. Now we
+ * begin group number 1, then 2. Now we set count1 to 5, and since it has
+ * no AfterGroupRst we save the 0 at level 2. Now we increment count1, and
+ * since it has an AfterGroupRst, we check the level. It is 2; everything
+ * is fine, and count1 is set to 6. Now we begin group 3, and again increment
+ * count1. The level is 2, so we make a new SavedVal and set its level to
+ * 3. (We now have count1==7, save==6 when exiting level 3, save==0 when
+ * exiting 2.) Now the user does a \global\count1=42, so alas!, all those
+ * saved values are useless. To get rid of them, we delete the current
+ * SavedVal, and its inner, and its inner's inner, and so forth, then clear
+ * the AfterGroupRst pointer. Voila! A global \count1, set to 42.
+ *
+ * Note that we save CodeBound changes here too. Since CodeBound objects
+ * have no flags, some care is needed during restoration.
+ */
+struct SavedVal {
+ int sv_level; /* the level to which this belongs */
+ struct SavedVal *sv_next; /* linked list */
+ struct SavedVal *sv_prev; /* or more precisely, queue */
+ struct SavedVal *sv_inner; /* the inner saved value (from the
+ previous group that saved this) */
+ union BindUnion sv_val; /* the saved value (note that saved
+ values are always the same type
+ as current values---i.e., types
+ are fixed) */
+ struct BoundName *sv_b; /* the BoundName to which it belongs */
+ int sv_flags; /* the saved b_flags (if applicable) */
+};
+
+struct BoundName **NewNames; /* during initialization, each internal
+ BoundName is stashed in the table to
+ which this points */
+
+int CurrentGroup; /* the group level number of the current
+ group; incremented for { and decremented
+ for }, etc */
+
+struct SavedVal *AfterGroupRst;/* the current list for restoring locally
+ modified BoundNames */
+
+/*
+ * The following hackery will make the compiler complain in the event
+ * of a dropped semicolon, without making lint complain.
+ */
+#ifdef lint
+#define do_nothing (void) rand()
+#else
+#define do_nothing 0
+#endif
+
+/*
+ * Save a binding.
+ */
+#define SaveB(b) \
+ if ((b)->b_AfterGroupRst == NULL || \
+ (b)->b_AfterGroupRst->sv_level != CurrentGroup) \
+ DoSave(b); \
+ else \
+ do_nothing
+
+/*
+ * Undo a save.
+ */
+#define UnSaveB(b) \
+ if ((b)->b_AfterGroupRst) \
+ DoUnsave(b); \
+ else \
+ do_nothing
+
+#ifdef StringSizeof
+#define InitStrAndLen(str,cstr) (str.s_len = sizeof cstr-1, str.s_str = cstr)
+#else
+#define InitStrAndLen(str,cstr) (str.s_len = strlen(str.s_str = cstr))
+#endif
+
+#define SetBFlags(f) NewNames[-1].b_flags |= (f)
+
+#define DefIntVar(addr, name) { \
+ static struct BoundName _b; \
+ InitStrAndLen(_b.b_name, name); \
+ _b.b_binding = IntBound; \
+ _b.b_bound.b_int = addr; \
+ *NewNames++ = &_b; \
+}
+
+#define DefDimenVar(addr, name) { \
+ static struct BoundName _b; \
+ InitStrAndLen(_b.b_name, name); \
+ _b.b_binding = DimenBound; \
+ _b.b_bound.b_dimen = addr; \
+ *NewNames++ = &_b; \
+}
+
+#define DefProc(name, proc, flags) { \
+ static struct BoundName _b; \
+ InitStrAndLen(_b.b_name, name); \
+ _b.b_binding = ProcBound; \
+ _b.b_bound.b_proc = proc; \
+ _b.b_bound.b_flags = flags; \
+ *NewNames++ = &_b; \
+}