home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
EFFO
/
forum16.lzh
/
SOFTWARE
/
C
/
DIV_UTILITIES
/
if.c
< prev
next >
Wrap
Text File
|
1991-03-24
|
8KB
|
302 lines
/*******************************************************************************
| Programmbeschreibung:
| Testet eine angegebene Bedingung und fuehrt in Abhaengigkeit vom Resultat
| des Tests unterschiedliche Teile der Argumentliste als Shell-Kommandozei-
| len aus.
+-------------------------------------------------------------------------------
| Autoren: Kuerzel Name
| MM Martin Moser, Jakob-Brucker-Str 15, 8950 Kaufbeuren
+-------------------------------------------------------------------------------
| Version Datum Kuerzel Arbeitsbericht
| 1.0 26.11.90 MM Urversion
+-------------------------------------------------------------------------------
| Besonderheiten:
| Das Programm wurde auf moeglichst einfache Erweiterbarkeit ausgelegt.
| Eigene Tests lassen sich einbauen, indem ein entsprechender Initiali-
| sierungsaufruf in die Funktion 'initCL' eingebaut und eine ent-
| sprechende Testfunktion programmiert wird.
*******************************************************************************/
/********** include - Files **********/
#include <stdio.h>
#include <errno.h>
#include "../DEFS/bool.h"
#include <module.h>
#include <strings.h>
/********** interne Definitionen **********/
#define EmptyList (struct c *) NULL
#define Any 0 /* loaded: der Modultyp ist unerheblich */
/********** interne Makros **********/
#define ErrExit(s, n) exit(_errmsg(n, s))
#define AddCond(f, t, a, p, d, cl) cl = addCond(f, t, a, p, d, cl)
/********** interne Strukturen **********/
struct c { /* Sturuktur zur Beschreibung eines Tests */
bool (*f)(); /* Adresse der Testfunktion */
char *t; /* Name des Tests */
int a; /* Stelligkeit des Tests */
char *p, /* Schema fuer Parameterliste des Tests */
*d; /* Kurzbeschreibung des Tests */
struct c *n; /* Verkettungselement fuer Listenaufbau */
};
/********** Testfunktionen **********/
/* > varVal: eine Umgebungsvariable auf einen Wert testen */
bool varVal(argv, i)
char *argv[];
int i;
{
return(strcmp(getenv(argv[i + 1]), argv[i + 2]) == 0 ?
True : False);
}
/* > loaded: testen, ob ein Modul bereits im Speicher ist */
bool loaded(argv, i)
char *argv[];
int i;
{
mod_exec *m;
if ((int) (m = modlink(argv[i + 1], Any)) != -1) {
munlink(m);
return(True);
} else
return(False);
}
/* > def: testen, ob eine Umgebungsvariable bereits definiert ist */
bool def(argv, i)
char *argv[];
int i;
{
return(getenv(argv[i + 1]) == NULL ? False : True);
}
/********** interne Funktionen **********/
/* > releaseCL: Liste der Tests wieder freigeben */
void releaseCL(cl)
struct c *cl;
{
struct c *h;
/* Alle Elemente der Liste freigeben */
while (cl != EmptyList) {
h = cl;
cl = cl->n;
free(h);
}
}
/* >> addCond: Test in die Liste aufnehmen */
struct c *addCond(f, t, a, p, d, cl)
bool (*f)();
char *t;
int a;
char *p, *d;
struct c *cl;
{
struct c *h = (struct c *) malloc(sizeof(struct c));
/* Test, ob neues Listenelement erzeugt werden konnte */
if (h == EmptyList) {
releaseCL(cl);
ErrExit("not enough memory for condition list", errno);
}
/* Komponenten des neuen Listenelements besetzen */
h->f = f;
h->t = t;
h->a = a;
h->p = p;
h->d = d;
h->n = cl;
return(h);
}
/* > initCL: Liste der zulaessigen Test aufbauen */
struct c *initCL(cl)
struct c *cl;
{
AddCond(varVal, "varval", 2, "<var> <val>",
"true, if envir. variable <var> has value <val>", cl);
AddCond(loaded, "loaded", 1, "<mod>",
"true, if module <mod> is already loaded", cl);
AddCond(def, "def", 1, "<var>",
"true, if environment variable <var> is defined", cl);
return(cl);
}
/* >> strEqu: Stringvergleich ohne Unterscheidung Gross/Kleinschrift */
bool strEqu(s1, s2)
char *s1, *s2;
{
while (*s1 != '\0' && *s2 != '\0' && toupper(*s1) == toupper(*s2)) {
s1++;
s2++;
}
return(toupper(*s1) == toupper(*s2));
}
/* > findArg: Ein Argument in der Kommandozeile suchen */
int findArg(s, n, argc, argv)
char *s;
int n, argc;
char *argv[];
{
while (n < argc && ! strEqu(s, argv[n]))
n++;
return(n < argc ? n : -1);
}
/* > help: kurze Funktionsbeschreibung und Fehlertext ausgeben */
void help(cl, s, n)
struct c *cl;
char *s;
int n;
{
struct c *h = cl; /* Hilfsvariable */
/* Funktionsbeschreibung ausgeben */
printf("Syntax: if [not] <cond> {<arg>} {<cmd1>} [else ");
printf("{<cmd2>}] endif\n");
printf("Function: if the [negated] condition <cond> depending ");
printf("on the arguments\n");
printf(" <arg> is true, then hand the commands <cmd1> ");
printf("to the shell for\n");
printf(" execution, else, if provided, <cmd2>.\n");
/* Liste der vorhandenen Tests ausgeben */
printf("Conditions available:\n");
while (h != EmptyList) {
printf(" %-6.6s %-18.18s %s\n", h->t, h->p, h->d);
h = h->n;
}
printf("Options:\n");
printf(" (none)\n");
/* Gegebenenfalls Fehlermeldung ausgeben und Programm beenden */
if (n > 0) {
releaseCL(cl);
ErrExit(s, n);
}
}
/* >> dispatchTest: den gewuenschten Test in der Liste suchen */
struct c *dispatchTest(s, cl)
char *s;
struct c *cl;
{
struct c *h = cl;
/* Test in Liste suchen */
while (h != EmptyList && ! strEqu(s, h->t))
h = h->n;
if (h == EmptyList)
help(cl, "unknown test", 1);
return(h);
}
/* >> execCmds: Argumente als Systemkommandos ausfuehren */
void execCmds(argv, i, n)
char *argv[];
int i, n;
{
while (n-- > 0)
system(argv[i++]);
}
/* > evalCond: Bedingung auswerten */
void evalCond(argc, argv, cl)
int argc;
char *argv[];
struct c *cl;
{
struct c *c; /* Deskriptor des selektierten Tests */
int i = 1, /* Index fuer Argumente in der Kommandozeile */
j, /* Hilfsgroesse */
m, /* Anzahl der Kommandos zwischen Test und ENDIF */
n; /* bzw. zwischen ELSE und ENDIF */
bool p = True; /* positiven Test voraussetzen */
/* Feststellen, ob negierter Test */
if (strEqu(argv[i], "not")) {
p = False;
i++;
}
/* Art des Test auslesen und Anzahl der Argumente pruefen */
c = dispatchTest(argv[i], cl);
j = i + c->a + 1;
if (j >= argc)
help(cl, "wrong number of arguments", 1);
/* ELSE und ENDIF suchen */
n = findArg("else", j, argc, argv);
m = findArg("endif", (n >= 0 ? n + 1 : j), argc, argv);
if (m < 0)
help(cl, "missing 'endif' (maybe wrong number of arguments)", 1);
/* Test ausfuehren */
if ((c->f)(argv, i) == p)
execCmds(argv, j, (n >= 0 ? n : m) - j);
else
if (n >= 0)
execCmds(argv, n + 1, m - n - 1);
}
/********** Hauptprogramm **********/
main(argc, argv)
int argc;
char *argv[];
{
struct c *cl; /* Liste der Tests */
/* Liste der Tests aufbauen */
cl = initCL(EmptyList);
/* Funktionsbeschreibung ausgeben oder Test ausfuehren */
if (findArg("-?", 1, argc, argv) >= 1)
help(cl, "", 0);
else if (argc < 3)
help(cl, "incorrect syntax", 1);
else
evalCond(argc, argv, cl);
/* Liste der Tests freigeben */
releaseCL(cl);
exit(0);
}
/***************************** Ende des Files *********************************/