DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T f

⟦2d48d28ec⟧ TextFile

    Length: 9944 (0x26d8)
    Types: TextFile
    Names: »functions.c«

Derivation

└─⟦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« 

TextFile

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