a99  V32.6
allegro Windows Hauptprogramm
 Alle Klassen Dateien Funktionen Variablen Typdefinitionen Aufzählungen Aufzählungswerte Makrodefinitionen
exet2.cpp
gehe zur Dokumentation dieser Datei
1 // exet2.cpp %% DOS: aexp2.c
2 // 1995-08-19 Parameterdatei, interne Darstellung; Einlesen der Datei
3 // Copyright 2011 Universitätsbibliothek Braunschweig, more see bottom
4 
5 // Klasse EXET Teil 2 (c) UB Braunschweig 1995
6 
7 /*
8  read parameter files of .cPR/.cPT and .cPI type
9  and convert into internal representation.
10  Sorry, but there's very little error checking!
11  General rule: 2 spaces - rest of line is comment
12  and: lines starting with space are treated as comments
13 
14  METHODS: (von aussen nutzbar)
15  E2Exet() main function, reads a param file
16 
17  Internal FUNCTIONS:
18 
19  ActiveGns() Gns setzen = interne Numerierung der EXET-Objekte
20  Par_init() initialize the EXET object
21  pr_par() Parameterzeile in interne Form konvertieren
22  ex_preproc() Zeile, die mit # oder ! beginnt (Manip.Befehle!)
23  ersatz() Ersatzdarstell. -> Phrasenspeicher
24  get_z() Zw.Teil lesen und in Phr.Sp. kopieren
25  getcs() Steuerzeichenfolge einlesen
26 
27 */
28 
29 #include "allegro.hpp"
30 #include "exet.hpp"
31 
32 /* phrase space usage: Gns = Nummer der geladenen Param.Datei, 0...9
33  (Die EXET-Objekte werden intern numeriert durch Funktion ActiveGns())
34  1000 + Gns*128 + j fix j, d.h. Zw.Teil 10 hat Nummer 1010, wenn Gns==0
35  10000 + Gns*300 + j ersatz p
36  20000 + Gns*300 + j ersatz q
37  30000 + Gns*500 + j global replace strings for set Gns
38  40000 + Adn*100 +j Glob. Ersetzungen
39 */
40 
41 CHAR Aw[1524]; // Hilfsfeld f. eine Zeile der Param.datei
42 
43 // CHAR chX[8000]; // geht nicht!
44 
45 char U1[8]="\\u", U2[8]="?"; // for UTF8->Entity, pre-/suffix $$2009
46 
47 int Outnull(int) // dummy output function
48 {
49  return 1;
50 }
51 
52 // FUNCTIONS
53 
54 // Vorher muss z.B. KONFIG kfg = new KONFIG("A"); gemacht werden
55 // d.h. ein Objekt der Klasse KONFIG muss schon da sein
56 
57 // ************ Konstruktor der Klasse EXET:
58 EXET::EXET(char *parName,KONFIG *cfg, int md, char *dbdir)
59 // read export or index param file
60 // parName get file parName.<schema>PR
61 // cfg Konfiguration
62 // md Modus: 0=.APR, 1=.API, 2=.APT
63 {
64  *Aerror=0; // in case of error: this contains the message
65 
66  if (md!=2) Gns=ActiveGns(); // Das Objekt bekommt eine Nr. 0,...,9
67  if (Gns==-1)
68  {
69  sprintf(Aerror,"cannot load %s\nmore than 10 sets not possible%c",parName,0);
70  return;
71  }
72 
73  strcpy(dbDir,dbdir); // data dir
74 
75  if (md!=2)
76  {
77  outChar=putchar; // default output function (to stdout)
78 
79  kat=cfg->kat;
80  kfg=cfg; // to make konfig available to all members
81  tgl=cfg->tgl;
82  crix=0;
83  xuc=0; // $$030427 Unicodes codes
84  ucp=ucq=0;
85  xk=0;
86  }
87 // Nun das eigentliche Einlesen der Parameterdatei
88  if (!E2Exet(parName,cfg,md)) return;
89 
90 // Beseitigt, um unerwuenschte 'Magie' zu vermeiden
91 // if(!md) E2Exet("d",cfg,2); // lade defaultmaessig d.apt
92 // if(md==1) E2Exet("o",cfg,2); // bzw. o.apt noch hinzu
93 // *Aerror=0; $$970617 Muss sein, sonst erfaehrt aufrufendes programm
94 // den Fehler nicht
95 
96  *Aerror=0; // Signal, dass kein Fehler
97  return;
98 }
99 
100 // ******** Das Einlesen der Datei
101 // Damit man diese Funktion rekursiv aufrufen kann: %% prp_read()
102 
103 int EXET::E2Exet(char *parName,KONFIG *cfg, int md)
104 // md==1: index param 2==.apt 0==.apr
105 // return: 0=Fehler, dann Meldung in Aerror
106 {
107  static int inx=0;
108  unsigned int m, i;
109  FILE *parfile;
110  char xtn[5]=".apr";
111 // War vorher schon eine Datei geladen, dann erst beseitigen
112  if (xk && md!=2) destruct(); // z.B. bei FLEX: index p ... $$071029
113 
114  if (md<2) inx=xmod=md; // index modus
115  xtn[1]=cfg->schema;
116  xtn[3]=(inx)?'i':'r';
117  if (md==2) xtn[3]='t'; // .API, .APT
118 
119  strcpy(idp,parName);
120 
121 // if(!(sl=strpbrk(idp,"/+"))); // option -eX/NAME : cut at + or /
122 // else *sl=NL;
123  m=strlen(idp); // else append xtn
124  while (m) if (idp[--m]=='.') break;
125  if (m) idp[m]=NL;
126  strcat(idp,xtn);
127  // Option -I : andere IndexParamDatei
128  if (md==1)
129  {
130  char *argum;
131  if ((argum=SyGetArg('I',1))!=0)
132  {
133  strcpy(idp,argum);
134  strcat(idp,xtn);
135  }
136  }
137 
138 SECOND:
139 #ifdef ALCA
140  extern int accu; // Sicherheit: kein beliebiges File, wenn accu==0
141  if (accu>3 && strchr(idp,*fsep)) // NEU $$970204 Separator kommt vor
142 #else
143  if (strchr(idp,*fsep)) // NEU $$970204 Separator kommt vor
144 #endif
145  parfile=fopen(idp,"r"); // dann direkt oeffnen
146  else
147  parfile=SyOpen(idp,"r",dbDir); // .APR not found
148 
149  if (!parfile && idp[strlen(idp)-3]!='@') // auch noch @ probieren statt a
150  {
151  *Aerror=0;
152  idp[strlen(idp)-3]='@';
153  goto SECOND;
154  }
155 
156  if (!parfile)
157  {
158  sprintf(Aerror+strlen(Aerror),uif[49],idp); // Datei %s existiert nicht
159  return 0;
160  }
161  m=0;
162  if (md==1) m=1;
163 
164  if (md<2)
165  {
166  par_init(); // defaults setzen
167  xfm=0;
168  ntn=nt1=0; // number of non-terms
169 // defaults:
170  keymax=64; // max key length for index
171  tnix=0; // total nr of symbolic index names (I names)
172  stll=0; // short title length (index 0)
173  resl=ress=0; // restric length
174  ecod=0; // 1:user entry on index must be decoded in browse()
175 
176  i5=0; // Steuerzeichen fuer Stammsatz-Referenz, 0=inaktiv
177  i6=8; // Register fuer Stammsatznummern // $$941018 8 statt 9
178  i7=0; // Register der SR-Schluessel $$970227
179  ia=ic=0;// Praefixcode fuer Ersetzungsschl.
180  ib=59; // Endecode:Semikolon (Default fuer Unicode-"Entitaeten")
181 
182  ii=1; // $$ii Faktor fuer "Aufbohrung"
183 
184  strcpy(ixf,"ddddddddddd"); // ix=xxeddd... MultiX
185 
186  wildc_e='?'; // Wildcard fuer vergleiche
187  ami=1;
188  repfix=1;
189  pfl=1;
190  xCount=0L;
191  strcpy(delim1,"_\20>");
192  strcpy(delim2,"_\20=>");
193  }
194 // if(!of) mss(uif[50],idp); // Set %s wird geladen...
195 
196 // nun das eigentliche Einlesen der Datei, zeilenweise:
197 
198  while (fgets((char *)Awx,1500,parfile)!=NULL) // get param line into Awx
199  {
200  UtRemCom((char *)Awx); // Kommentar und whitespace am Ende weg
201  if (*Awx=='N') // Stopptwortliste beginnt : nonterm list (brief lines, one word each!)
202  {
203  *xkc++=NL; // Einlesen, bis wieder N kommt
204  while (fgets((char *)Awx,80,parfile)!=NULL) // get param line into Awx
205  {
206  UtRemCom((char *)Awx);
207  if (*Awx=='N') break;
208  if (*Awx=='>') nt1=ntn; // 20070131 2ndlist
209  else if (!isspace(*Awx)) // elim comments
210  {
211  i=0;
212  while (Awx[i]) if (isspace(Awx[i])) Awx[i]=NL;
213  else ++i;
214  strcpy(xkc,Awx);
215  nonterm[ntn++]=xkc++;
216  xkc+=strlen(Awx);
217  }
218  }
219  if (!nt1) nt1=ntn; // $$20070131
220 
221  } // Andere Befehle
222  else if (pr_par()) // Verarbeitung einer Zeile; return 1: Fehler
223 
224  {
225  sprintf(Aerror+strlen(Aerror),uif[52],Awx); // par_init(); // Fehler: %s
226  break;
227  }
228  } // end while
229 
230  fclose(parfile);
231  if (md==2) return 1;
232  *x0c= *xkc++=NL; // mark the end of xk
233  // $$010126 : NEU: parName, damit man den Dateinamen sieht
234  if (!*xk || *Aerror)
235  {
236  if (!*Aerror) sprintf(Aerror+strlen(Aerror)," %s : %s",uif[54],parName); // fehlerhafte Parameter nicht benutzbar
237  return 0;
238  }
239  // error detected, disallow all output
240  if (inx) xl=0; // default zl=0 fuer Indexparam
241  if (!xfc) xlm=0;
242  else if (!xlm) xfc=0; // file mode
243  if (!xl) // $$980728 NEU: xi=0
244  {
245  xi=0; // continuous output
246  xl=(ML-2)*MC;
247  xfl=xfc=xlm=0;
248  }
249  xri=xfm; // card mode
250 
251  /* if (of) { outf=1; return; } XXX
252  output wird alles extern gemacht!!!
253  m=exp_open(idp);
254  if (m=='0') { outf=0; expf=PRT1; }
255  */
256  ExOutf(Outnull); // default output function: nope
257  return 1;
258 } // ende des Konstruktors
259 
260 
261 // ****** Verarbeitung einer Zeile der Export-Parameterdatei
262 // das erste Zeichen ist das signifikante Befehlszeichen
263 // Die Parameterzeilen werden in kompakter Form verschluesselt gespeichert
264 int EXET::pr_par() // process param line Awx = global var.
265 {
266  int i, j, k, f;
267  CHAR *a;
268  int rc=0;
269  if (*Awx!=NL)
270  if (s_param((char *)Awx)) // programmer's interface for param line
271  // line begins with QT - multi spaces not eliminated!
272  if (*Awx==QT)
273  {
274  strcpy(Awx,Awx+1);
275  Awx[strlen(Awx)-1]=0;
276  }
277  switch (*Awx) // was ist das erste Zeichen?
278  {
279  case TAB:
280  case ' ':
281  break; // comment
282 
283  case 'l': // line related parms
284  case 'z': // zeilenbez.
285  switch (Awx[1])
286  {
287  case 'l': // line len
288  i=geti(3);
289  if (i>132) prw(xl);
290  else xl=i;
291  break;
292  case 'i': // indentation
293  i=geti(3); // $$980728 xl>10
294  if (xl>10 && i>xl-10) prw(xi);
295  else xi=i;
296  break;
297  case 'e': // line end
298  case 't': // obsolete
299  getcs(3,xle);
300  break;
301  case 'b': // line break characters
302  strcpy(xlb,Awx+4);
303  i=strlen(xlb)-1;
304  if (xlb[i]==QT) xlb[i]=NL;
305  break;
306  case 'm': // max lines per page
307  i=geti(3);
308  if (i && i<5) prw(xlm);
309  else xlm=i;
310  break;
311  case '1': // min lines before break
312  case '2': // max overflow over xlm
313  i=geti(3);
314  if (Awx[1]=='1') xl1=i;
315  else xl2=i;
316  if (xl1==0) xl1=50; // maximum
317  break;
318  default:
319  break;
320  }
321  break;
322 
323  case 'r': // record related params
324  case 'a': // aufnahmebez.
325  switch (Awx[1])
326  {
327  case 'd': // ad: default heading?
328  xrd=geti(3);
329  break;
330  case 'g': // ag: grouping: 0,1,2
331  xrg=geti(3);
332  break;
333  case 'e': // ae: rec end
334  getcs(3,xre);
335  break;
336  case 'f': // af: rec foot ctrl
337  getcs(3,xrf);
338  break;
339  case 'h': // ak: headings
340  case 'k': // ak-Befehle
341  a=xrK; // Bereich f.d. ak-Bef.
342  if (Awx[3]==NL)
343  {
344  *a=NL; // clear xrK
345  break;
346  }
347  if (*a!=NL) strcat(a,"\04"); // Delimiter, frueher " "
348  i=3;
349  a=a+strlen(a);
350  while (Awx[i])
351  {
352  int i0=i;
353  f=kfg->KoVerify(Awx+i);
354  if (f== -1) f=E3SpecKat(Awx+i-1);
355  else f+=256;
356  if (f== -1) /* ak=x.."ab"+M */
357  {
358  while (Awx[i] && !strchr("\042 +/",Awx[i]))
359  *a++=Awx[i++];
360  if (i-i0<1+tgl)
361  {
362  strcpy(a,"....");
363  a+=tgl+1-i+i0;
364  }
365  }
366  else // ak=xxf"abc"/nnf+M
367  {
368  *a++=(CHAR)((int)f/256);
369  *a++=(CHAR)(f%256);
370  if (f<256) i+=2;
371  else i+=tgl; // multicode ?
372  if (Awx[i]=='"' || Awx[i]==NL || Awx[i]==' ' || Awx[i]=='+' || Awx[i]=='/')
373  *a++=' ';
374  else *a++=Awx[i++];
375  }
376  if (Awx[i]=='"')
377  {
378  do (*a++=Awx[i++]) ;
379  while (Awx[i]!='"');
380  *a++=Awx[i++];
381  }
382  if (Awx[i]=='/') // secondary heading?
383  {
384  *a++='/';
385  f=kfg->KoVerify(Awx+(++i));
386  if (f== -1) f=E3SpecKat(Awx+i-1);
387  else f+=256;
388  *a++=f/256;
389  *a++=f%256;
390  if (f<260) i+=2;
391  else i+=tgl; /* multicode ? */
392  if (Awx[i]==NL || Awx[i]==' ' || Awx[i]=='+')
393  *a++=' ';
394  else *a++=Awx[i++];
395  } // Sprung: noch verbessern, damit auch ak=..+#nnf moeglich??
396  // $$051008 ak=nn+xi
397  if (Awx[i]=='+')
398  {
399  *a++='+';
400  *a++=Awx[++i];
401  ++i;
402  if (Awx[i]>'0' && Awx[i]<'<') *a++=Awx[i++];
403  }
404  if (Awx[i++]==' ') *a++=(CHAR)4;
405  else break;
406  }
407  *a=a[1]=NL;
408  break;
409  case 'm': // am: max # of outp recs
410  xrm=geti(3);
411  break;
412  case 'n': // an: rec # for 1st print
413  xrn=(RECNR)geti(3);
414  break;
415  case 'b': // ab: rec begin
416  getcs(3,xrb);
417  break;
418  case 's': // as: subrec start
419  getcs(3,xrs);
420  break;
421  default:
422  break;
423  }
424  break;
425 
426  case 'f': // form/page-rel. parm
427  case 's': // seitenbez.
428  switch (Awx[1])
429  {
430  case 'c': // # of 1st page
431  case 'z':
432  xfc=xfca=geti(3);
433  ln=0; // reset line ct
434  break;
435  case 'l': // fl=form length = lines per form
436  i=geti(3);
437  if (i==1) prw(xfl+1);
438  else xfl=i;
439  if (!i) // list mode
440  {
441  xfl=ML;
442  xfm=0;
443  xff=2;
444  }
445  else xfm=2; // card mode default: separate cards for vols
446  break;
447  case 'a': // continuation form string
448  getcs(3,xfa);
449  break;
450  case 'b': // fb: form break cntrl
451  getcs(3,xfb);
452  break;
453  case 'f': // ff: foot-lines
454  i=geti(3); // 0..2
455  if (i>2) prw(i);
456  else xff=i;
457  break;
458  case 'm': // fm: card mode , for xri
459  i=geti(3); // 0..2
460  if (i>2) prw(i);
461  else xfm=i;
462  break;
463  case 'n': // # forms per sheet
464  xfn=geti(3);
465  break;
466  case 's': // fs: sheet feed cntrl
467  case 'v': // fv: Seitenvorschub
468  getcs(3,xfs);
469  break;
470  default:
471  break;
472  }
473  break;
474 
475  case 'k': // kategory-related params
476  switch (Awx[1])
477  {
478  case 'b': // 1: omit cont code
479  xkb=geti(3);
480  break;
481  case 's': // kat start pos
482  xkS=geti(3);
483  break;
484  case 't': // kat end pos
485  xkT=geti(3);
486  break;
487  case 'e': // string to print at kat end
488  getcs(3,xkE);
489  break;
490  case 'h': // hierarchy separator
491  xkh=Awx[3];
492  break;
493  default:
494  break;
495  }
496  break;
497 
498  case 'i': // index related parms
499  {
500  switch (Awx[1]) // used in INDEX, PRESTO and UPDATE only
501  {
502  case '0':
503  {
504  stll=geti(3); // short title length
505  if (stll>250) stll=250;
506  break;
507  }
508  case '1':
509  getcs(3,xisep1);
510  break; // separators for 2part keys
511  case '2':
512  getcs(3,xisep2);
513  break;
514  case '3':
515  getcs(3,xisep3);
516  break;
517 
518  case '4':
519  xi4=geti(3);
520  break;
521  case '5':
522  i5=Awx[3];
523  if (Awx[4]==i5) ic=1;
524  else ic=0;
525  break; // $$030201 NEU ic
526  case '6':
527  i6=geti(3)-1;
528  break;
529  case '7':
530  {
531  i7=geti(3)-1; // i7 = SR index $$970227
532  break;
533  }
534  case 'r':
535  resl=geti(3);
536  break; // $$970219 NEU
537  case 'a':
538  ia=geti(3);
539  break; // ia = Anfangszeichen fuer Sequenzen
540  case 'b':
541  ib=geti(3);
542  break; // ib = Begrenzerzeichen fuer Seq
543 
544  case '8':
545  getcs(3,delim1);
546  break; //$$8.1.93 2 Zeilen
547  case '9':
548  getcs(3,delim2);
549  break; // Referenzzeichen fuer Index
550  case 'l':
551  {
552  keymax=geti(3)+4;
553  if (keymax<8 || keymax>251) // $$960609 i<8
554  {
555  sprintf(Aerror,uif[65],Awx);
556  keymax=251;
557  }
558  // ungueltig %s il muss >7 oder <255 sein
559  break;
560  }
561  case 'c':
562  ecod=geti(3);
563  break; // $$13.11.92 neu
564  case 'i':
565  ii=geti(3);
566  if (ii<1 || ii>125)
567  {
568  ii=1; //$$ii
569  prw(1);
570  }
571  break;
572  case 'x':
573  {
574  Awx[14]=0;
575  strcpy(ixf,Awx+3); // ix=dded : Index 3 is file AEX
576  if(!isalpha(*ixf)) strcpy(ixf,ixf+1); // quote vorne weg
577  int i=strlen(ixf);
578  if(!isalpha(ixf[i-1])) ixf[--i]=0; // quote hinten weg
579  while (i<11)ixf[i++]='d';
580  svTab['~']=62; // $$07 MultiX
581  svTab['|']=60; // sonst klappt SR nicht
582  break;
583  }
584  case ' ':
585  ptx=svTab;
586  goto INDXTBL; // $$15.3.93 neu
587  }
588  break;
589  }
590  case 'p': // define values for
591  case 'q':
592  case 'd':
593  case 'D':
594  case 'o': // editor conversion table
595  if (*Awx=='d') *Awx='p';
596  if (*Awx=='D') *Awx='q';
597  if (*Awx=='p') pix=0;
598  else pix=1;
599  ptx=ptb[pix];
600  if (*Awx=='o') ptx=etb[0]; // $$951013
601 INDXTBL: // $$15.3.93 neu
602  switch (Awx[1])
603  {
604  case 'i': // prt init
605  getcs(3,xpi);
606  break;
607  case ' ': // prt tble values : p x mmm
608  pos=3;
609  if ((i=Awx[2])=='.') i=geti(3); // p .nnn mmm
610  j=0;
611  if (Awx[pos]==' ' || Awx[pos]=='/')
612  if (Awx[pos]==' ' && (Awx[pos+1]==QT || Awx[pos+1]=='.')) ersatz(i);
613  else
614  {
615  if (Awx[pos]=='/')
616  {
617  pos+=3;
618  j=Awx[pos-2];
619  }
620  else ++pos;
621  if (Awx[pos]=='=')
622  {
623  k=geti(pos+1);
624  while (i<=j) ptx[i++]=k;
625  }
626  else
627  {
628  ptx[i++]=k=geti(pos);
629  if (*Awx=='o')
630  {
631  if (k) etb[1][k]=i-1; // Chinese!!
632  else etb[1][i-1]=0;
633  }
634  else
635  while (i<=j) ptx[i++]= ++k;
636  }
637  }
638  break;
639  case 'a': // $$030114 NEU pa=CS accent table
640  getcs(3,Aextra+8000);
641  break;
642  case 'b': // backspace codes
643  i=3;
644  j=0;
645  while (i!=0)
646  {
647  k=geti(i);
648  if (k!=-1) xpB[j++]=geti(i);
649  i=pos;
650  }
651  xpB[j]=NL;
652  break;
653  case 'n': // parm set name
654  getcs(3,xpn);
655  break;
656  case 'x': // code conv y/n
657  xpx=geti(3);
658  break;
659  }
660  break;
661 
662  case 'P': // $$030427 : Unicode codes
663  case 'Q': // store codes at ucp or ucq
664  { // Ps=nnnn size of code space. Default 10000
665  if (Awx[1]=='s')
666  {
667  if (!xuc) xuc=atoi(Awx+3);
668  break;
669  }
670  if (!ucp)
671  {
672  if (!xuc) xuc=10000;
673  ucp=uc=new CHAR[xuc];
674  if (!ucp) break;
675  }
676  k=2;
677  if (*Awx=='Q') if (!ucq)
678  {
679  *uc++=0;
680  ucq=uc;
681  }
682  /* *uc++=atoi(Awx+k); k=6;
683  *uc++=atoi(Awx+k); k=10;
684  if(uc[-2]>223) { *uc++=atoi(Awx+k); k=14; }
685  */
686  if ((int)(uc-ucp)>xuc-10)
687  {
688  sprintf(Aerror,"not enough space for P/Q data, increase Ps setting in %s\n",idp);
689  return 1;
690  }
691 
692  while (Awx[k])
693  {
694  if (Awx[k]==' ') ++k;
695  if (isdigit((char)Awx[k]))
696  {
697  *uc++=atoi(Awx+k); // nnn
698  while (isdigit((char)Awx[++k]));
699  }
700  else if (Awx[k]==34)
701  {
702  ++k; // "xyz"
703  while (Awx[k] && Awx[k]!=34) *uc++=Awx[k++];
704  if (Awx[k]==34) ++k;
705  }
706  else if (Awx[k]>0) *uc++=Awx[k++]; // letter
707  else ++k;
708  }
709  *uc++=0;
710  break;
711  }
712 
713  case '_': // replace cmds
714  case ',':
715  case '*':
716  case 'X': // external cmd: define a global repl X_abc_xyz_
717  {
718  int ks=0;
719  if (*Awx=='X')
720  {
721  ks=1;
722  strcpy(Awx,Awx+1);
723  }
724  k=*Awx;
725  if (k=='*') // $$960711 NEU : welches Zeichen ist es, , oder _ ?
726  {
727  i=1;
728  while (Awx[i]!=',' && Awx[i]!='_') ++i;
729  k=Awx[i];
730  }
731  j=strlen(Awx)+1;
732  if (j==3)
733  {
734  xrp[ks]=0; // command X_ : reset replacements
735  break;
736  }
737  i=0;
738  while (Awx[i])
739  { // Dieser backslash muss stehenbleiben!!!
740  if (Awx[i++]==92)
741  {
742  Awx[j++]=(CHAR)atoi(Awx+i);
743  while (isdigit((int)Awx[i])) ++i; // more codes?
744  }
745  else Awx[j++]=Awx[i-1];
746  }
747  Awx[j]=NL;
748  if (ks==0) UtPinst(Awx+i+1,30000+Gns*500+xrp[ks]);
749  else UtPinst(Awx+i+1,40000+Adn*100+xrp[ks]);
750  ++xrp[ks];
751  break;
752  }
753 
754  // zone cmds
755  case 'F': // foot zone
756  *xkc=NL;
757  xft= ++xkc;
758  break;
759 
760  case 'H':
761  case 'K': // head zone
762  *xkc=NL;
763  xhd= ++xkc;
764  break;
765 
766  case 'R': // $$970221 : Restriction
767  // R XXX mp "text"
768  {
769  int i=10;
770  while (!isalnum(Awx[i])) ++i;
771  sprintf(restrics+ress*6,"%c%c%.3s%c",Awx[6],atoi(Awx+7),Awx+2,0);
772  Awx[strlen(Awx)-1]=0;
773  sprintf((char *)Aw," %d : %s%c",ress+1,Awx+i,0);
774  i=UtPinst(Aw,ress+4000); // put Aw into phrase space
775  ++ress;
776  }
777  break;
778 
779  case '#': // param strings for kat, coding via ptb[0]
780  case '!': // coding via ptb[1]
781  /* syntax: #nn[f] [J] [B] [Po]
782  Kat#
783  indicator
784  Jump or subroutine
785  preproc string (incl. prefixes)
786  set of postfixes */
787  *xkc++=127; // *KAT* these are special commands
788  switch (Awx[1])
789  {
790  case '#': // ##
791  case 'L': // #L $$980131 NEU
792  if (Awx[1]=='#') *xkc++=255;
793  else *xkc++=254;
794  *xkc++=254;
795  if (*Awx=='!') *xkc++=253; // alt tble
796  break;
797  case '+': // goto
798  *xkc++=240;
799  *xkc++=Awx[2];
800  break;
801  case '<': // remove secondary rec and go to label
802  /* or switch database */
803  *xkc++=234;
804  *xkc=Awx[2]; // #< + < ^ / 0 1 2 3
805  if (*xkc==NL) Awx[3]=*xkc=' '; // no label
806  *++xkc=Awx[3];
807  if (*xkc==NL) *xkc=' '; // no label
808  ++xkc;
809  break;
810  case '-': // label
811  *xkc++=241;
812  *xkc++=Awx[2];
813  break;
814  case '(': // subroutine start
815  case ')': // end
816  // #(A translates into 239 A+128
817  *xkc++=239;
818  *xkc++=Awx[2]+128;
819  break;
820  case '>': // subrout call : #>A --> 238 A+128
821  *xkc++=238;
822  *xkc++=Awx[2]+128;
823  break;
824 
825  case 'i': // indicator actions: #ip c x..
826  // --> 237 (char)p (char)c (char)x : fix
827  // 128+(char)x : subr call
828  // or 237 (char)p (char)c 128 (char)x : jmp label
829  *xkc++=237;
830  *xkc++=geti(2); // p = Position in current kat
831  i=pos+1;
832  *xkc=Awx[i++]; // c = character to match
833  if (*xkc==NL) *xkc=' ';
834  ++xkc;
835  switch (Awx[++i]) // x = action code
836  {
837  case '+': // x = +a (its a jump label)
838  *xkc++=128;
839  *xkc++=Awx[i+1];
840  break;
841  default: // x = n or >A (its a fix or subroutine)
842  *xkc++=geti(i)+1;
843  break;
844  }
845  break;
846 
847  // NEU $$021204 : Aenderung eines Basisparam., #p<befehl>
848  case 'b': // change a base param
849  *xkc++=232;
850  strcpy(xkc,Awx+1);
851  xkc+=strlen(xkc);
852  break;
853 
854  case 't': // write text of fix unconditionally
855  *xkc++=236;
856  case 'q': // question to the user // $$930821
857  if (Awx[1]=='q') *xkc++=233;
858  case 'T': // repeat this fix# after a page switch
859  if (Awx[1]=='T') *xkc++=235;
860  i=2;
861  while (isspace(Awx[i])) ++i;
862  if (Awx[i]=='{') // } prevent matching trouble
863  {
864  *xkc++=235;
865  xkc+=(getcs(i+1,xkc));
866  *xkc++=255;
867  *xkc++=1;
868  }
869  else *xkc++=geti(i)+1;
870  break;
871 
872  case 'd': // do internal subrout: #da or #dA $$030115 NEU
873  if (Awx[2]!='t') // #dt or #dts
874  {
875  *xkc++=231;
876  *xkc++=Awx[2];
877  break;
878  }
879  // else fall thru
880  default: // normal #nnf ... (see above)
881  --xkc; // *KAT* this is a real export line
882  // __930915 :
883 
884  rc = ex_preproc(); // preprocess line beginning with #
885  break;
886  }
887  *xkc++=0; // close this cmd line off
888  break;
889 
890  case '/': // leave this out
891  rc=kmode();
892  break;
893 
894  case 't': // load X.APT into current set
895  i=1;
896  while (Awx[++i]!=' ');
897  Awx[i]=NL;
898  if (!E2Exet((char *)Awx+1,kfg,2))
899  {
900  sprintf(Aerror+strlen(Aerror),"\nin %s\n",idp);
901  return 1; // Fehler aufgetreten
902  }
903  break;
904 
905  case '?':
906  wildc_e=Awx[2];
907  break;
908 
909  case '|': // Index headline
910  case 'I': // Index Kurzname, fuer Suchbefehle
911  if (!xmod) break;
912  {
913  int y;
914  if (*Awx=='|') // z.B. |1="1 : Namen von Personen"
915  {
916  y=strlen(Awx)-1;
917  if (Awx[y]=='"') Awx[y]=0;
918  y=Awx[1]-'1';
919  if (Awx[1]=='a') y=12;
920  if (y<0 || y>12) break;
921  IndeX[y]= new char[128];
922  i=3;
923  if (Awx[i]=='"') ++i;
924  while (strchr(" :=",Awx[i]) || isdigit(Awx[i])) ++i;
925  Awx[i+127]=0; // vorher weiter oben $$021216
926  strcpy(IndeX[y],(char *)Awx+i); // z.B. IndeX[0]="Namen von Personen"
927  }
928  else // z.B. Awx= 'I PER 1 "Personenregister"' // $$960723 NEU
929  // ^^^^^^^^^^^^^^^^ = InamX
930  { // ^^^^^ = InamE
931  if (tnix==100) break;
932  if (strchr(Awx,34)) // kommt " vor?
933  {
934  y=2;
935  while (Awx[y]!=' ' || Awx[y+1]!=34) ++y;
936  Awx[y]=0; // y = Pos before "Per...
937  InamX[tnix]=new char[strlen(Awx+y+1)+1];
938  strcpy(InamX[tnix],Awx+y+2); // InamE= 'Personenregister'
939  if (InamX[tnix][strlen(InamX[tnix])-1]==34)
940  InamX[tnix][strlen(InamX[tnix])-1]=0;
941  }
942 // else InamX[tnix]=nil; anderswo
943  y=strlen(Awx)-1;
944  while (Awx[y]=='.') Awx[y--]=' '; // replace '.' by ' ' at end
945  strcpy(InamE[tnix++],Awx+2); // InamE= 'PER 1' or 'PER x1' (MultiX)
946  }
947  break;
948  }
949  case 'u': // UNICODE UTF-8 pair or triple
950  {
951  CHAR *u;
952  int c,d;
953  if (!*Aextra) u=Aextra+1; // extra: allegro.hpp
954  else u=Aextra+strlen(Aextra);
955  *Aextra=1; // to indicate that there are codings
956  // zzz yyy xxx bbb aaa
957  // yyy entfaellt wenn zzz<224
958  // xxx = 255 bei 2-Byte-Codes
959  // aaa = Akzent auf bbb, sonst a=255 oder nichts
960  if (Awx[1]!=' ') // u&# ; f. UTF8->E
961  {
962  char *t;
963  strcpy(Aw,Awx+1);
964  t=strchr(Aw,' ');
965  if (t)
966  {
967  *t=0;
968  strcpy(U1,Aw);
969  strcpy(U2,t+1);
970  }
971  else
972  {
973  strcpy(U1,Aw);
974  *U2=0;
975  }
976  break;
977  }
978  d=2;
979  if (!isdigit(Awx[d])) // u zyx ba as characters
980  {
981  c=*u++=Awx[d++];
982  *u++=Awx[d++];
983  if (c>223) *u++=Awx[d++];
984  else *u++=255;
985  ++d;
986  }
987  else // isdigit(Awx[d] u z y x b a as decimal numbers, 3digit each!
988  {
989  c=*u++=atoi(Awx+2);
990  if (c==0)
991  {
992  *Aextra=0; // u 000 : clear+replace u list
993  break;
994  }
995  *u++=atoi(Awx+6);
996  d=10;
997  if (c>223)
998  {
999  *u++=atoi(Awx+d);
1000  d+=4;
1001  }
1002  else *u++=255; // if 2byte UTF, then 3rd=255
1003  }
1004  if (!isdigit(Awx[d]))
1005  {
1006  *u++=Awx[d++];
1007  *u++=Awx[d++];
1008  }
1009  else
1010  {
1011  *u++=atoi(Awx+d);
1012  d+=4;
1013  *u++=atoi(Awx+d);
1014  }
1015  *u=0;
1016  if (u[-1]==0) u[-1]=255; // if 1byte replacement, 2nd=255
1017  }
1018  break;
1019 
1020  default: /* number? */
1021  if (isdigit(*Awx)!=0) get_z(); /* fix */
1022  break;
1023 
1024  } /* end switch */
1025  return(rc);
1026 }
1027 
1028 
1029 // Zeile beginnt mit / : bezieht sich nur auf Pauschalexport
1030 int EXET::kmode() // get kat# to be skipped
1031 {
1032  strcat(Awx," ...");
1033  strncpy((char *)x0c,(char *)Awx+1,tgl+1);
1034  x0c+=tgl+1;
1035  *x0c++=0;
1036  return(0);
1037 }
1038 
1039 // ******* Preprocessor f.d. Zeilen, die mit # beginnen
1040 // d.h. Parameterzeile #... oder !... in die interne Darstellung wandeln
1041 // Diese interne Form ist stark komprimiert! 2Byte Interne Nummern lt. CFG statt #nnn
1042 
1043 int EXET::ex_preproc() // transform an export command line : => manual 10.2.6.1
1044 /* Text der Zeile steht in Awx
1045  #kkf +#mmf PPC #kt1 Pf1 ...
1046  write it to xkc in this format:
1047  F 2-byte internal Field number (int hi/lo) *KAT*
1048  (special fields have numbers <0 )
1049  M 1-byte Multicode / hierarchy code if #0...
1050  253 if '!' instead of '#' (alternative table)
1051  252 if #^kkf was given
1052  or 251 if #_kkf was given
1053  or 250 if #kkf was given
1054  F 2-byte internal number of skip kat (hi/lo) *KAT*
1055  M mult code of skip kat
1056  or 224 '+' jump
1057  L label byte
1058  or 254
1059  254 if neither applies
1060  <PPC> chain of preproc cmds (incl. prefixes)
1061  236 f m Pf1 f m Pf2 (f=int hi/lo) *KAT*
1062  chain of postfixes
1063  0 zero
1064 */
1065 {
1066  int i=2, j=0, k=0, f;
1067  CHAR mx;
1068  int mist=0;
1069  int fm=0;
1070  mx=*Awx;
1071  if (Awx[1]=='^')
1072  {
1073  j=1;
1074  k=252;
1075  }
1076  if (Awx[1]=='_')
1077  {
1078  j=1;
1079  k=251;
1080  }
1081  if (Awx[1]=='')
1082  {
1083  j=1; // get kat from lower level
1084  k=250;
1085  }
1086  memmove(Aw,Awx+j,1500); // Awx to Aw
1087  memmove(Awx,Aw,1500); // and back; now: Aw has copy of Awx
1088  Awx[strlen(Awx)+1]=0; // $$960609 zusaetzl. Sicherheit wg. +#nn */
1089  f=kfg->KoVerify(Awx+1);
1090  if (f== -1) f=E3SpecKat(Awx);
1091  else f+=256;
1092  if (f== -1)
1093  {
1094  sprintf(Aerror,uif[65],Aw); // ungueltig: %s
1095  return(1);
1096  }
1097  else *Aerror=0; // $$971029 NEU sonst evtl. "keine gueltige Kat."
1098  /*KAT* mehrere Žnderungen: */
1099  *xkc++=f/256;
1100  *xkc++=f%256; // internal kat#
1101 
1102  // the multicode:
1103  if (f>256) *xkc++=(Aw[tgl+1])?Aw[tgl+1]:' ';
1104  else *xkc++=(Aw[3])?Aw[3]:' ';
1105 
1106 
1107  // if(f==259) xkc[-1]=Aw[2]; // #00..#06 add 2nd digit *KAT*
1108  if (mx=='!') *xkc++=253; // use alt tble for this field
1109  if (k) *xkc++=k; // #^nnf : get kat from level #00
1110  while (Aw[i] && !isspace(Aw[i])) ++i; // #_nnf : don't do that
1111  if (Aw[i]) ++i; // go for 1st space
1112  if (i>8) Aw[i]=NL; // treat rest of line as comment
1113  switch (Aw[i])
1114  {
1115  case '+': // goto label after processing this field
1116  if (Aw[++i]=='#') if (Aw[i+1]!=' ' && Aw[i+1]!=NL) goto skips;
1117  *xkc++=224;
1118  *xkc++=Aw[i];
1119  ++i;
1120  break;
1121 skips:
1122  case '#': // skip#
1123  f=kfg->KoVerify(Aw+i+1);
1124  if (f== -1) f=E3SpecKat(Aw+i);
1125  else f+=256; //$$7.4.93 *KAT*
1126  if (f== -1)
1127  {
1128  sprintf(Aerror,uif[65],Aw+i); // "ungueltig: %s"
1129  xkc-=2;
1130  return(1);
1131  }
1132  else *Aerror=0; // $$971029 NEU sonst evtl. "keine gueltige Kat."
1133  if (Aw[i+1]=='u') i+=4;
1134  else i+=(tgl+2);
1135  *xkc++=f/256;
1136  *xkc++=f%256;
1137  *xkc++=Aw[i-1]; // internal # of skip-kat
1138  if (xkc[-1]==NL) xkc[-1]=' '; // bei Sonderkat nicht richtig!
1139  break;
1140  default:
1141  *xkc++=254;
1142  *xkc++=254;
1143  break;
1144  }
1145  *Aerror=0; // falls KONFIG da was reingeschrieben hatte!
1146  /* if(isspace(Aw[i])) ++i; */
1147  if (!Aw[i])
1148  {
1149  *xkc++=236; // no preprocessing for this kat
1150  return 0;
1151  }
1152  // now build the preproc chain
1153  while (fm!=2) // evaluate the manipul commands
1154  {
1155  fm=1;
1156  mx=Aw[i];
1157  if (isdigit(mx) || mx=='>') mx='0'; // it's a number
1158  switch (mx) // eval any manipul cmds?
1159  {
1160  case 'M': // Move workstring to memory $$941116
1161  *xkc++=214;
1162  fm=0;
1163  ++i;
1164  break;
1165 
1166  case 'C': // new line
1167  *xkc++=226;
1168  fm=0;
1169  ++i;
1170  break;
1171 
1172  case 'N': // new page
1173  *xkc++=225;
1174  fm=0;
1175  ++i;
1176  break;
1177 
1178  case 'Z': // stop this line without output
1179  *xkc++=220;
1180  fm=0;
1181  ++i;
1182  break;
1183 
1184  case 'w': // take workstring as tag //*KAT*
1185  *xkc++=216;
1186  fm=0;
1187  ++i;
1188  break;
1189 
1190  case 'x': // calculations
1191  *xkc++=227;
1192  break;
1193 
1194  case 'f': // front char suppression: leading blanks and such
1195  *xkc++=228;
1196  break;
1197 
1198  case 'F': // rear char suppression: trailing blanks and such
1199  *xkc++=224;
1200  break;
1201 
1202  case 't': // trim code
1203  *xkc++=223;
1204  break;
1205 
1206  case 'y': // code or noncode, y0, y1, y2...
1207  *xkc++=221;
1208  break;
1209 
1210  case 'T': // trim code
1211  *xkc++=222;
1212  break;
1213 
1214  case 'c': // contain code
1215  *xkc++=229;
1216  break;
1217 
1218  case 'b': // begin-code
1219  *xkc++=250;
1220  break;
1221 
1222  case 'B': // begin-code
1223  *xkc++=251;
1224  break;
1225 
1226  case 'e': // end-code
1227  *xkc++=252;
1228  break;
1229 
1230  case 'E': // end-code
1231  *xkc++=253;
1232  break;
1233 
1234  case 'k': // srch key for rapid access
1235  case 'K':
1236  if (mx=='k') *xkc++=244;
1237  else *xkc++=243;
1238  break;
1239 
1240  case '|': // |i access via index i to other rec
1241  *xkc++=219;
1242  break;
1243 
1244  case '~': // ~x : delete subfield x // $$960604 NEU
1245  case 31: //  = subfield code
1246  case '$': // $ und  gleichwertig $$960214
1247  if (mx=='~') *xkc++=211;
1248  else *xkc++=218; // $$941107 2 neue Zeilen:
1249  *xkc++=Aw[++i];
1250  ++i;
1251  fm=0;
1252  break;
1253 
1254  case ',': // , or _ : local replacement /*KAT*/
1255  case '_':
1256  *xkc++=217;
1257  break;
1258 
1259  case 's': // snk : fill right end with k to fit length n
1260  *xkc++=247;
1261  case 'r': // right align within specified width, leading k's
1262  if (mx=='r') *xkc++=249;
1263  ++i;
1264  *xkc++=geti(i);
1265  i=pos;
1266  if (Aw[i]==',')
1267  {
1268  *xkc++=Aw[++i];
1269  ++i;
1270  }
1271  else *xkc++=' ';
1272  fm=0;
1273  break;
1274 
1275  case 'R': // right align in current line
1276  *xkc++=248;
1277  ++i;
1278  fm=0;
1279  break;
1280 
1281  case 'u': // umn : eliminate non-sort words and such
1282  case 'U': // everything between m and n, e.g., u[]
1283  if (mx=='u') *xkc++=246;
1284  else *xkc++=245;
1285  fm=0;
1286  ++i;
1287  if (Aw[i] && Aw[i]!=' ')
1288  {
1289  *xkc++=Aw[i++];
1290  if (Aw[i] && Aw[i]!=' ') *xkc++=Aw[i++];
1291  else *xkc++=1;
1292  }
1293  else
1294  {
1295  *xkc++=kfg->NS;
1296  if (kfg->nsm) *xkc++=kfg->NS;
1297  else *xkc++=' ';
1298  }
1299  break;
1300 
1301  case '=': // equal to earlier version?
1302  // =xy[,k] : #uxy = user variable
1303  // [+a] : k = fix#, a = label
1304  fm=0;
1305  *xkc++=242;
1306  strcat(Aw," "); // =x
1307  *xkc++=Aw[++i];
1308  *xkc++=Aw[++i];
1309  if (Aw[++i]=='+')
1310  {
1311  *xkc++=242; // label
1312  *xkc++=Aw[++i];
1313  ++i;
1314  }
1315  else
1316  {
1317  if (Aw[i]==',') fm=1; // =xy,n : get fix#
1318  else
1319  {
1320  ++i; // =xy : just store text to #uxy
1321  *xkc++=1;
1322  }
1323  }
1324  break;
1325 
1326  // $$951231 : v und V NEU :
1327  case 'v': // compare: vk,x is ax[k]<'x' ? then go on
1328  *xkc++=212;
1329  case 'V': // compare: Vk,x is ax[k]>'x' ? then go on
1330  if (mx=='V') *xkc++=213;
1331  case 'i': // indicator ik,x is ax[k]=='x' ? then continue
1332  if (mx=='i') *xkc++=231;
1333  case 'I': // indicator Ik,x is ax[k]!='x' ? then continue
1334  if (mx=='I') *xkc++=230;
1335  *xkc++=geti(++i);
1336  i=pos;
1337  if (Aw[i]==',')
1338  {
1339  *xkc++=Aw[++i];
1340  ++i;
1341  }
1342  else *xkc++=' ';
1343  if (xkc[-1]==NL) xkc[-1]=' '; // ix, xyz... (2 spaces after , !)
1344  fm=0;
1345  break;
1346  // $$931210 : naechste 3 Zeilen
1347  case 'l': // lxy : put length of workstring to #uxy
1348  *xkc++=215;
1349  case 'L': // Lxy : find label of field in CFG $$980131
1350  if (mx=='L') *xkc++=209; // and put into #uxy
1351  case 'd': // dxy : delete #uxy
1352  if (mx=='d') *xkc++=232;
1353  case 'a': // axy : affix workstring to front of #uxy
1354  if (mx=='a') *xkc++=234;
1355  case 'A': // Axy : append workstring to a user variable
1356  fm=0;
1357  if (mx=='A') *xkc++=233;
1358  strcat(Aw," "); // ax
1359  *xkc++=Aw[++i];
1360  if (mx=='l' && (Aw[i]=='>' || Aw[i]=='<')) /* $$020603 */
1361  {
1362  *xkc++=atoi(Aw+i+1);
1363  while (Aw[++i]!=' ');
1364  }
1365  else *xkc++=Aw[++i];
1366  ++i;
1367  break;
1368 
1369  case 'p': // this is redundant
1370  ++i;
1371  fm=0;
1372  break;
1373 
1374  case '\42': // "xxx" embedded prefix
1375  case '\47': // single or double quote
1376  --i;
1377  *xkc++=241;
1378  case 'm': // m"xxx" or m n (embedded prefix) for multiple fields
1379  if (mx=='m') if (Aw[i+1]=='{') goto dprf;
1380  else *xkc++=238; // }
1381  break;
1382 
1383  case 'P': // P {..} or P"xxx" or P n (embedded postfix)
1384  if (Aw[i+1]=='{') /* } */
1385  {
1386  i+=2;
1387  *xkc++=235;
1388  xkc+=(getcs(i,xkc));
1389  *xkc++=255;
1390  *xkc++=1;
1391  i=pos;
1392  fm=0;
1393  }
1394  else
1395  {
1396  *xkc++=240;
1397  }
1398  break;
1399 
1400  case 'X': // Xj : SR key (i=1..9:; $$970227
1401  *xkc++=241; // make prefix "\|9"
1402  *xkc++=255;
1403  *xkc++='\\';
1404  *xkc++='|';
1405  if (Aw[i+1]) *xkc++=Aw[++i];
1406  else *xkc++='9';
1407  *xkc++=1;
1408  fm=0;
1409  ++i;
1410  break;
1411 
1412  case 'J': // J : prefix |i from ak=nn+xi, $$051008
1413  *xkc++=208;
1414  ++i;
1415  if (!Aw[i] || Aw[i]==' ') *xkc++=1;
1416  else *xkc++=Aw[i++];
1417  fm=0;
1418  break;
1419 
1420  case '{': // control character }
1421 dprf:
1422  if (mx=='m')
1423  {
1424  *xkc++=237;
1425  ++i;
1426  }
1427  else *xkc++=239;
1428  xkc+=(getcs(++i,xkc));
1429  *xkc++=255;
1430  *xkc++=1;
1431  i=pos;
1432  fm=0;
1433  break;
1434 
1435  case TAB:
1436  case ' ':
1437  ++i;
1438  fm=0;
1439  break;
1440 
1441  case '0': // number: prefix
1442  *xkc++=241;
1443  --i;
1444  break;
1445 
1446  default:
1447  fm=2; // '#' or comment or end-of-line
1448  break;
1449  }
1450 
1451  while (fm==1) // eval manipul cmd
1452  {
1453  ++i;
1454  switch (k=Aw[i])
1455  {
1456  case QT: // result: 255 single or double quoted text 1
1457  case '\47':
1458  if (mx=='s' || mx=='r')
1459  {
1460  sprintf(Aerror,uif[52],Aw); // Fehler: %s
1461  mist=1;
1462  }
1463  *xkc++=255;
1464  ++i;
1465  while (Aw[i]!=k) *xkc++=Aw[i++];
1466  *xkc++=Aw[i++]=1;
1467  fm=0;
1468  break;
1469  case TAB:
1470  case ' ':
1471  break;
1472  default: // fix number or subrout# +1
1473  *xkc++=geti(i)+1;
1474  i=pos;
1475  fm=0;
1476  break;
1477  }
1478  }
1479  }
1480  j=i;
1481  *xkc++=236; // marks the end of preproc chain
1482  while (isspace(Aw[i])) ++i;
1483  pos=1; // to prevent flipout:
1484  while (pos!=0)
1485  { // now get the postfixes
1486  j=i;
1487  while (Aw[i]!='#' && Aw[i]!=NL) ++i;
1488  if (i>j+3 || Aw[i]==NL) pos=0;
1489  else if (Aw[i]=='#') // Aw[i]=='#' : there is a postfix
1490  {
1491  ++i;
1492  f=kfg->KoVerify(Aw+i);
1493  if (f== -1) f=E3SpecKat(Aw+i-1);
1494  else f+=256;
1495  if (f== -1) f=1000; //$$94051/* #zz means: any kat will do */
1496  *Aerror=0; // $$971029 NEU sonst evtl. "keine gueltige Kat."
1497  if (f<0) f=-f; // *KAT*
1498  *xkc++=f/256;
1499  *xkc++=f%256;
1500  *xkc++=Aw[i+tgl]; // nxt kat
1501  // $$940519 : die naechsten 2 Zeilen wg. Postfix #zz u.ae.
1502  /* $$941015 postf. verbessert
1503  i+=tgl; **KAT**
1504  if(Aw[i-1]!=' ' && Aw[i]!=' ') ++i;
1505  */
1506  if (xkc[-1]==0) xkc[-1]=' ';
1507  while (Aw[++i]!=' ');
1508 
1509  k=geti(i)+1;
1510  if (k== -1) k=1,pos=0;
1511  *xkc++=k;
1512  i=pos;
1513  }
1514  else pos=0;
1515  }
1516  return(mist);
1517 }
1518 
1519 // ***** Ersatzdarstellung speichern, Bef. p x "...."
1520 void EXET::ersatz(CHAR e) // move ersatz to phrase space
1521 {
1522  int i=pos+2, j=2;
1523  CHAR k;
1524  Aw[1]=e;
1525  switch (Awx[pos+1])
1526  {
1527  case QT: /* text-ersatz: flag 0 */
1528  while ((k=Awx[i++])!=NL && k!=QT) Aw[j++]=k;
1529  Aw[j]=NL;
1530  ptx[e]=4;
1531  break;
1532  case '.': // print-ersatz: flag 254/253
1533  getcs(i,Aw+2);
1534  ptx[e]=(pix)?7:6; // 0/1 : normal(6)/alternate(7)
1535  break;
1536  }
1537  if (!pix) j=10000;
1538  else j=20000;
1539  UtPinst(Aw+2,e+j+Gns*300);
1540  return;
1541 }
1542 
1543 // Zwischenteil speichern, Bef. nummer=....
1544 void EXET::get_z() // get 'fix' and put it to phrase space
1545 {
1546  int i=0, j=0;
1547  j=geti(0);
1548  i=pos+1; /* transform it to Aw[] */
1549  getcs(i,Aw+2);
1550  UtPinst(Aw+2,j+1000+Gns*400); // move over to phrase space: 1 -> 201 ..
1551  return ;
1552 }
1553 
1554 // Zahl einlesen
1555 int EXET::geti(int i) // get int value from Awx at pos i, set pos after int
1556 // ret: int value ; pos=0 after NL
1557 // exceptions: >A --> A+128 / :i and ;i -> 10i / 11i
1558 {
1559  int j;
1560  CHAR z[9];
1561  j=i;
1562  if (Awx[i]) if (isspace(Awx[i])) ++i;
1563  if (!Awx[i])
1564  {
1565  pos=0;
1566  return(0);
1567  }
1568  if (Awx[i]=='>') // subroutine call instead of a fix
1569  {
1570  pos=i+2;
1571  return(Awx[i+1]+128);
1572  }
1573  if (!isdigit(Awx[i]))
1574  { // $$950602: to allow |:i and |;i
1575  if (Awx[i]==':' || Awx[i]==';')
1576  {
1577  pos=i+2;
1578  return((Awx[i]-'0')*10+Awx[i+1]-'0');
1579  }
1580  pos=i+1;
1581  return Awx[i];
1582  } /* no digit: value of char */
1583  j=0;
1584  while (isdigit(Awx[i])) z[j++]=Awx[i++];
1585  /* if (Awx[i]==NL) i=0; */
1586  z[j]=NL;
1587  pos=i;
1588  return(atoi(z));
1589 }
1590 
1591 // ****** Steuerzeichenkette lesen von Pos. i in Awx, Ergebnis nach adr
1592 int EXET::getcs(int i,CHAR *adr) // get control string from Awx at pos i to adr
1593 // return length of string
1594 {
1595  int j=0;
1596  int m;
1597  CHAR cx;
1598  while (Awx[i]!=NL)
1599  {
1600  switch (m=Awx[i])
1601  {
1602  case QT: // quote string
1603  case '\47':
1604  adr[j++]=Awx[i++];
1605  while ((cx=adr[j++]=Awx[i++])!=m && cx!=NL) ;
1606  if (cx==NL)
1607  {
1608  adr[j-1]=m;
1609  adr[j]=NL;
1610  pos=i;
1611  return j;
1612  }
1613  /* factor? */
1614  if (Awx[i]=='*')
1615  {
1616  adr[j++]=127;
1617  adr[j++]=geti(++i);
1618  i=pos;
1619  }
1620  break;
1621 
1622  case 'p': // pre-/postfix# : insert this fix
1623  Awx[i]='t'; /* this line obsolete in 1990*/
1624 
1625  // control cmds:
1626  case '$': // home jmp
1627  case '%': // change xll
1628  case '&': // htab : move to this pos in same line
1629  case '#': // change xli
1630  case 'h': // hierarchy code
1631  case 's': // start point of text // $$950514 NEU
1632  case 't': // pre-/postfix# : insert this fix //obsolete in 199
1633  case 'N': // new page
1634  case 'K': // Card#
1635  case 'J': // J : |i $$051008, ak=nn+xi
1636  adr[j++]=255;
1637  adr[j++]=254;
1638  adr[j++]=Awx[i++];
1639  if (adr[j-1]!='$')
1640  { // $$051008
1641  if (adr[j-1]=='J')
1642  {
1643  m=Awx[i];
1644  if (m<'1' || m>';') m=1;
1645  else ++i;
1646  }
1647  else if (isdigit(Awx[i]))
1648  {
1649  m=1+geti(i);
1650  i=pos;
1651  }
1652  else m=1;
1653  adr[j++]=m;
1654  }
1655  else
1656  {
1657  adr[j++]=' ';
1658  if (isdigit(Awx[i])) // line jump?
1659  {
1660  m=geti(i);
1661  i=pos;
1662  if (m) while (m--) adr[j++]=13;
1663  if (!xi) xi=1; // $i won't work properly without
1664  if (Awx[i]>' ') Awx[i]='&';
1665  }
1666  }
1667  break;
1668 
1669  case TAB:
1670  case ' ': // two spaces=terminator
1671  if (isspace(Awx[++i])) Awx[i]=NL; // end of ctrl string
1672  break;
1673 
1674  case '*': // factor?
1675  adr[j++]=127;
1676  adr[j++]=geti(++i);
1677  i=pos;
1678  break;
1679  // {
1680  case '}': // code sequence end
1681  pos=++i;
1682  adr[j]=0;
1683  return j;
1684 
1685  case 'C': // carriage return
1686  adr[j++]=13;
1687  ++i;
1688  break;
1689 
1690  default: // numbers as ctrl-chars
1691  m=geti(i); // special coding for NULL: 255 255 1
1692  if (!m) m=1;
1693  else if (m>253) m-=252; // 254 : 255 255 2 255 : 255 255 3
1694  // $$931217 ++m; weil 34/39 sonst falsch rauskommen
1695  else if (m==34 || m==39) ++m; // 34/39 : 255 255 34/39
1696  else
1697  {
1698  adr[j++]=m; // normal
1699  m=0;
1700  }
1701  if (m)
1702  {
1703  adr[j++]=255;
1704  adr[j++]=255;
1705  adr[j++]=m;
1706  }
1707  i=pos;
1708  break;
1709  } // end switch
1710  } // end while
1711  adr[j]=NL;
1712  pos=i;
1713  return j;
1714 }
1715 
1716 void EXET::prw(int i) // Fehlermeldung ausgeben
1717 {
1718  sprintf(Aerror,uif[64],(char *)Awx,i); // unerlaubter Wert: '%s', es bleibt bei: %u
1719  return ;
1720 }
1721 
1722 
1723 // ************* INITIALIZATION : Parameterobjekt initialisieren
1724 
1725 void EXET::par_init() // initialize param set i (=0..3)
1726 {
1727  int j=0;// static int rep=0;
1728 // if (!rep) // this need be done only the 1st time we come here
1729  {
1730  x0 = new CHAR[256]; // rep=1;
1731  chx = new CHAR[8000];
1732 // chx=chX;
1733  strcpy(chx,"00000");
1734  chx+=5;
1735  xrK = new CHAR[4096];
1736 
1737  xk=new CHAR[kfg->parmem];
1738  while (j<256)
1739  {
1740  etb[0][j]=etb[1][j]=j; // edit table $$951011 NEW
1741  ++j;
1742  } // $$970108 NEUe Initialisierungen:
1743  j=0;
1744  while (j<13) IndeX[j++]=nil;
1745  j=0;
1746  while (j<100) InamX[j++]=nil;
1747  }
1748  j=0;
1749  xk1=xkc=xk;
1750  xk0=x0c=x0; // space for kat param strings
1751  *xkc= *x0c=NL;
1752  *xrK= *xrs= *xre= *xpi= *xrb=NL; // *xrb=255;
1753  strcpy(xle,"\r\n"); // xle+fb anders initialisiert
1754  *xkE= *xfb= *xrf= *xpB=NL;
1755  xfn=fct=xri=xi=xff=xkT=0;
1756  tcn=0L;
1757  xrm=xrp[0]=xrp[1]=ln=xkb=0;
1758  xrn=1L;
1759  xrd=xrg=xfc=xpx=1;
1760  xfl=ML;
1761  *xfs=12;
1762  xfs[1]=NL;
1763  xi4=-1;
1764  strcpy(xlb," -/");
1765  strcpy(xfa,"...");
1766  xl=56;
1767  xkS=kfg->skt;
1768  xlm=65;
1769  xl1=3;
1770  xl2=2;
1771  xkh=',';
1772  xhd=xft=(CHAR *)nil;
1773  while (j<256) ptb[0][j]=ptb[1][j]=j, ++j; //prt tble
1774 
1775  if (xmod)
1776  {
1777  while (--j>-1) svTab[j]=j; // for index only
1778  j=0;
1779  while (j<13) IndeX[j++]=nil; // Registernamen
1780  }
1781 
1782  hdl=0;
1783  ch1=ch2=(CHAR*)NULL;
1784  curr_kat=curr_head=(CHAR *)nil;
1785  return;
1786 }
1787 
1788 
1789 // AUXILIARY ROUTINES
1790 
1791 
1792 // Verwaltung der Set-Nummern, bis zu 10
1793 // Jedes EXET-Objekt erhaelt also eine Nr.
1794 
1795 int EXET::ActiveGns(void) // get a free number for this set
1796 {
1797  int i=0;
1798  while (i<10 && Pctive[i]!=0) ++i;
1799  if (i==10) return -1;
1800  Pctive[i]=1;
1801  return i; // next free number -> Gns for this object
1802 }
1803 
1804 
1805 // ************ Bereiche freigeben
1806 void EXET::destruct()
1807 {
1808  int y=0;
1809  if (xk) delete [] xk;
1810  xk=(CHAR*)NULL;
1811  if (chx)
1812  {
1813  chx-=5; // $$960222 da pointer verschoben!
1814  delete [] chx;
1815  chx=(CHAR*)NULL;
1816  }
1817  if (xrK) delete [] xrK;
1818  xrK=(CHAR*)NULL;
1819  if (x0) delete [] x0;
1820  x0=(CHAR*)NULL;
1821  if (xmod) while (y<13)
1822  {
1823  if (IndeX[y]!=nil) delete [] IndeX[y];
1824  IndeX[y]=NULL;
1825  ++y;
1826  }
1827  y=0;
1828  if (xmod) while (y<100)
1829  {
1830  if (InamX[y]!=nil) delete [] InamX[y];
1831  InamX[y]=NULL;
1832  ++y;
1833  }
1834  xmod=0;
1835  if (xuc)
1836  {
1837  delete [] ucp; // $$030430 Unicode Methode 2
1838  ucp=0;
1839  }
1840  return;
1841 }
1842 
1843 EXET::~EXET() // Destruktor $$970108 erweitert $$970312 virtual
1844 {
1845  destruct();
1846  Pctive[Gns]=0;
1847  return;
1848 }
1849 
1850 /*
1851  Copyright 2011 Universitätsbibliothek Braunschweig
1852 
1853  Licensed under the Apache License, Version 2.0 (the "License");
1854  you may not use this file except in compliance with the License.
1855  You may obtain a copy of the License at
1856 
1857  http://www.apache.org/licenses/LICENSE-2.0
1858 
1859  Unless required by applicable law or agreed to in writing, software
1860  distributed under the License is distributed on an "AS IS" BASIS,
1861  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1862  See the License for the specific language governing permissions and
1863  limitations under the License.
1864 */
1865