|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T f
Length: 9944 (0x26d8) Types: TextFile Names: »functions.c«
└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape └─⟦eba4602b1⟧ »./isode-5.0.tar.Z« └─⟦d3ac74d73⟧ └─⟦this⟧ »isode-5.0/others/max/functions.c« └─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« └─⟦de7628f85⟧ └─⟦this⟧ »isode-6.0/others/max/functions.c«
/* functions.c - max -- user-defined functions */ #include <ctype.h> #include <signal.h> #include <stdio.h> #include "max.h" #include "Quarks.h" #include "XrmConvert.h" #define NVEC 100 /* \f */ struct table { int t_min; int t_max; UFproc t_proc; }; #define newtable(name,min,max,proc) \ if ((t = (struct table *) calloc (1, sizeof *t)) == NULL) \ adios (NULLCP, "out of memory"); \ t -> t_min = (min); \ t -> t_max = (max); \ t -> t_proc = (proc); \ if (XtSaveContext (XtNameToWindow (name), UFcontext, (caddr_t) t)) \ adios (NULLCP, "unable to save context"); \ static XtContext UFcontext; static XtQuark XtQfunctions; static XtQuark XtQcommand; void XtScanEntry (); int str2vec (); void UFexec (), UFpick (); int filesort (), run (); /* \f */ void buildUF (rdb, uf) ResourceDataBase rdb; UF uf; { static int inited = 0; if (inited == 0) { register struct table *t; XtQfunctions = XtAtomToQuark ((XtAtom) "functions"); XtQcommand = XtAtomToQuark ((XtAtom) "command"); UFcontext = XtUniqueContext (); newtable ("f.exec", 1, -1, UFexec); newtable ("f.pick", 1, 1, UFpick); inited++; } uf -> uf_forw = uf -> uf_back = uf; XtEnumDataBase ((caddr_t) uf, XtScanEntry, rdb); } /* \f */ /* ARGSUSED */ static void XtScanEntry (quarks, type, val, tag) XtQuarkList quarks; XtRepresentation type; XrmValue val; caddr_t tag; { int vecp; register char *p, **pp, **qp; XtQuark qk; UF uf; struct table *t; static char *vec[NVEC + 1]; if (type != XtQString || *quarks++ != XtQfunctions || (qk = *quarks++) == NULLQUARK || *quarks++ != XtQcommand || *quarks != NULLQUARK) return; if ((p = strdup (val.addr)) == NULLCP) adios (NULLCP, "out of memory"); if ((vecp = str2vec (p, vec)) < 1) { display_message (NULLCP, "malformed definition for function \"%s\"", XtQuarkToAtom (qk)); out: ; free (p); return; } if (XtFindContext (XtNameToWindow (vec[0]), UFcontext, (caddr_t *) &t)) { display_message (NULLCP, "unknown keyword \"%s\" for function \"%s\"", vec[0], XtQuarkToAtom (qk)); goto out; } if (t -> t_min >= 0 && t -> t_min > vecp - 1) { display_message (NULLCP, "too few arguments for \"%s\" in function \"%s\"", vec[0], XtQuarkToAtom (qk)); goto out; } if (t -> t_max >= 0 && t -> t_max < vecp - 1) { display_message (NULLCP, "too many arguments for \"%s\" in function \"%s\"", vec[0], XtQuarkToAtom (qk)); goto out; } if ((uf = (UF) calloc (1, sizeof *uf)) == NULLUF) adios (NULLCP, "out of memory"); insque (uf, ((UF) tag) -> uf_back); uf -> uf_name = strdup (XtQuarkToAtom (qk)); uf -> uf_proc = t -> t_proc; uf -> uf_narg = vecp - 1; if ((uf -> uf_args = (char **) calloc ((unsigned int) (vecp + 1), sizeof *uf -> uf_args)) == NULL) adios (NULLCP, "out of memory"); for (pp = vec + 1, qp = uf -> uf_args; --vecp > 0; pp++, qp++) *qp = *pp; uf -> uf_mode = UFexecUnknown; uf -> uf_command = p; } /* \f */ #define QUOTE '\\' static int str2vec (s, vec) register char *s, **vec; { register int i; for (i = 0; i <= NVEC;) { vec[i] = NULL; while (isspace (*s) || *s == ',') *s++ = NULL; if (*s == NULL) break; if (*s == '"') { for (vec[i++] = ++s; *s != NULL && *s != '"'; s++) if (*s == QUOTE) { if (*++s == '"') (void) strcpy (s - 1, s); s--; } if (*s == '"') *s++ = NULL; continue; } if (*s == QUOTE && *++s != '"') s--; vec[i++] = s++; while (*s != NULL && !isspace (*s) && *s != ',') s++; } vec[i] = NULL; return i; } /* \f */ void freeUF (head) UF head; { register UF uf; for (uf = head -> uf_forw; uf != head; uf = uf -> uf_forw) { free (uf -> uf_command); free ((char *) uf -> uf_args); remque (uf); free ((char *) uf); } } /* \f */ /* ARGSUSED */ static void UFexec (tag, reason) caddr_t tag; unsigned long reason; { register int i; register char *cp, **ap, **pp, **qp; register FI fi, *gi; register UF uf = (UF) tag; if (uf -> uf_mode == UFexecError) { display_message (NULLCP, "function \"%s\" is improperly defined", uf -> uf_name); return; } remove_message (0); if (uf -> uf_mode == UFexecUnknown) { uf -> uf_mode = UFexecNone; for (ap = uf -> uf_args; cp = *ap; ap++) if (*cp == '%') { switch (*++cp) { case '%': { register char *dp; for (dp = cp - 1; *dp++ = *cp++;) continue; } break; case 'n': if (uf -> uf_mode != UFexecNone) { multiple: ; display_message (NULLCP, "multiple %%-expressions in function \"%s\"", uf -> uf_name); uf -> uf_mode = UFexecError; return; } for (pp = ap, qp = ap + 1; *pp++ = *qp++;) continue; uf -> uf_mode = UFexecIgnore; break; case 'f': if (uf -> uf_mode != UFexecNone) goto multiple; uf -> uf_mode = UFexecEachFile; uf -> uf_ap = ap; break; case 'F': if (uf -> uf_mode != UFexecNone) goto multiple; uf -> uf_mode = UFexecAllFiles; uf -> uf_ap = ap; break; case 'd': if (uf -> uf_mode != UFexecNone) goto multiple; uf -> uf_mode = UFexecEachDirectory; uf -> uf_ap = ap; break; case 'D': if (uf -> uf_mode != UFexecNone) goto multiple; uf -> uf_mode = UFexecAllDirectories; uf -> uf_ap = ap; break; case 'r': if (uf -> uf_mode != UFexecNone) goto multiple; uf -> uf_mode = UFexecEachRegular; uf -> uf_ap = ap; break; case 'R': if (uf -> uf_mode != UFexecNone) goto multiple; uf -> uf_mode = UFexecAllRegulars; uf -> uf_ap = ap; break; } } if (uf -> uf_mode == UFexecNone) uf -> uf_ap = ap; } if (uf -> uf_mode != UFexecIgnore) { if (numselected == 0) { if (advancesw) { doAdvance ((caddr_t) 2, (unsigned long) uf -> uf_mode); XFlush (); } else display_message (NULLCP, "nothing selected"); if (numselected == 0) return; } if (curDI -> di_list == NULL) { i = 0; for (fi = curDI -> di_parts.fi_forw; fi != &curDI -> di_parts; fi = fi -> fi_forw) i++; if (i > 0) { curDI -> di_list = (FI *) calloc ((unsigned int) (i + 1), sizeof *curDI -> di_list); if (curDI -> di_list == NULL) { display_message (NULLCP, "insufficient memory"); return; } } } gi = curDI -> di_list; switch (uf -> uf_mode) { case UFexecNone: case UFexecEachFile: case UFexecAllFiles: for (fi = curDI -> di_parts.fi_forw; fi != &curDI -> di_parts; fi = fi -> fi_forw) if (fi -> fi_selected) *gi++ = fi; break; case UFexecEachRegular: case UFexecAllRegulars: for (fi = curDI -> di_parts.fi_forw; fi != &curDI -> di_parts; fi = fi -> fi_forw) if (fi -> fi_selected && !FI_ISDIR (fi)) *gi++ = fi; if (gi != curDI -> di_list) break; display_message (NULLCP, "no regular files selected"); return; case UFexecEachDirectory: case UFexecAllDirectories: for (fi = curDI -> di_parts.fi_forw; fi != &curDI -> di_parts; fi = fi -> fi_forw) if (fi -> fi_selected && FI_ISDIR (fi)) *gi++ = fi; if (gi != curDI -> di_list) break; display_message (NULLCP, "no directories selected"); return; default: display_message (NULLCP, "unknown %-expression in function \"%s\"", uf -> uf_name); uf -> uf_mode = UFexecError; return; } *gi = NULLFI; i = gi - curDI -> di_list; if (sortsw && i > 1) qsort ((char *) curDI -> di_list, i, sizeof *curDI -> di_list, filesort); } switch (uf -> uf_mode) { case UFexecNone: case UFexecEachRegular: case UFexecEachDirectory: case UFexecEachFile: cp = *uf -> uf_ap; for (gi = curDI -> di_list; fi = *gi; gi++) { *uf -> uf_ap = fi -> fi_direct -> d_name; (void) run (uf -> uf_args); } *uf -> uf_ap = cp; break; case UFexecIgnore: (void) run (uf -> uf_args); break; case UFexecAllRegulars: case UFexecAllDirectories: case UFexecAllFiles: if ((ap = (char **) calloc ((unsigned int) (uf -> uf_narg + i), sizeof *ap)) == NULL) { display_message (NULLCP, "insufficient memory"); return; } for (pp = uf -> uf_args, qp = ap; pp < uf -> uf_ap; pp++, qp++) *qp = *pp; for (gi = curDI -> di_list; fi = *gi; gi++) *qp++ = fi -> fi_direct -> d_name; for (pp++; *pp; pp++, qp++) *qp = *pp; (void) run (ap); free ((char *) ap); break; } if (advancesw) doAdvance ((caddr_t) 2, (unsigned long) uf -> uf_mode); else if (!reselectsw) doSelect ((caddr_t) 0, 0L); } /* \f */ /* ARGSUSED */ static void UFpick (tag, reason) caddr_t tag; unsigned long reason; { display_message (NULLCP, "f.pick -- not yet implemented"); } /* \f */ static int filesort (fi, gi) FI *fi, *gi; { return ((*fi) -> fi_selectpos - (*gi) -> fi_selectpos); } /* \f */ static int run (args) char **args; { int pid, status, w; int (*istat) (), (*qstat) (); if (autoraisesw && xtermid != NULL) XRaiseWindow (xtermid); XFlush (); switch (pid = vfork ()) { case NOTOK: display_message ("fork", "unable to"); status = NOTOK; break; case OK: execvp (*args, args); fprintf (stderr, "unable to exec "); perror (*args); _exit (1); /* NOTREACHED */ default: istat = signal (SIGINT, SIG_IGN); qstat = signal (SIGQUIT, SIG_IGN); while ((w = wait (&status)) != pid) if (w == NOTOK) { status = NOTOK; break; } (void) signal (SIGINT, istat); (void) signal (SIGQUIT, qstat); break; } return status; }