P8000/WEGA/contrib/ingres/dbs/ing_src/teil3/amxzip

1285 lines
28 KiB
Plaintext

.so /z/ing_src/macdoc
.pn 320
.NH 1
.NH 1
.NH 1
.ds RH \f3AMX/ZIP\f1
.ds RF \f3\*(xx\f1
.ds LH Beispiele
.ds LF \*(vv
.ds CH - % -
.bp
.NH 2
.ft B
Terminkontrolle **
.ft R
.LP
.sp 10
.NH 3
.ft B
Vorbemerkung
.ft R
.LP
Um sich sinnvoll in ein \*(xx-System einzuordnen,
sollte das Prinzip des "Werkzeugkastens" auch in der
Anwenderebene durch\%ge\%standen werden - n\o'a"'mlich kleine Programme
mit exakt abgegrenzten Leistungen zu schaffen und diese
zu einem Paket verbinden.
Nachfolgend wird auszugsweise ein Projekt vorgestellt,
das die Nutzung von AMX und ZIP veranschaulicht.
.LP
Als Bedingungen seien gestellt:
.br
Die Terminkontrolle ist schirmorientiert zu l\o'o"'sen.
Bei Bedarf k\o'o"'nnen Protokolle gedruckt werden.
Die zu kontrollierende Einheit besteht aus einer
Basis-Massnahme und keiner oder beliebig vielen Festlegungen.
W\o'a"'hrend des Kontrollvorganges sollen die Basis-Massnahmen
gezeigt (entsprechend vorzugebender Eingrenzungen),
ge\o'a"'ndert oder als realisiert markiert werden - Festlegungen
sollen gezeigt, korrigiert, als realisiert markiert oder neu
hinzugef\o'u"'gt werden. Neben der M\o'o"'glichkeit \o'u"'ber
Zieltermine zu recherchieren, kann nach dem Kreis der,
f\o'u"'r die Reali\%sierung der Massnahme Verantwortlichen
(Gruppe oder Einzelperson) oder nach dem Kreis, der eine
Massnahme ausgel\o'o"'st hat (Gruppe oder Einzelperson) - gegen\o'u"'ber
dem der recherchierende Leiter also rechenschaftspflichtig ist -
eingegrenzt werden. Es existiert eine Nomenklatur, die Struktureinheiten
ordnet bzw. gruppiert.
.NH 3
.ft B
Relationen
.ft R
.LP
Innerhalb der Datenbank
.ft B
terkon
.ft R
werden folgende Relationen verwendet:
.br
.ft B
basis
.ft R
enth\o'a"'lt die Basis-Massnahmen.
\o'U"'ber die Massnahme-Nummer
.ft B
mnr
.ft R
werden die dazugeh\o'o"'rigen Festlegungen identifiziert.
.ft B
vongrup
.ft R
gibt Auskunft, durch welche Struktureinheit (auch \o'u"'bergeordnete
Organe) die Massnahme veranlasst wurde (Gruppe),
.ft B
vonpart
.ft R
grenzt innerhalb der Gruppe auf einen konkreten Partner ein.
.ft B
angrup
.ft R
bzw.
.ft B
anpart
.ft R
geben an, wer die Massnahme verantwortlich zu realisieren hat (Gruppe bzw.
Partner).
.ft B
edat
.ft R
ist das Rechnerdatum, zu dem die Massnahme erfasst wurde und
.ft B
termin
.ft R
der vorgegebene Zieltermin. Die Angabe
.ft B
festanz
.ft R
gilt als Hinweis auf die aktuelle Anzahl von Festlegungen,
ist der Wert -1 sind alle Festlegungen realisiert (Hinweis
zum Austragen).
Der eigentliche Text wird vierzeilig in
.ft B
tx1..tx4
.ft R
abgelegt.
.DS L
Relation: basis
--------- P8000 / EVK Olbernhau
Besitzer: kodir
Tupellaenge: 218
Verfallsdatum: Tue Jan 1 00:00:00 1991
Tupelanzahl: 131
Speicherstruktur: HEAP
Pages: 1 + 46
Relationentyp: Nutzerrelation
Domaenname Typ Laenge Schluessel
--------------------------------------------
mnr i 4
edat i 4
vongrup i 2
vonpart i 2
angrup i 2
anpart i 2
tx1 c 49
tx2 c 49
tx3 c 49
tx4 c 49
termin i 4
festanz i 2
--------------------------------------------
.DE
.ft B
festl
.ft R
enth\o'a"'lt die zur Basis-Massnahme geh\o'o"'rigen Festlegungen.
.ft B
fnr
.ft R
nummeriert innerhalb der Massnahme-Nummer,
.ft B
vgrup
.ft R
und
.ft B
vpart
.ft R
geben die Verantwortlichkeit und
.ft B
kgrup
.ft R
bzw.
.ft B
kpart
.ft R
die Kontrollpflicht an. Mit
.ft B
realis
.ft R
wird ein Kennzeichen f\o'u"'r gegebene Realisierung (=1)
gesetzt.
.DS L
Relation: festl
--------- P8000 / EVK Olbernhau
Besitzer: kodir
Tupellaenge: 216
Verfallsdatum: Tue Jan 1 00:00:00 1991
Tupelanzahl: 26
Speicherstruktur: HEAP
Pages: 1 + 11
Relationentyp: Nutzerrelation
Domaenname Typ Laenge Schluessel
--------------------------------------------
mnr i 4
fnr i 2
tx1 c 49
tx2 c 49
tx3 c 49
tx4 c 49
termin i 4
vgrup i 2
vpart i 2
kgrup i 2
kpart i 2
realis i 2
--------------------------------------------
.DE
.ft B
partn
.ft R
enth\o'a"'lt die Nomenklatur und Bezeichnungen der Struktureinheiten,
die an der Terminkontrolle teilhaben.
Mit
.ft B
grup
.ft R
wird eine Gruppe, mit
.ft B
fein
.ft R
ein Partner bestimmt.
.DS L
Relation: partn
--------- P8000 / EVK Olbernhau
Besitzer: kodir
Tupellaenge: 28
Verfallsdatum: Tue Jan 1 00:00:00 1991
Tupelanzahl: 56
Speicherstruktur: HEAP
Pages: 1 + 1
Relationentyp: Nutzerrelation
Domaenname Typ Laenge Schluessel
--------------------------------------------
grup i 2
fein i 2
bez c 24
--------------------------------------------
.DE
.ft B
mafenr
.ft R
ist eine tempor\o'a"'re Relation, die jeweils alle Massnahme-Nummern, sich
qualifizierender Tupel der Relation
.ft B
basis
.ft R
bzw. die dazugeh\o'o"'rigen Festlegungs-Nummern der Relation
.ft B
festl
.ft R
enth\o'a"'lt.
.DS L
Relation: mafenr
--------- P8000 / EVK Olbernhau
Besitzer: kodir
Tupellaenge: 6
Verfallsdatum: Tue Jan 1 00:00:00 1991
Tupelanzahl: 0
Speicherstruktur: HEAP
Pages: 1 + 0
Relationentyp: Nutzerrelation
Domaenname Typ Laenge Schluessel
--------------------------------------------
mnr i 4
fnr i 2
--------------------------------------------
.DE
.NH 3
.ft B
Steuerprogramm
.ft R
.LP
Um die relativ langen Zeilen der Quellprogramme noch
einigermassen \o'u"'bersichtlich darstellen zu k\o'o"'nnen,
wurden nachfolgend \et durch drei Leerzeichen ersetzt.
.LP
Das Hauptmenue steht in der Prozedur
.ft B
hauptm.c.
.ft R
Hier das Hauptprogramm:
.sp 2
.nf
/* Hauptmenue zur Terminkontrolle in hauptm.c */
/* Pfadname in cmd.c definiert */
# include <stdio.h>
# include <curses.h>
# include "/z/zip/inkeys.h"
char command[65];
main()
{
char *cmd();
initzip();
if (!system(cmd("part"))) goto fehler;
for (;;)
{
switch(hauptm())
{
case 1:
while (system(cmd("kontr")))
{
system(cmd("teko"));
system(cmd("delmaf"));
}
system(cmd("fanze"));
break;
case 2:
system(cmd("eiko"));
system(cmd("fanze"));
break;
case 3:
while (system(cmd("druw")))
{
system("modifyr terkon mafenr heapsort mnr fnr");
system("nq -nb newpg");
if (!system(cmd("druk")))
{
perror("Systemfehler");
sleep(5);
break;
}
clear(); refresh();
}
system(cmd("delmaf"));
break;
case 4:
system(cmd("nomenkl"));
if (!system(cmd("part"))) goto fehler;
break;
case 5:
crmode(); noecho();
clear();
refresh();
nocrmode(); echo();
endwin();
exit(0);
default:
goto fehler;
}
}
fehler:
crmode(); noecho();
clear();
refresh();
nocrmode(); echo();
endwin();
printf("*** System-Fehler ***\en");
exit(-1);
}
.fi
.LP
.ft B
initzip()
.ft R
ist eine Prozedur aus libzip.a, die die Initia\%lisierung
des Paketes
.ft B
curses
.ft R
und des Paketes
.ft B
zip
.ft R
veranlasst. Die Auswahl erfolgt \o'u"'ber die Prozedur hauptm(),
indem die gew\o'u"'nschte Zeile mit der Kursortaste (\o'|v') angefahren
und mit -> angeklickt wird.
Um einen \o'U"'berblick bez\o'u"'glich der Lei\%stung der
einzelnen Programme zu verschaffen wird nachfolgend die
Menue-Prozedur
.ft B
hauptm.c
.ft R
gezeigt:
.sp 2
.nf
/* Hauptmenue zur Terminkontrolle */
# include <curses.h>
# include "/z/zip/inkeys.h"
# define Fragen 5
# define Beginn 5
extern char *SO, *SE;
hauptm()
{
static char *men[] = {
"? Kontrolle von Faelligkeiten mit Aenderungsmoeglichkeit.. ",
"? Erfassung neuer Basis-Massnahmen (auch mit Festlegungen) ",
"? Druck von Protokollen (auch mit Eingrenzungen).......... ",
"? Aenderung und Ergaenzung der Nomenklatur (Partner)...... ",
"? Beendigung der Arbeit................................... "
};
int inp;
int aus;
int zl, sp, spa;
char buf[80];
crmode();
clear();
datum(12, 5);
move(2, 5);
addstr("TERMINKONTROLLE Hauptmenue");
zl = Beginn; sp = 5;
for (inp = 0; inp < Fragen; inp++)
{
move(zl+inp, sp);
strcpy(buf, SO);
strcat(buf, men[inp]);
strcat(buf, SE);
addstr(buf);
}
move(zl, sp-1);
refresh();
noecho();
for (;;)
{
aus = 0;
switch(inp = ZZgetchx())
{
case CCdo:
getyx(stdscr, zl, spa);
if (zl < (Fragen+Beginn-1)) move(++zl, spa);
break;
case CCup:
getyx(stdscr, zl, spa);
if (zl > Beginn) move(--zl, spa);
break;
case CCri:
nocrmode(); echo();
aus = zl - Beginn + 1;
move(zl, sp+1);
addstr(men[aus-1]);
refresh();
return(aus);
default :
continue;
}
refresh();
}
}
.fi
.LP
Mit der Prozedur hauptm() wird eine Leistung beschrieben, die
in der Regel die ZIP-Prozedur menzip() ausf\o'u"'hrt - der einzige
Unterschied besteht darin, dass das f\o'u"'hrende Fragezeichen nach
dem Anklicken durch die nachfolgende Zeichenkette (normale
Darstellung) \o'u"'berschrieben wird.
Die Pointer *SO und *SE stammen aus der termcap und realisieren
das Ein- und Ausschalten einer inversen Darstellung der Terminal\%ausgabe.
.ft B
ZZgetchx()
.ft R
bietet die M\o'o"'glichkeit, in der termcap definierte Steuerfolgen
auszuwerten - hier CCdo (Cursor down), CCup (Cursor up) usw. -
und entsprechende Reaktionen des Programms zu gestalten. Die
Prozedur steht in libzip.a, die entsprechenden Definitionen
zu CCdo, CCup usw. in inkeys.h.
Mit getyx() aus curses l\o'a"'sst sich die aktuelle Kursorposition
auf dem Standard-Screen (stdscr) erfragen und auf die nachfolgenden
beiden Parameter zur\o'u"'ck\%schreiben.
.NH 3
.ft B
Kontroll-Menue
.ft R
.LP
Das Programm
.ft B
teko
.ft R
wird nach dem Programm
.ft B
kontr
.ft R
gerufen. Mittels kontr wird eine Abfrage zur Qualifikation
(Eingrenzung) der Massnahmen bzw. Festlegungen realisiert.
Es entsteht die Relation
.ft B
mafenr,
.ft R
die eingangs alle eingegrenzten Massnahmen anbietet. Wird
teko durch einen Abbruch vorzeitig verlassen, ist diese
Relation mit delmaf wieder zu l\o'o"'schen.
.ft B
teko
.ft R
wird nachfolgend komplett gezeigt, Bezugspunkte f\o'u"'r
Erl\o'a"'uterungen werden laufend nummeriert (n) und als Kommentar
gekennzeichnet.
.sp 2
.ft B
teko.x:
.ft R
.nf
## shared terkon
/* Menue 1 - Kontr.-Menue: Eingangsrelation mafenr aus kontr */
/* Kontrolle von Festlegungen und Basis-Massnahmen; */
/* Basis-Massnahmen koennen geaendert, Festlegungen geaendert*/
/* und neue hinzugefuegt werden; */
# include <curses.h>
## long MNR;
## int GRUP;
## int FEIN;
## int FNR;
## char BEZ[24];
## char TX1[49];
## char TX2[49];
## char TX3[49];
## char TX4[49];
## long EDAT;
## long TERMIN;
## int VGRUP;
## int VPART;
## int AGRUP;
## int APART;
## int FESTL;
## int REALIS;
char DATUM[9];
char SLE[15];
char ANTW[2];
char mess[25];
int VON;
int clr;
int zl, sp;
int anzfest;
amx()
{
/* (1) */
static char *bas[] = {
"Weiter.............. ",
"Realisiert.......... ",
"Aendern............. ",
"Festl. zeigen/aend.. ",
"Festlegungen zufueg. ",
"Abbruch............. "
};
static char *fest[] = {
"Weiter.............. ",
"Realisiert.......... ",
"Aendern............. ",
"Festlegungen zufueg. "
};
static char *festzu[] = {
"Festlegungen zufueg. ",
"Abbruch............. "
};
int c;
int d;
int flag;
int flagm;
int flagf;
int end_fl;
int bas_fl;
int maxfnr;
int t_count;
long old_mnr;
initzip();
## open basis
## open partn
## open festl
## open mafenr
## use (+basis,partn,+festl,+mafenr)
zyk:
end_fl = 0;
## scan mafenr (MNR=$mnr, FNR=$fnr)
## {
++end_fl;
## }
if (!end_fl)
{
/* (2) */
melde();
goto end;
}
if (MNR == old_mnr) goto zyfest;
clr = 0;
flag = 0;
## scan basis $mnr=MNR (TX1=$tx1,TX2=$tx2,TX3=$tx3,TX4=$tx4,
## TERMIN=$termin,VGRUP=$vongrup,
## VPART=$vonpart,AGRUP=$angrup,APART=$anpart,FESTL=$festanz)
## {
++flag;
anzfest = FESTL;
/* (3) */
abas();
getyx(stdscr, zl, sp);
move(2, 52);
if (anzfest == -1)
sprintf(mess, "Festlegungen realisiert");
else
sprintf(mess, "%2d Festlegung(en) ! ", anzfest);
addstr(mess);
refresh();
move(zl, sp);
c = menzip(bas, 6, 3, 52);
switch(c)
{
case 2: /* B.-M. loeschen vorbereiten */
ZZbeep();
okay(1,0);
if (ANTW[0] == 'j' || ANTW[0] == 'J')
{
ZZbeep();
FESTL = -1;
}
break;
case 3: /* B.-M. korrigieren */
dbas(); /* Bereich fuer B.-M. loeschen */
/* (5) */
if (!ebas()) c = 1;
break;
default:
break;
}
if (c == 2 || c == 3)
{
## replace ($mnr=MNR,$tx1=TX1,$tx2=TX2,$tx3=TX3,$tx4=TX4,
## $termin=TERMIN,$vongrup=VGRUP,$edat=EDAT,
## $vonpart=VPART,$angrup=AGRUP,$anpart=APART,$festanz=FESTL)
}
## }
switch(c)
{
case 6: goto end;
case 1:
case 2:
case 3:
## scan mafenr $mnr=MNR
## {
## delete
## }
goto zyk;
default :
break;
}
d = 0;
flagf = 0;
zyfest:
switch(c)
{
case 4:
if (FNR) /* Ueber Festl. recherchiert */
{
## scan mafenr $mnr=MNR (FNR=$fnr)
## {
## scan festl $mnr=MNR, $fnr=FNR (TX1=$tx1,TX2=$tx2,TX3=$tx3,
## TX4=$tx4,TERMIN=$termin,VGRUP=$vgrup,
## VPART=$vpart,AGRUP=$kgrup,APART=$kpart,REALIS=$realis)
## {
dfest();
afest();
d = menzip(fest, 4, 13, 52);
switch(d)
{
case 1: break;
case 2: ZZbeep();
okay(1,0);
if (ANTW[0] == 'j' || ANTW[0] == 'J')
{
ZZbeep();
REALIS = 1;
}
case 3: if (!REALIS) kfest();
## replace ($mnr=MNR,$fnr=FNR,$tx1=TX1,$tx2=TX2,$tx3=TX3,
## $tx4=TX4,$termin=TERMIN,$vgrup=VGRUP,
## $vpart=VPART,$kgrup=AGRUP,$kpart=APART,$realis=REALIS)
break;
case 4: c = 5;
goto zyfest;
}
## }
## delete
## }
}
else /* Keine Festl.-Nr.: Recherche BMn. */
{
++flagf;
## scan festl $mnr=MNR (FNR=$fnr,TX1=$tx1,TX2=$tx2,TX3=$tx3,
## TX4=$tx4,TERMIN=$termin,VGRUP=$vgrup,
## VPART=$vpart,AGRUP=$kgrup,APART=$kpart,REALIS=$realis)
## {
dfest();
afest();
d = menzip(fest, 4, 13, 52);
switch(d)
{
case 1: break;
case 2: REALIS = 1;
case 3: if (!REALIS) kfest();
## replace ($mnr=MNR,$fnr=FNR,$tx1=TX1,$tx2=TX2,$tx3=TX3,
## $tx4=TX4,$termin=TERMIN,$vgrup=VGRUP,
## $vpart=VPART,$kgrup=AGRUP,$kpart=APART,$realis=REALIS)
break;
case 4: c = 5;
goto zyfest;
}
## }
}
break;
case 5:
++flagf;
zyzuf: if (d == 4)
{
maxfnr = 1;
## scan festl $mnr=MNR (FESTL=$fnr)
## {
if (FESTL > maxfnr) maxfnr = FESTL;
## }
}
TX1[0] = '\e0';
TX2[0] = '\e0';
TX3[0] = '\e0';
TX4[0] = '\e0';
FNR = maxfnr + 1;
kfest();
## append festl ($mnr=MNR,$fnr=FNR,$tx1=TX1,$tx2=TX2,$tx3=TX3,
## $tx4=TX4,$termin=TERMIN,$vgrup=VGRUP,
## $vpart=VPART,$kgrup=AGRUP,$kpart=APART,$realis=REALIS)
if ((d = menzip(festzu, 2, 13, 52)) == 1)
{
d = 4;
goto zyzuf;
}
break;
default: break;
}
if (flagf)
{
## scan mafenr $mnr=MNR
## {
## delete
## }
flagf = 0;
}
goto zyk;
end:
## commit
## close partn
## close basis
## close festl
## close mafenr
}
/* (4) */
ks_part()
{
## scan partn $grup=GRUP, $fein=FEIN (BEZ=$bez)
## {
## }
}
.fi
.LP
Die Datenbank wird f\o'u"'r mehrere Nutzer gleichzeitig
ge\o'o"'ffnet (shared). Dabei sind die Relationen
.ft B
basis, festl
.ft R
und
.ft B
mafenr
.ft R
zum Lesen und Schreiben sowie
.ft B
partn
.ft R
nur zum Lesen verf\o'u"'gbar (use).
Die lokalen Vereinbarungen
.ft B
(1)
.ft R
repr\o'a"'sentieren jeweils ein
Menue, das mit menzip() zur Anzeige kommt.
.LP
Die Prozedur
.ft B
melde()
.ft R
bei
.ft B
(2)
.ft R
teilt bei den Phasen, die mehrere Sekunden keine Ver\o'a"'nderungen
am Bildschirm veranlassen, mit, dass der Rechner arbeitet. Die
Prozedur beinhaltet lediglich eine Positionierung mit move(),
nachdem vorher mit getyx() die aktuelle Kursor-Position gesichert
wurde und gibt die Zeichenkette
.ft B
Ich arbeite!
.ft R
mit addstr()
aus - die Prozeduren entstammen
curses.
.sp 2
.nf
/* Ausschrift einer Meldung am Bildschirm */
# include <curses.h>
melde()
{
int zl, sp;
getyx(stdscr, zl, sp);
move(15, 1);
addstr(" Ich arbeite ! ");
refresh();
move(zl, sp);
}
.fi
.LP
Die Prozedur
.ft B
abas()
.ft R
bei
.ft B
(3)
.ft R
fasst einige Positionierungen und ZIP-Prozeduren
zusammen.
.sp 2
.nf
/* Anzeige Basis-Massnahmen */
# include <curses.h>
extern int GRUP, VGRUP, FEIN, VPART, AGRUP, APART;
extern long TERMIN;
extern char DATUM[9];
extern char SLE[15];
extern int clr;
extern int anzfest;
extern char mess[25];
abas()
{
emnr(clr++, 0);
tocdat(&TERMIN, DATUM);
dfest();
strcpy(SLE, "Basis-Massn.");
bas(clr, -1);
tobdat(DATUM, &TERMIN);
move(8, 0);
refresh();
strcpy(SLE, "Aufgst. durch");
GRUP = VGRUP;
FEIN = VPART;
ks_part();
kvekop(clr, 0);
strcpy(SLE, "Realis. durch");
GRUP = AGRUP;
FEIN = APART;
ks_part();
kvekop(clr, 0);
APART = FEIN;
refresh();
}
.fi
.LP
abas() soll die Basis-Massnahmen entsprechend der, in
der Relation mafenr vorgegebenen Reihenfolge anzeigen.
Um dies etwas zu verdeutlichen, sehen wir uns den Aufbau
der oberen H\o'a"'lfte des Bildschirms an:
.sp 2
.DS L
+-----------------------------------------------------------+
Massnahme-Nr.: 9999999999 >>>> TERMINKONTROLLE <<<<
Text Basis-Massn. : 1 Festlegung(en) !
>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..aa< +--------------------+
>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..aa< |Weiter..............|
>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..aa< |Realisiert..........|
>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..aa< |Aendern.............|
Termin(tt.mm.jj) : 28.02.89< |Festl. zeigen/aend..|
\&.Aufgst. durch > Partner: Kombinatsd.. |Festlegungen zufueg.|
\&.Realis. durch > Partner: Direktor T.. |Abbruch.............|
+--------------------+
+-----------------------------------------------------------+
.DE
.LP
Die Abbildung wurde nicht
v\o'o"'llig korrekt wiedergegeben, weil eine
Breite von 80 Zeichen den rechten Rand beim Druck zu weit
\o'u"'berschreitet. Das invers zu zeigende Menue aus der
Zeichenkettenvariablen
.ft B
*bas
.ft R
wurde gerahmt dargestellt. In der Regel wird der untere Teil
des Bildschirms - sofern Festlegungen vorhanden sind -
beim Anklicken der 4. Zeile des Menues mit der analogen Darstellung
zur Festlegung gef\o'u"'llt. Das Menue 'Weiter' zeigt
die n\o'a"'chste Massnahme. Das Anklicken von 'Realisiert'
ist mit einer R\o'u"'ckversicherung verbunden - die Frage
.ft B
Okay (j/n)?
.ft R
muss mit 'j' beantwortet werden, bevor die Massnahme
tats\o'a"'chlich zum L\o'o"'schen markiert wird. Ein Piepton
(ZZbeep()) best\o'a"'tigt die L\o'o"'schvormerkung.
.LP
Zur\o'u"'ck zu abas().
.ft B
curses.h
.ft R
wurde eingezogen, um die Makros aus curses
.ft B
move()
.ft R
und
.ft B
refresh()
.ft R
verf\o'u"'gbar zu haben.
Die Prozedur
.ft B
emnr()
.ft R
ist aus ZIP entstanden und zeigt die Massnahme-Nr. an.
Der Erarbeitungsweg wird gezeigt.
.br
Mit dem Editor ist folgendes File
.ft B
emnr_m
.ft R
zu erstellen:
.sp 1
.DS L
Massnahme-Nr.: #999999999 >>>> TERMINKONTROLLE <<<<
.DE
Die Erzeugung des Quell- und Objektcodes erfolgt mit
dem Aufruf:
zip -l ../LIBTERM emnr
Die Maskenidentifikation '_m' darf nicht im Aufruf
angegeben sein, sonst wird der gesamte Name als Basisname
interpretiert. Im Dialog antworten sie in dieser Reihenfolge:
.nf
l
MNR
n
.fi
.LP
Zur Verdeutlichung wird das entstehende _i-File
gezeigt, das f\o'u"'r eventuelle Modifikationen genutzt werden kann
und \o'u"'ber den stattgefundenen Dialog informiert.
.DS L
emnr -l ../LIBTERM
long MNR n n
.DE
.LP
.ft B
tocdat()
.ft R
wandelt die intern \o'u"'bliche long-Darstellung (Zeit, Datum) in
die normale Darstellung des Datums (tt.mm.jj).
.ft B
dfest()
.ft R
l\o'o"'scht auf dem Bildschirm den Bereich, auf dem Festlegungen
dargestellt werden, um zu vermeiden, dass eine m\o'o"'glicherweise
von der vorausgegangenen Massnahme abgebildete Festlegung stehen
bleibt. Die ZIP-Prozedur
.ft B
bas()
.ft R
rea\%lisiert die Anzeige der n\o'a"'chsten 6 Zeilen, wobei das
2. Argument '-1' die Prozedur veranlasst, unabh\o'a"'ngig von
einer gew\o'u"'nschten Korrekturart, die Variablen nur auszuschreiben.
Die Maske
.ft B
bas_m
.ft R
sieht so aus:
.DS L
Text #aaaaaaaaaaaa:
>#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<
>#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<
>#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<
>#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<
Termin(tt.mm.jj) : #aaaaaaa<
.DE
Aus dem _i-File wird ersichtlich, welche Variablen verwendet und
wie sie behandelt werden sollen:
.DS L
bas -a 2 -pl ../LIBTERM
char SLE[15] n n
char TX1[49] j n
char TX2[49] j n
char TX3[49] j n
char TX4[49] j n
char DATUM[9] j testdat() w
.DE
Die Maske wird auf dem Bildschirm nach der 2. Zeile angeh\o'a"'ngt (-a 2)
und die Variable DATUM[9] einer Pr\o'u"'fung mit
.ft B
testdat()
.ft R
unterzogen (g\o'u"'ltiges Datum) - diese Pr\o'u"'fung wird nur bei einer
Korrektur des alten Wertes angestossen.
.ft B
tobdat()
.ft R
ist die Umkehrung von tocdat().
.LP
Mit
.ft B
refresh()
.ft R
werden die, auf der Speicherfl\o'a"'che stdscr vorgenommenen \o'A"'nderungen
sichtbar gemacht - dieser Algorithmus hilft, insgesamt ein ruhiges
Abbilden auf dem Schirm zu realisieren und die Kursorbewegungen zu
optimieren. Die Prozedur
.ft B
ks_part()
.ft R
- es geht noch um abas() -
stammt aus teko.x (4).
AMX-Statements k\o'o"'nnen nicht in separat zu \o'u"'bersetzenden Prozeduren
verwendet werden, der AMX-Compiler generiert ein main(). Das gezeigte
Beispiel weist auf eine sehr effiziente Anwendung von AMX hin,
mit der differenzierte und relativ komplizierte Einsatzf\o'a"'lle
l\o'o"'sbar sind.
ks_part() sucht zum angegebenen Schl\o'u"'ssel f\o'u"'r GRUP und FEIN
die Bezeichnung aus der Relation partn. Die Ausgabe der Bezeichnung
erfolgt mit
.ft B
kvekop().
.ft R
Im Gegensatz zu bas() kann kvekop() nicht durch eine fest eingestellte
Zeilennummer zur Positionierung \o'u"'bersetzt werden, da es zweimal bei
Basis-Massnahmen und zweimal bei Festlegungen benutzt wird.
F\o'u"'r solche Anwendungsf\o'a"'lle ist die Option -z von ZIP gedacht,
wie am Beispiel nocheinmal gezeigt werden soll:
.DS L
\&.#aaaaaaaaaaaaa >Partner: #aaaaaaaaaaaaaaaaaaaaaaa
.DE
Aus kvekop_i wird der Aufruf deutlich:
.DS L
kvekop -zl ../LIBTERM
char SLE[15] n n
char BEZ[24] n n
.DE
.LP
Nachdem abas() abgearbeitet ist, wird \o'u"'ber die Anzahl der
Festlegungen informiert. Die Verwendung von curses schliesst
direkte Ausgaben auf den Schirm (printf()) aus, deshalb
erfolgt erst der Aufbau der Zeichenkette mit sprintf() und
anschliessend die Ausgabe mittels addstr().
.LP
.ft B
menzip()
.ft R
ist in das Paket ZIP eingegliedert und gestattet eine freie
Postionierung eines Menues - das seitliche Ausrutschen der
Zeichenketten bei \o'U"'berschreitung der Spalte 80 wird nicht
kontrolliert, ebenso sollte die Spalte 80 selbst nicht benutzt
werden, weil einige Terminaldriver dort eigenwillig reagieren.
Die Argumente f\o'u"'r menzip() haben folgende Bedeutung:
.IP 1.Argument:
Variable, in der die auszugebende Zeichenkette
definiert ist.
.IP 2.Argument:
Zeilenzahl des Menues;
.IP 3.Argument:
Zeilennummer des Bildschirms, ab der das Menue geschrieben werden
soll, zusammen mit der Spaltennummer ergibt das die linke obere
Ecke des Menues.
.IP 4.Argument:
Spaltennummer des Bildschirms, mit 1 beginnend.
.LP
Sofern das benutzte Terminal invers schreiben kann, wird das
Menue so ausgegeben und die angeklickte Zeile auf normal
gewandelt.
.LP
Mit der Prozedur
.ft B
ebas()
.ft R
(5) k\o'o"'nnen Basismassnahmen korrigiert werden, insoweit unterscheidet
sie sich von abas(). Durch die Korrektur ist ausserdem denkbar,
dass w\o'a"'hrend einer Eingabe mit zweimal Interrupt (bspw. DEL)
abgebrochen wird und der R\o'u"'ckkehrcode der ZIP-Prozedur
im Hauptprogramm behandelt werden muss.
Nachfolgend die Prozedur:
.nf
/* Erfassung oder Korrektur von Basis-Massnahmen */
# include <curses.h>
extern int GRUP, VGRUP, FEIN, VPART, APART, VON, AGRUP;
extern long TERMIN;
extern char DATUM[9];
extern char SLE[15];
extern char ANTW[2];
extern int clr, anzfest;
extern char mess[25];
ebas()
{
tocdat(&TERMIN, DATUM);
move(1, 0);
emnr(clr, 0);
wdh:
strcpy(SLE, "Basis-Massn.");
if (!bas(clr, 1)) return(0);
tobdat(DATUM, &TERMIN);
move(2, 52);
sprintf(mess, "%2d Festlegung(en)!", anzfest);
addstr(mess);
move(8, 0);
refresh();
strcpy(SLE, "Aufgst. durch");
GRUP = VGRUP;
VON = 0;
if (!verkog(clr, 0)) return(0);
VGRUP = GRUP;
VON = 1;
FEIN = VPART;
if (!verkop(clr, 0)) return(0);
VPART = FEIN;
strcpy(SLE, "Realis. durch");
GRUP = AGRUP;
VON = 0;
move(10, 0);
refresh();
if (!verkog(clr, 0)) return(0);
AGRUP = GRUP;
FEIN = APART;
VON = 1;
if (!verkop(clr, 0)) return(0);
APART = FEIN;
okay(1, 0);
if (ANTW[0] == 'n' || ANTW[0] == 'N') goto wdh;
else ZZbeep();
return(1);
}
.fi
.LP
Innerhalb von ebas() sind die ZIP-Prozeduren
.ft B
verkog()
.ft R
f\o'u"'r die Eingabe des Gruppenschl\o'u"'ssels und
.ft B
verkop()
.ft R
f\o'u"'r die Eingabe des Partnerschl\o'u"'ssels interessant, weil hier
\o'u"'ber eine Hilfe (Eingabe von ?) aus der Relation partn
die Schl\o'u"'sseltabelle f\o'u"'r Gruppen bzw. Partner innerhalb der
gew\o'a"'hlten Gruppe angezeigt werden k\o'o"'nnen.
Als Beispiel wird verkog() vorgestellt:
.DS L
Maske:
#aaaaaaaaaaaaaa > Gruppe: #9
verkog_i:
-zhl ../LIBTERM verkog
char SLE[15] n n
int GRUP j n s_part() p
.DE
.LP
Die Hilfe wird in diesem Fall \o'u"'ber
.ft B
s_part()
.ft R
realisiert.
.nf
/* Nutzt das File 'partner' aus 'part.x', zeigt fuer Hilfe
** die Gruppenuebersicht bzw. die Partner zur Gruppe an !
*/
# include <curses.h>
extern int GRUP;
extern int VON;
s_part()
{
FILE *fp, *fopen();
int zl = 8;
int count = 14;
int fein, grup;
char bez[24];
char buf[29];
if ((fp = fopen("/z/ing_db/work/termin/partner", "r")) == NULL)
{
echo(); nocrmode();
perror("partner not found");
exit(0);
}
while (fscanf(fp, "%d %d ", &grup, &fein) != EOF)
{
if (fgets(bez, 24, fp) == NULL) break;
if (!VON)
{
if (!fein)
{
move(zl, 50); addstr(" ");
sprintf(buf,"%2d %s", grup, bez);
move(zl, 51); addstr(buf);
}
else continue;
}
else
{
if (GRUP == grup)
{
move(zl, 50); addstr(" ");
sprintf(buf, "%2d %s", fein, bez);
move(zl, 51); addstr(buf);
}
else continue;
}
++zl;
if (!(--count))
{
refresh();
getchar(zl);
zl = 8;
count = 14;
}
}
refresh();
fclose(fp);
}
.fi
.LP
Der scan() aus ks_part() k\o'o"'nnte auf den ersten Blick
eigentlich auch hier genutzt
werden, analog m\o'u"'sste anstelle des fscanf() die Prozedur ks_part()
stehen und die in der Qualifikation geforderten Werte in einer
Schleife aktua\%li\%siert werden.
Allerdings w\o'a"'re die Formulierung der Qualifikation '$grup=GRUP, $fein=FEIN'
zu differenzieren und damit drei scan() erforderlich.
Die Kopie der Relation partn in ein \*(xx -File
ist in diesem Fall doch der geringere Aufwand.
Da maximal 14 Zeilen, beginnend ab 6, geschrieben werden k\o'o"'nnen, wird
mit getchar(zl) die Ausgabe gestoppt und nach Eingabe eines beliebigen
Zeichens fortgesetzt.
.LP
Einige wesentliche Dinge sind damit erkl\o'a"'rt.
Da der Rahmen des Anwenderhandbuches durch weitergehende Beschreibungen
gesprengt w\o'u"'rde, muss hier das Kapitel abgebrochen werden.