aboutsummaryrefslogtreecommitdiffstats
path: root/z30.c
diff options
context:
space:
mode:
Diffstat (limited to 'z30.c')
-rw-r--r--z30.c192
1 files changed, 192 insertions, 0 deletions
diff --git a/z30.c b/z30.c
new file mode 100644
index 0000000..65b7992
--- /dev/null
+++ b/z30.c
@@ -0,0 +1,192 @@
+/*@z30.c:Symbol uses:InsertUses()@********************************************/
+/* */
+/* THE LOUT DOCUMENT FORMATTING SYSTEM (VERSION 3.17) */
+/* COPYRIGHT (C) 1991, 1999 Jeffrey H. Kingston */
+/* */
+/* Jeffrey H. Kingston (jeff@cs.usyd.edu.au) */
+/* Basser Department of Computer Science */
+/* The University of Sydney 2006 */
+/* AUSTRALIA */
+/* */
+/* This program is free software; you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation; either Version 2, or (at your option) */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA */
+/* */
+/* FILE: z30.c */
+/* MODULE: Symbol Uses */
+/* EXTERNS: InsertUses(), FlattenUses(), SearchUses(), */
+/* FirstExternTarget(), NextExternTarget() */
+/* */
+/*****************************************************************************/
+#include "externs.h"
+
+
+/*****************************************************************************/
+/* */
+/* InsertUses(x, y) */
+/* */
+/* Record the fact that symbol x uses symbol y, by linking them. */
+/* Increment count of the number of times y is used, if y is a parameter. */
+/* */
+/*****************************************************************************/
+
+void InsertUses(OBJECT x, OBJECT y)
+{ OBJECT tmp;
+ debug2(DSU, D, "InsertUses( %s, %s )", SymName(x), SymName(y));
+ if( type(x) == LOCAL && type(y) == LOCAL && !predefined(y) )
+ { GetMem(tmp, USES_SIZE, no_fpos); item(tmp) = y;
+ if( base_uses(x) == nilobj ) next(tmp) = tmp;
+ else next(tmp) = next(base_uses(x)), next(base_uses(x)) = tmp;
+ base_uses(x) = tmp;
+ }
+ if( is_par(type(y)) )
+ {
+ uses_count(y) += (enclosing(y) == x ? 1 : 2);
+ if( dirty(y) || uses_count(y) > 1 ) dirty(enclosing(y)) = TRUE;
+ }
+ else if( sym_body(y) == nilobj || dirty(y) ) dirty(x) = TRUE;
+ debug5(DSU, D, "InsertUses returning ( %s %s; %s %s, count = %d )",
+ SymName(x), (dirty(x) ? "dirty" : "clean"),
+ SymName(y), (dirty(y) ? "dirty" : "clean"), uses_count(y));
+} /* end InsertUses */
+
+
+/*@::GatherUses(), GatherAllUses(), FlattenUses()@****************************/
+/* */
+/* static GatherUses(x, sym) */
+/* static GatherAllUses(x) */
+/* */
+/* GatherUses adds all the unmarked descendants of x to the uses relation */
+/* of sym; GatherAllUses applies gather_uses to all descendants of x. */
+/* */
+/*****************************************************************************/
+
+static void GatherUses(OBJECT x, OBJECT sym)
+{ OBJECT link, y, tmp;
+ if( base_uses(x) != nilobj )
+ { link = next(base_uses(x));
+ do
+ { y = item(link);
+ if( marker(y) != sym )
+ { if( y != sym )
+ { marker(y) = sym;
+ GetMem(tmp, USES_SIZE, no_fpos); item(tmp) = y;
+ if( uses(sym) == nilobj ) next(tmp) = tmp;
+ else next(tmp) = next(uses(sym)), next(uses(sym)) = tmp;
+ uses(sym) = tmp;
+ if( indefinite(y) ) indefinite(sym) = TRUE;
+ if( uses_extern_target(y) ) uses_extern_target(sym) = TRUE;
+ GatherUses(y, sym);
+ }
+ else recursive(sym) = TRUE;
+ }
+ link = next(link);
+ } while( link != next(base_uses(x)) );
+ }
+} /* end GatherUses */
+
+
+static void GatherAllUses(OBJECT x)
+{ OBJECT link, y;
+ for( link = Down(x); link != x; link = NextDown(link) )
+ { Child(y, link);
+ if( type(y) == LOCAL ) GatherUses(y, y);
+ GatherAllUses(y);
+ }
+} /* end GatherAllUses */
+
+
+/*****************************************************************************/
+/* */
+/* FlattenUses() */
+/* */
+/* Traverse the directed graph assembled by InsertUses, finding its */
+/* transitive closure and storing this explicitly in uses(x) for all x. */
+/* */
+/*****************************************************************************/
+
+void FlattenUses(void)
+{ GatherAllUses(StartSym);
+} /* end FlattenUses */
+
+
+/*@::SearchUses(), FirstExternTarget(), NextExternTarget()@*******************/
+/* */
+/* BOOLEAN SearchUses(x, y) */
+/* */
+/* Discover whether symbol x uses symbol y by searching the uses list of x. */
+/* */
+/*****************************************************************************/
+
+BOOLEAN SearchUses(OBJECT x, OBJECT y)
+{ OBJECT p;
+ debug3(DSU, DD, "SearchUses(%s, %s) uses: %d", SymName(x),SymName(y),uses(x));
+ if( x == y ) return TRUE;
+ if( uses(x) != nilobj )
+ { p = next(uses(x));
+ do
+ { debug1(DSU, DDD, " checking %s", SymName(item(p)));
+ if( item(p) == y ) return TRUE;
+ p = next(p);
+ } while( p != next(uses(x)) );
+ }
+ return FALSE;
+} /* end SearchUses */
+
+
+/*****************************************************************************/
+/* */
+/* OBJECT FirstExternTarget(sym, cont) */
+/* OBJECT NextExternTarget(sym, cont) */
+/* */
+/* Together these two procedures return all symbols which are both used by */
+/* sym and a target for at least one external galley. Return nilobj at end.*/
+/* */
+/*****************************************************************************/
+
+OBJECT FirstExternTarget(OBJECT sym, OBJECT *cont)
+{ OBJECT res;
+ debug1(DSU, D, "FirstExternTarget( %s )", SymName(sym));
+ res = nilobj; *cont = nilobj;
+ if( is_extern_target(sym) ) res = sym;
+ else if( uses(sym) != nilobj )
+ { *cont = next(uses(sym));
+ do
+ { if( is_extern_target(item(*cont)) )
+ { res = item(*cont);
+ break;
+ }
+ *cont = next(*cont);
+ } while( *cont != next(uses(sym)) );
+ }
+ debug1(DSU, D, "FirstExternTarget returning %s", SymName(res));
+ return res;
+} /* end FirstExternTarget */
+
+OBJECT NextExternTarget(OBJECT sym, OBJECT *cont)
+{ OBJECT res;
+ debug1(DSU, D, "NextExternTarget( %s )", SymName(sym));
+ res = nilobj;
+ if( *cont != nilobj )
+ { *cont = next(*cont);
+ while( *cont != next(uses(sym)) )
+ { if( is_extern_target(item(*cont)) )
+ { res = item(*cont);
+ break;
+ }
+ *cont = next(*cont);
+ }
+ }
+ debug1(DSU, D, "NextExternTarget returning %s", SymName(res));
+ return res;
+} /* end NextExternTarget */