|
|
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;
}