a99  V32.6
allegro Windows Hauptprogramm
 Alle Klassen Dateien Funktionen Variablen Typdefinitionen Aufzählungen Aufzählungswerte Makrodefinitionen
exet.cpp
gehe zur Dokumentation dieser Datei
1 // exet.cpp : Parameterdatei, Ausfuehrung
2 // 950819
3 // Copyright 2011 Universitätsbibliothek Braunschweig, more see bottom
4 
5 // Klasse EXET
6 
7 // Achtung: Parameterdatei einlesen und vorverarbeiten: in EXET2.CPP
8 // main body of export routines
9 // containing all of the formatting routines
10 
11 #include "allegro.hpp" // allg. Variablen
12 #include "konfig.hpp" // Klasse KONFIG
13 
14 #include "exet.hpp" // Variablen (Attribute), Initialis. in exet2.cpp
15 #include "abase.hpp" // Klasse ABASE
16 
17 #define QT '"' // quote
18 
19 // Hilfsvar.
20 char rG[3]="|1"; // $$051008 neu fuer ak=nn+xi, d.h. Schl. soll in Reg. i
21 CHAR gx[32000]; // $$051009 $$060405 doppelt, Hilfsbereich f. Aufbereitung
22 CHAR AExtra[8000]; // Hilfsvar fuer export (nur EXET.CPP)
23 
24 // CHAR chX[1000]; //test. Mist! chx ist in exet2.cpp
25 
26 // METHODS (von aussen nutzbar)
27 
28 // ****** Konstruktor ist in EXET2.CPP
29 
30 // ****** HauptMethode: Einen Satz exportieren gemaess der .APR
31 // DOS: %% cmd_dx()
32 // Exp() : Datensatz ausgeben mit diesen Parametern
33 
34 // Sonstige von aussen nutzbare Methoden:
35 // ExOutf() : Funktion fuer das Ausgeben eines Zeichens, hiermit von aussen vorgebbar
36 // ExRcode() : Zeichenfolge umcodieren mit den p/q-Befehlen dieses Objekts
37 // ExFindKat() : Adresse eines Datenfelds finden
38 // pghf() : Kopf-/Fussabschnitt abarbeiten
39 
40 // Der Export wird zunaechst zweilenweise in den Array ct[][] geschrieben,
41 // d.h. ct[0] ist die erste Zeile usw.
42 
43 
44 int EXET::Exp(RECORD *record,int mn,CHAR *labl)
45 // mn = max# of outp recs, default=0=no max (alle ak-Bef. abarbeiten)
46 // begin at labl, default=NULL
47 // *labl = "1": Fuss, "2": Kopf, "x": #-x, 255: Nur Variablen setzen
48 // return 0 / 1 : ohne/mit Erfolg
49 {
50  int k=0;
51  int xy;
52  rec=record;
53  cri=rec->cri;
54  gri=rec->gri;
55  ga=rec->ga;
56  gi=rec->gi;
57  gend=rec->gend;
58  xrn=rec->rNr;
59  Adn=rec->Adn; // logical nr of database to which rec belongs
60  xrk=xrK-2;
61  rkflag=1;
62  rkp1=rkp2=hdc=0; // reset pos in xrk
63  if (!mn) rmx=xrm;
64  else rmx=mn;
65  if (!rmx) rmx=32000; // no limit
66  prfl=1;
67  crix=cri;
68  if (prfl)
69  {
70 // if (parflg<1) { err(uif[89]); return 0;} // keine Parameter
71  xpy=xpx;
72  xy=xpy;
73  xks=xkS;
74  xkt=xkT;
75  xke=xkE;
76  xpb=xpB;
77  xbl=strlen((char *)xpB);
78 // if(stream!=stdout)
79 // $$971201 : wegen Kopf/Fusszeilen
80  if (labl && *labl==255) return 1; // $$030202 NEU sonst replace()!!
81  if (labl && *labl==1)
82  {
83  int i=xff; // fuss
84  xff=2;
85  pghf(0);
86  xff=i;
87  return 1;
88  }
89  if (labl && *labl==2)
90  {
91  int i=xff; // Kopf
92  xff=2;
93  pghf(1);
94  xff=i;
95  return 1;
96  }
97 // xmod==1 : Indexparam.
98  if (xmod!=1 && !labl) // wenn nur Label abzuarbeiten, dann kein Kopf!
99  {
100  if (!tcn)
101  if (!xfc) pghf(1); // file header, else card header
102  else if (!xri && xfl && !ln) pghf(1);
103  }
104  ++tcn; // ++ to prevent a second pghf
105  s_preex(); // external addition
106  if (xrp[0]) replace(1,0);
107  cri_base=cri;
108  if (gri) if ((curr_level=ga[cri][1])!=1)
109  while (cri_base && ga[--cri_base][1]!=1);
110  if (prfl==1)
111  do // now there we go with all those headings
112  {
113  rmc=0;
114  curr_head=ch2=(CHAR *)nil;
115  xk1=xk; // $$940824 curr_head
116  c_init(0);
117  crc=lop=0;
118  if (labl!=0)
119  {
120 // 5 Stellen mit "!=241" : zusaetzlich *xk1==127
121  while ((xk1[1]!=241 || xk1[2]!=*labl || *xk1!=127) && *xk1!=NL)
122  {
123  while (*xk1++!=0) ;
124  }
125  if (*xk1==127) xk1+=4;
126  else return 0; // $$11.11.92 label not found
127  if (ch1) curr_head=ch1;
128  else curr_head=(CHAR *)nil;
129  if (xmod!=1) pghf(1);
130  format(1);
131  if (xmod!=1) pghf(0);
132  if (*labl=='#') rmc=1000; // wg. replace()/return
133  break; // out of do-loop
134  }
135  ch1=0; // nxt line if(!..
136 
137  k=h_test(); // k==0: no heading
138  if (ch1==0 && gi[cri]==1) ch1=ga[cri]+2; // #u1 nehmen, wenn kein ch1
139  if (k) do
140  {//rc
141  format(0);
142  k=(h_test() && (rmc<rmx) ) ;
143  // if(rc && k) if(stop()) break;
144  }
145  while (k) ;
146  if (!rmc && xrd) // we had no output but we need one
147  {
148  format(1);
149  }
150  }
151  while (rmx>1 && crif()!=gri/* && !stop()*/); // rmx=1:
152  else
153  {
154 // if(isupper(k)) stream=stdout; else stream=expf;
155  if (k=='f' || k=='F') pghf(0);
156  else pghf(1);
157 // if(stream==stdout) { cho(uif[309]); inkey(); } // " ... beliebige Taste"
158  }
159 // XXX noch noetig?
160 // if(xrp[0] && rmc!=1000) restore(); // undo the replacements
161  }
162  cri=crix;
163  xpy=xy; // restore
164  main_ixl(rec->Adn,rec,0,-4); // remove all secondary recs
165  s_postex();
166  return rmc;
167 }
168 // ENDE Exp()
169 
170 
171 // Die eigentliche Ausgabefunktion liegt aussen, hier wird ihre Adresse uebergeben
172 void EXET::ExOutf(int (*outChr)(int))
173 {
174  outChar=outChr; // outChr soll die Char-Ausgabefunktion sein
175  return;
176 }
177 
178 // ********** Den Satz aufbereiten
179 
180 int EXET::format(int fmd) // format current rec
181 {
182  int rc; // fmd=1 : format even if no heading (ch1==0)
183  CHAR *xkk; // save xk1 here (Startpkt d. internen Befehlsliste)
184 // stopc=1;
185  if ((ch1==0 || *ch1==NL || ch2==0) && !fmd) return 0;
186  xkk=xk1;
187  ftf=hdl=hdc=crl=crc=0;
188  if (!xmod)
189  {
190  c_init(0);
191  c_init2();
192  }
193  pfl=0;
194  if (xri && Apgnb!='1') // no page head in PRESTO display
195  {
196  pghf(0);
197  pghf(1);
198  }
199 // if(!ps) xfca=xfc[0]; XXX xfca wichtig?
200  pfl=1;
201  // cnpos=NULL;
202  rc=form_pr(1,0); // eigentliche Ausfuehrung
203 // if(*ct[0]) // nur zaehlen, wenn was rauskam
204 // if(crl+crc)
205  rmc+=rc;
206  prfl=0;
207  xk1=xkk; // restore it
208  return rc;
209 }
210 
211 int EXET::crif() // set cri to nxt relevant rec (falls mehrere Saetze im Arb.sp., z.B. Hierarchie)
212 {
213  ++cri;
214  while (*ga[cri]!=RS && cri<gri) ++cri;
215  if (cri>=gri) return gri;
216  if (ga[cri][1]>curr_level && xrg!=1) return cri;
217  return gri;
218 }
219 
220 
221 // ********** naechstes Feld zum aktuellen ak-Befehl suchen
222 int EXET::h_test(void) // move nxt kat#s from xrk to ck1, ck2, ch1, ch2
223 // #d40./20 85+s 27 272 41.+h 3.."; "+w or such
224 {
225  static CHAR *ch, *a, *b, *c;
226  static int spf, k; // split flag
227  ami=ami0=0;
228  if (!rkp1) spf=0;
229 h_t1:
230  if (!spf)
231  {
232  xk1=xk;
233  if (!rkflag)
234  {
235  rkp1=0; // Pos. in xrk = ak-Befehle
236  rkflag=1;
237  return(0);
238  }
239  if (!rkp1) rkp1=2; // rkp1=pos of nxt kat or 0
240  else if (rkflag==1) rkp1=rkp2;
241  rkp2=getk(rkp1); // Hilfsfktn zur Suche nach d. naechsten Feld
242  if (!rkp2)
243  {
244  rkp1=0;
245  rkflag=1;
246  return(0);
247  }
248  if (ch1==0)
249  {
250  rkflag=1;
251  goto h_t1;
252  }
253  /*KAT*
254  if (xrk[rkp1+4]=='/' || xrk[rkp1+4]==QT) ++rkp1; // ak=200x/40+M **
255  if (xrk[rkp1+2]=='/' || xrk[rkp1+2]==QT) --rkp1; // ak=20/40+M **
256  */
257  c=chx+kfg->skt;
258  // $$931109 Korrekturen
259  if (xrk[rkp1+3]=='/') // ak=20x/40+M 2part headg
260  {
261  ck2=xrk[rkp1+4]*256 + xrk[rkp1+5];
262  if (ck2>0) ck2-=256;
263  cc2=xrk[rkp1+6];
264  if (!cc2 || cc2=='+') cc2=' ';
265  if (ck2!=-1) ch2=ExFindKat(ck2,cc2,cri);
266  if (ch2==0 && gi[cri+1]==2) ch2=ga[cri+1]; // #u2 exists
267  // if(ch2==NULL) return 0; // 2nd part does not exist
268  }
269  // $$931115 Korrekturen
270  else if (xrk[rkp1+3]==QT) // split kat heading
271  {
272  if (xrk[rkp1+4]=='\\')
273  {
274  ++rkp1;
275  spf=3;
276  }
277  else spf=1;
278  ch=xrk+rkp1+4;
279  b=ch1+kfg->skt;
280  k=rkp1+5;
281  while (xrk[k++]!=QT) ;
282  if (xrk[k]=='/')
283  {
284  ch2=0;
285  ck2=xrk[k+1]*256+xrk[k+2];
286  if (ck2>0) ck2-=256;
287  if ((cc2=xrk[k+3])==NL || cc2=='+') cc2=' ';
288  if (ck2!=-1) ch2=ExFindKat(ck2,cc2,cri);
289  }
290  }
291  else if (xrk[rkp1+tgl+1]==QT) // split kat heading
292  {
293  if (xrk[rkp1+tgl+2]=='\\')
294  {
295  ++rkp1;
296  spf=3;
297  }
298  else spf=1;
299  ch=xrk+rkp1+tgl+2;
300  b=ch1+kfg->skt;
301  k=rkp1+tgl+3;
302  while (xrk[k++]!=QT) ;
303  if (xrk[k]=='/')
304  {
305  ch2=0;
306  ck2=xrk[k+1]*256+xrk[k+2];
307  if (ck2>0) ck2-=256;
308  if ((cc2=xrk[k+3])==NL || cc2=='+') cc2=' ';
309  if (ck2!=-1) ch2=ExFindKat(ck2,cc2,cri);
310  }
311  }
312  // $$931109 bis hierhin
313  } // now, spf might have been changed
314  if (spf) // split wanted?
315  {
316  if (spf>1)
317  {
318  b=fndstr(b,ch,1,QT); // look for nxt split
319  }
320  if (spf==3) if (!b)
321  {
322  spf=0;
323  rkp1=rkp2;
324  goto h_t1;
325  }
326  else spf=2;
327  else spf=2;
328  k=0;
329  a=0;
330  if (b) a=fndstr(b,ch,0,QT); // look for split
331  if (a==0)
332  {
333  spf=0;
334  rkp1=rkp2;
335  }
336  while (a!= b+k && (c[k]=b[k])!=NL && k<218) ++k; // warum <218??? mehr geht nicht, obwohl chx 8K gross
337  c[k]=NL;
338 // if(k>200) printf("%ld/%ld--%s\n",c,chx,chx); //test
339 
340  ch1=chx;
341  }
342  return(1);
343 } // ENDE h_test()
344 
345 // Hilfsfunktion f. Suche nach dem naechsten Feld zur ak
346 int EXET::getk(int i) // get addr of nxt kat to ch1 + get label
347 // return 0 if none, i=pos to look nxt
348 { // *KAT* neu: '' als Delimiter, vorher ' '
349  static int kmi=0; // kat modus indic: 0: #nnf 1: #n.. 2: #nn.
350  static int kt0; // position of kat #00
351  static int k, k0;
352  static short ckk;
353  static CHAR kc, l;
354  static CHAR *xkk; // begin of kat list for this heading
355  if (!rkp2) kmi=0;
356  if (xrk[i]==NL) return(0); // last ak was done
357  if (!kmi) // this is a new ak command
358  {
359  k=-1; // label must be looked for
360  k0=i;
361  ck2=-1;
362  ch2=(CHAR *)nil;
363  kt0=cri-1;
364  while (gi[++kt0]<3) ; // put kt0 on #00
365  /*KAT*/
366  if (xrk[i]>' ' && xrk[i]<127 /* && xrk[i+tgl-1]=='.'*/)
367  {
368  kmi=1; /* 4.. */
369  kc=xrk[i];
370  }
371  else if (xrk[i+2]=='.') /*KAT*/
372  {
373  kmi=2;
374  ck1=ckk=(short)xrk[i]*256+(short)xrk[i+1];
375  if (ck1>32767) ck1=-ck1; // NEU
376  if (ck1>0)
377  {
378  ck1-=256;
379  ckk-=256;
380  }
381  // #40.
382  }
383  else kmi=0;
384  }
385  // else xk1=xkk;
386  switch (kmi)
387  {
388  case 0: // 40a
389  ck1=(short)xrk[i]*256+(short)xrk[i+1];
390  if (ck1>32767) ck1=-ck1;
391  if (ck1>0) ck1-=256;
392  i+=2;
393  cc1=xrk[i];
394  if (!cc1)
395  {
396  cc1=' ';
397  --i;
398  }
399  if (cc1=='/' || cc1==QT || cc1=='+') cc1=' ';
400  ch1=ExFindKat(ck1,cc1,cri);
401  break;
402  case 1: // 4.. ??? but only digits allowed behind 4 ???
403  {
404  int p=1; // ak=n.. or editor cmd #dnnn+M
405  int j=1;
406  while (!strchr("+/.\042\004 ",xrk[i+j])) ++j;
407  kmi=0;
408  if (kt0==cri) p=3;
409  if (kt0>cri && *ga[kt0]==RS) ch1=0;
410  else while (kt0<gri)
411  { // for speed, we check the 1st char before checking the string
412  // if(ga[kt0][p]==xrk[i]
413  if (!strncmp(ga[kt0]+p,xrk+i,j)) kmi=1;
414  // if(ga[kt0++][p+1]==kc) kmi=1; /*KAT*/
415  ++kt0;
416  if (kmi || *ga[kt0]==RS) break;
417  p=1;
418  }
419  if (kmi) ch1=ga[kt0-1]+p-1;
420  else ch1=0;
421  }
422  break;
423  case 2: // 40.
424  if (kt0>cri && *ga[kt0]==RS) ch1=0;
425  else while (gi[kt0]<ckk && kt0<gri)
426  {
427  ++kt0;
428  if (*ga[kt0]==RS)
429  {
430  --kt0;
431  break;
432  }
433  }
434  // $$931220 : kt0==gri ergaenzt, sonst (selten) falsche Eintraege moeglich
435  if (gi[kt0]!=ckk || kt0==gri)
436  {
437  kmi=0;
438  ch1=0;
439  }
440  else ch1=ga[kt0];
441  if (*ga[kt0]==RS && ch1!=0) ch1+=2;
442  ++kt0;
443  break;
444  }
445  if (ch1) curr_head=ch1;
446  else curr_head=(CHAR *)nil; // $$940824
447  strncpy((char *)chx,(char *)curr_head,kfg->skt);
448  if (k==-1) // label must be looked for
449  {
450  k=k0+3;
451  while (xrk[k]!='' && xrk[k]!=NL) ++k;
452 
453  if (ch1 && (xrk[k-2]=='+' || xrk[k-3]=='+')) // goto label
454  /* if(l==xrk[k-1]) xk1=xkk; * same label! *
455  else */
456  {
457  if (xrk[k-3]=='+') // $$051008 : ak=nn+xi, Schl. soll in Reg. i
458  {
459  l=xrk[k-2];
460  rG[1]=xrk[k-1];
461  }
462  else
463  {
464  l=xrk[k-1]; // the label
465  rG[1]=0;
466  }
467 
468  while ((xk1[1]!=241 || xk1[2]!=l || *xk1!=127) && *xk1!=NL) while (*xk1++!=0) ;/*KAT*/
469  if (*xk1==127) xk1+=4;
470  else return 0; // $$11.11.92 label not found /*KAT*/
471  }
472  xkk=xk1;
473  // while(xrk[k]=='') // $$991123 sonst probl. bei mehr als 768 Kat.
474  ++k;
475  }
476  else xk1=xkk;
477  if (!kmi) return(k);
478  else return(i);
479 } // ENDE getk()
480 
481 // *********** Hauptfunktion zum Formatieren, d.h. Abarb. d. Param.
482 // Rekursiv f. Unterprogramme des Typs >x
483 
484 int EXET::form_pr(int hif, CHAR sub) // main routine for form-print
485 // 1:with hierarchy 0:without
486 // not0:called as subrout, 0: as main
487 { // recursively callable, therefore no statics
488  unsigned int i, i0,m, cix, ckn;
489  int cri1, cri2, cri3;
490  short kn, cu;
491  CHAR *cn, *cn0, ccn, ccu, cu1, cu2;
492  int p;
493  int postfi=0;
494  int repflg=0;
495  int subroutflg;
496  CHAR prefs[10];
497  CHAR *postf;
498  postf=(CHAR *)"\0";
499  postfix0=1;
500  postfix1=0; // $$951008: init was forgotten!!
501  cri3=cri2=cri; // from here we go
502  if (!ch1 && cri==gri) return 0; // Vorsichtsmassnahme
503  if (!sub)
504  {
505  if (!xmod) main_ixl(rec->Adn,rec, 0,-5);
506  } // initialize retr.stack
507  /* do * base is cri3 *
508  { */
509  if (!sub) cnr=ami=ami0=1; // card#
510  // ami=1: analyse cri, if it is a volume
511  cri=cri1=cri0=cri2;
512  i=cri+1;
513  while ((int)i<gri && *ga[i]!=RS) ++i; //$$990207 umgestellt
514  if ((int)i<gri && *(ga[i]+1)>*(ga[cri3]+1)) // lower level
515  cri2=i;
516  else
517  {
518  cri2=0;
519  if (!sub) cnr=0;
520  }
521  if (!ftf && !sub)
522  {
523  if (*xrb==NL) pr_cso(xrs); // rec begin
524  else pr_cso(xrb);
525  }
526 // Hierarchieschleife
527  do // print the whole hierarchy, down from cri
528  {
529  cri0=cri1;
530  i=cri0+1;
531  while (*ga[i]!=RS && (int)i<gri) ++i; //$$8.1.93 < for !=
532  if ((int)i<gri && *(ga[i]+1)>*(ga[cri3]+1)) // we're on a lower level
533  cri1=i;
534  else cri1=0;
535  if (!sub)
536  {
537  postfi=0; // flag is 1 after 1st field
538  xll=xl;
539  xli=xi;
540  if (!ftf)
541  {
542  if (/*stream!=stdin &&*/ (xri!=1 || cri0==cri3))
543  {
544  lop=0;
545  c_init(hdl);
546  }
547  if (xri!=1 || cri0==cri3)
548  {
549  crl=lap=hdl;
550  crc=0;
551  }
552  if (hdl && xhd==(CHAR *)nil && xri==2) cont_card(); /* $$15.7.93 aktiviert*/
553  if (cri0>cri3)
554  { /* why this??
555  if(xri==1 && crl>=xfl-3) nxtlin(),nxtlin(),nxtlin();
556  */
557  pr_cs(xrs); // subrec start
558  ami0=0;
559  }
560  }
561  }
562  i=0; // now the hard work:
563  while (xk1[i])
564  {
565  // nxt kat
566  i0=i;
567  kn=(xk1[i])*256+xk1[i+1];
568  i+=2;
569  ccn=xk1[i++];// get kat# + code /*KAT*/
570  // if nxt byt==253: alt tble for this
571  cix=cri0;
572  ami=ami0=pix=0;
573  if (xk1[i]>249)
574  {
575  if (xk1[i]==253)
576  {
577  pix=1;
578  ++i;
579  }
580  if (xk1[i]==252)
581  {
582  cix=cri3;
583  ++i;
584  while (ga[cix][1]!=1 && cix>0) --cix;
585  }
586  if (xk1[i]==251)
587  {
588  ami=0;
589  ++i;
590  }
591  if (xk1[i]==250)
592  {
593  ami=2;
594  ++i;
595  }
596  }
597  ptx=ptb[pix];
598  if (pix) utx=ucq;
599  else utx=ucp;
600  if (kn/256==127) /*KAT*/ // special commands
601  {
602  switch (kn%256) /*KAT*/
603  {
604  case 255: /* ## was given */
605  case 254: /* #L : all fields with labels $$980131 NEU*/
606  pos=i;
607  ++i; /* $$941213 : [3] statt [2] */
608  if (postfi) if (*postf) pr_fix(postf[3]);
609  else pr_cs(xke);
610  if (kn%256==255) kat_pr(7);
611  else kat_pr(15);
612  postfi=0; /* no postfix after this */
613  break;
614  case 234: /* #<+M : remove secondary rec and go to label #-M */
615  /* set cri to begin and gri to end of current rec */
616  /* #< : continue on nxt line
617  #<< : go back to first rec but leave stack in place
618  #<^ : restore previously unloaded sec rec
619  #</ : unload whole stack
620  #<0 : switch to nxt database 0->1->2->3->0
621  #<i : switch to database i
622  */
623  switch (ccn)
624  {
625  case '<':
626  m=main_ixl(rec->Adn,rec, 0,-2); /* #<< */
627  break;
628  case '^':
629  m=main_ixl(rec->Adn,rec, 0,-3); /* #<^ */
630  break;
631  case '/':
632  m=main_ixl(rec->Adn,rec, 0,-4); /* #</ */
633  break;
634  case '0':
635  case '1':
636  case '2':
637  case '3':
638  m=main_ixl(rec->Adn,rec, 0,200+ccn-'0');
639  break;
640  /* $$931022 : d , u , U neu: */
641  case 'd': /* #<d 1 step down in the hierarchic rec */
642  m=main_ixl(rec->Adn,rec, 0,-6);
643  break;
644  case 'u': /* #<u 1 step up in the hierarchic rec */
645  m=main_ixl(rec->Adn,rec, 0,-7);
646  break;
647  case 'U': /* #<U : back to top level */
648  while (ga[cri][1]!=1) --cri; /*$$950529*/
649  rec->cri=cri; // $$000109 NEU
650  /* cri=crix; */
651  m=1;
652  break;
653  default:
654  m=main_ixl(rec->Adn,rec, 0,-1); /* #< */
655  } // $$031204 NEU cri=... und gend=...
656  cri=cix=cri0=rec->cri; /* maybe it had been changed */
657  gri=rec->gri;
658  gend=rec->gend;
659  ccn=xk1[i++];
660  if (ccn==' ' || !m)
661  {
662  ++i; /* no label given, continue */
663  break;
664  }
665  /* success, and there was a label, then continue like #+M */
666  case 240: /* + goto label */
667  i=0;
668  if (ccn=='-')
669  {
670  ch1=0; /* !!! CANCEL OUTPUT at +- !!! */
671  return 0;
672  }
673  if (ccn=='#')
674  {
675  xk1=(CHAR *)nil;
676  break;
677  }
678  xk1=xk; /* reset ptr to beginning of list and srch from there */
679  while ((xk1[i+1]!=241 || xk1[i+2]!=ccn) && xk1[i]!=NL) /*KAT*/
680  while (xk1[i++]!=0) ;
681  if (xk1[i]!=NL) i+=4; /*KAT*/
682  break;
683  case 241: /* -L : this is a label, skip it */
684  case 239: /* (L : a subrout label, skip it and walk thru */
685  ++i;
686  break;
687  case 238: /* >L : a subrout call! */
688  cix0=cix;
689  subroutine(ccn);
690  postfi=0; /* invalidate postfix for nxt kat */
691  ++i;
692  break;
693  case 237: /* indicator action: 237 position char action */
694  cn=curr_kat;
695  if (cn[ccn]!=xk1[i++])
696  {
697  while (xk1[i++]!=0) ; /* no action */
698  break;
699  }
700  switch (xk1[i++])
701  {
702  case 128: /* goto label */
703  ccn=xk1[i];
704  if (ccn=='-')
705  {
706  ch1=0; /* !!! CANCEL OUTPUT at +- !!! */
707  return 0;
708  }
709  i=0;
710  if (ccn=='#')
711  {
712  xk1=(CHAR *)nil;
713  break;
714  }
715  xk1=xk;
716  while ((xk1[i+1]!=241 || xk1[i+2]!=ccn || xk1[i]!=127) && xk1[i]!=NL) /*KAT*/
717  while (xk1[i++]!=0) ;
718  if (xk1[i]==127) i+=4; /*KAT*/
719  break;
720  default: /* print a fix or do a subroutine */
721  pr_fix(xk1[i-1]);
722  ++i;
723  break;
724  }
725  break;
726  // Steuerbefehl #t{ ... } ausgeben
727  case 236: /* #t : unconditional output of a fix text */
728  /* $$941203 2 neue Zeilen: anhaengendes Postfix VOR #t ausfuehren */
729  /* $$941213 [3] statt [2] */
730  if (postfi) if (*postf) pr_fix(postf[3]);
731  else pr_cs(xke);
732  postfi=0; /* no postfix after this */
733  if (ccn==235)
734  {
735  pr_cs(xk1+i);
736  i+=strlen(xk1+i);
737  }
738  else pr_fix(ccn);
739  ++i;
740  break;
741  case 235: /* #T : repeat this fix# after a page feed */
742 // if(stream!=stdout)
743  {
744  ct[crl][crc]=255; // insert this into the text stream
745  ct[crl][crc+1]=252;
746  ct[crl][crc+2]=ccn;
747  cp[crl][crc+1]=cp[crl][crc+2]=cp[crl][crc+3]=cp[crl][crc];
748  crc+=3;
749  }
750  ++i;
751  break;
752  case 232: /* #b<basisbefehl> NEU $$021204 */
753  {
754  strcpy(Awx,xk1+i);
755  pr_par();
756  i+=strlen(xk1+i);
757  ++i;
758  /* womoegl. einer der folgenden werte veraendert: */
759  xll=xl;
760  xli=xi;
761  xks=xkS;
762  xkt=xkT;
763  xke=xkE;
764  xpb=xpB;
765  xbl=strlen((char *)xpB);
766  break;
767  }
768  case 231: /* #da , #dA , #dv : accent exchange $$030115 */
769  {
770  char d=xk1[i-1];
771  if (d=='V' || d=='U') /* #dv : v-sequenzen ersetzung */
772  {
773  int j=cri+1;
774  CHAR *gr;
775  while (j<gri && *ga[j+1]!=RS)
776  {
777  strcpy(fend+1,ga[j]+1);
778  if (d=='V') rcd=2;
779  else rcd=5; // #dU : UTF->Entitaet $$090319
780  gr=ExRcode(fend+1);
781  if (*gr==RS) gr+=2;
782  rec->Ins(gr);
783  ++j;
784  }
785  d='a';
786  }
787  else // #da / #dA Diakritika vertauschen
788  // a : hinter, A : vor den Buchstaben
789  {
790  extern void UtAccent(char *,char *,int);
791  UtAccent((char *)ga[cri],(char *)gend,d-'A');
792 // Hintergrund nur, wenn es keine Nachladung ist (dann cri==0)
793  if (!cri) UtAccent((char *)fa[0],(char *)fend,d-'A');
794  }
795  ++i;
796  }
797  break;
798  }
799  }
800  else /*KAT*/
801  { /* normal: kn/ccn=next field tag */
802  if (kn>0) kn-=256; /*KAT*/
803  subroutflg=0;
804  /*KAT*/
805  cu=xk1[i++]; /* conditional jump */
806  if (cu!=254 && cu!=224)
807  {
808  cu1=(CHAR)cu; // cu=cu*256+xk1[i++]; /*KAT*/
809  cu2=xk1[i++];
810  }
811  ccu=xk1[i++]; /* skip-kat# + code */
812  pos=i;
813  cn=(CHAR *)nil;
814  prefix0=0;
815  if (repflg) /* we have a ++ command */
816  { /* $$941012 ckn */
817  if (gi[++ckn]==kn)
818  {
819  ccn=ga[ckn][tgl+1]; /*KAT*/
820  cn=pre_chk(cn0=ga[ckn],&i,repflg,prefs);
821  }
822  else repflg=0;
823  }
824  else
825  {
826  if ((cn0=ExFindKat(kn,ccn,cix))!=0)
827  cn=pre_chk(cn0,&i,repflg,prefs);
828 // if(!repflg && !sub) ckn=curr_kn;
829  if (!repflg) ckn=curr_kn; // $$950512 ckn
830  }
831  if (!cn || *cn!=NL) /* SUNC cannot eval *cn if cn==NULL ! */
832  {
833  cix0=cix; /* save this for subrout */
834  /* cix0=cri; */ /* save this for subrout */
835  i=pos;
836  while (xk1[i]!=236) ++i;
837  m=0; /* postfix handling */
838  if (postfi)
839  {
840  if (*postf==0) PR_CS(); /* if no postfixes given */
841  else
842  {
843  while ((p=postf[m])!=0)
844  {
845  p=(p-1)*256+postf[m+1]; /* Žnderungen wg *KAT*/
846  if (kn>p) m+=4;
847  else if (kn==p && ccn>postf[m+2]) m+=4;
848  else
849  {
850  pr_fix(postf[m+3]);
851  break;
852  }
853  }
854  if (p==0) /* if (kn<230) PR_CS(); // default **
855  else */ pr_fix(postf[m-1]); /* spec kat */
856  }
857  }
858  if (!sub) curr_kat=cn0;
859  /* prefix handling */
860  m=0;
861  while (prefs[m]) subroutflg+=pr_fix(prefs[m++]);
862  if (!subroutflg) /* 0:normal prefix , 1: subroutine */
863  {
864  if (prefix0) pr_cs(prefix0);
865  /* don't print text if prefix was a subroutine */
866  if (cn) cpr(cn,0); /* most important function */ /*$$950502 ,1 */
867  if (postfix0!=1)
868  {
869  pr_fix(postfix0);
870  postfix0=1;
871  }
872  if (postfix1)
873  {
874  pr_cs(postfix1);
875  postfix1=0;
876  }
877  }
878  postf=(CHAR *)xk1+i+1; /* addr of postf string */
879  postfi=1; /* to be evaluated before nxt field */
880  }
881  else cu=254;
882  while (xk1[i++]!=0) ; /* goto nxt field */
883  if (cu!=254)
884  {
885  if (cu==224) /* +goto */
886  {
887  if (ccu=='+')
888  {
889  i=i0; /* repetition of same kat */
890  repflg=1;
891  }
892  else /* normal conditional jump */
893  {
894  if (ccu=='-') return 0; /* +- means CANCEL */
895  i=0;
896  if (ccu=='#')
897  {
898  xk1=(CHAR *)nil;
899  break;
900  }
901  xk1=xk; /* reset ptr to beginning of list and srch from there */
902  while ((xk1[i+1]!=241 || xk1[i+2]!=ccu || xk1[i]!=127) && xk1[i]!=NL)
903  /*KAT*/
904  while (xk1[i++]!=0) ;
905  if (xk1[i]==127) i+=4;
906  }
907  }
908  else /* +#mm (skip to #mm) */
909  {
910 // while ((cu!=(short)xk1[i]*256+xk1[i+1] || ccu!=xk1[i+2]) && xk1[i]!=NL)
911  while ((cu1!=xk1[i] || cu2!=xk1[i+1] || ccu!=xk1[i+2]) && xk1[i]!=NL)
912  while (xk1[i++]!=NL) ;
913  }
914  }
915  } /* end default */
916  if (sub==xk1[i+2] && xk1[i+1]==239) return 1; /* end of subroutine *//*KAT*/
917 // if(!stopc) return 0;
918  } /* end while - Ende hard work */
919 
920  if (postfi) // Postfix noch zu erledigen?
921  {
922  if (postfix0!=1)
923  {
924  pr_fix(postfix0);
925  postfix0=1;
926  }
927  if (!*postf) PR_CS();
928  else
929  {
930  while ((p=*postf)!=0)
931  {
932  postf+=4;
933  }
934  pr_fix(postf[-1]); /* spec kat */
935  }
936  }
937  if (pfl)
938  {
939  if (!ftf) /* normal card mode */
940  {
941  if (xri!=1)
942  { /* cont_card(); */
943  /* folgende Zeile wg. PA.APR bei langen Aufn. */
944  if (xll>MC && !xmod)
945  {
946  ct[crl][crc]=NL;
947  pr_ct1(0);
948  crl=crc=0;
949  }
950  else if (!xmod)
951  {
952  crl=hdl;
953  ++lap;
954  pr_ct(1);
955  }
956  if (xri==2)
957  {
958  pr_foot();
959  form_brk();
960  }
961  }
962  ami=0; /* no analytics for volumes */
963  }
964  else pr_foot(); /* pghf ! Fussabschnitt */
965  }
966  /* wg. Befehl M - moegliche Verschiebung: */
967  if (cri1 && *ga[cri1]!=RS)
968  {
969  i=cri1-1;
970  while (*ga[i]!=RS && i<(unsigned)gri) ++i;
971  cri1=i;
972  }
973  i=(cri1 && hif && xrg);
974  xk1=xk; /* reset pointer to start of param file */
975 // if(i && xri==2) if(stop()) break; // continuation card coming
976  } // Ende Hierarchieschleife - end do for hierarchy
977 
978  while (i && rmc<rmx);
979  if (!ftf && !sub)
980  {
981  if (xri==1)
982  {
983  ++lap;
984  pr_ct(1);
985  }
986  pr_cso(xre); /* rec-end: re */
987  if (xri==1)
988  {
989  pr_foot(); /* card modes */
990  form_brk();
991  }
992  }
993  hdl=0;
994  /* } while (cri2 && hif); * end outer do */
995 // if(!xmod) fflush(stream);
996  cri=cri3;
997  return 1;
998 } // ENDE form_pr()
999 
1000 // Exp.Unterprog >r abarbeiten
1001 void EXET::subroutine(CHAR r)
1002 {
1003  CHAR *xkk;
1004  int m, crj=cri;
1005  int crj0=cri0;
1006  xkk=xk1;
1007  m=0;
1008  do while (xk1[m++]!=0) ;
1009  while ((xk1[m+1]!=239 || xk1[m+2]!=r) && xk1[m]!=NL) ; /*KAT*/
1010  if (xk1[m]!=NL) m+=4;
1011  else return; /*KAT*/
1012  cri=cix0;
1013  xk1+=m;
1014  /* ++reclv; */ /* incr recursion level */
1015  form_pr(0,xk1[-2]); /* recursive! */
1016  /* --reclv; */ /* decr it */
1017  xk1=xkk;
1018  cri=crj;
1019  cri0=crj0;
1020  return;
1021 }
1022 
1023 char zz[64]; /* auxil string */
1024 
1025 // *********** Manipulationsbefehle bearbeiten
1026 
1027 CHAR *EXET::pre_chk(CHAR *ad,unsigned int *ixx,int repflg,CHAR prefs[])
1028 // chk ad for ersatz, non-sort etc.
1029 // and do replacements on char level
1030 // current position in field list
1031 // 0:normal 1:repetition
1032 // prefix list
1033 // ret: ax = string for output after preprocessing
1034 // nil : do nothing
1035 // NULL : do pre/postfixes, but no text
1036 {
1037  static int i,j,k,m,n,p,bec,rep;
1038  static CHAR *ax, *ax1, *ax0, *xbas; /*$$950704 xbas NEU */
1039  static int ups; /* uppercase flag : if(ups) set 1st char to upper */
1040  static int prefnr; /* prefix counter */
1041  static int bcn, ecn; /* begin/endpoint within kat */
1042  static CHAR *bca, *eca; /* begin/end addrs */
1043  *prefs=0;
1044  rcd=dcd=1;
1045  i=j=ups=prefnr=0;
1046  postfix0=1;
1047  postfix1=0; /*$$971221 prevent unwanted postfixes */
1048 
1049  ax1=aux=xbas=gx+1000; /* $$051009 */
1050  // Achtung: es muessen einige Zeichen VOR aux frei sein! wg. Praefix
1051  i=j=0;
1052  if (!ad || !*ad || (int)strlen(ad)<=xks) return (CHAR *)nil; /* $$15.5.93 */
1053  strcpy(ax1,ad);
1054  /* now: decoding the character level */
1055  ax=aux+xks;
1056  /* preprocessing required? */
1057  /* ax is now our workstring address */
1058  while (1)
1059  {
1060  rep=0;
1061  p=xk1[pos];
1062  bec=p-247;
1063  /* any of "b B e E s r R k K = p P m M N a A d i I c C
1064  f F u U T t w ,_ x y Z |  " ? l L */
1065  switch (bec)
1066  {
1067  case -20: /* x"..." calculation commands */
1068  if (xk1[++pos]==255)
1069  {
1070  static double val0,val1;
1071  static char frmat[]="%.9f";
1072  static char div_err[]="divide error";
1073  int flag=1;
1074  frmat[2]='9'; /* $$960609 sonst folgefehler */
1075  bca=xk1+pos+1;
1076  while (xk1[++pos]!=1) ; /* string is terminated by 1 */
1077  ++pos; /* pts behind 1 */
1078  val0=ATOF(ax);
1079  switch (*bca++) /* which operation? */
1080  {
1081  case '+':
1082  val1=val0+NUMBER(bca);
1083  break;
1084  case '-':
1085  val1=val0-NUMBER(bca);
1086  break;
1087  case '*':
1088  val1=val0*NUMBER(bca);
1089  break;
1090  case '/':
1091  if (!(val1=NUMBER(bca))) return (CHAR *)div_err;
1092  val1=val0/val1;
1093  break;
1094  case '%':
1095  val1=(double)((long)val0 % (long)NUMBER(bca)); /* $$940602 */
1096  break;
1097  case '>':
1098  if (*bca=='=')
1099  if (val0>=NUMBER(++bca))
1100  {
1101  flag=0;
1102  break;
1103  }
1104  else return (CHAR *)nil;
1105  if (val0>NUMBER(bca))
1106  {
1107  flag=0;
1108  break;
1109  }
1110  else return (CHAR *)nil;
1111  case '<':
1112  if (*bca=='=')
1113  if (val0<=NUMBER(++bca))
1114  {
1115  flag=0;
1116  break;
1117  }
1118  else return (CHAR *)nil;
1119  if (val0<NUMBER(bca))
1120  {
1121  flag=0;
1122  break;
1123  }
1124  else return (CHAR *)nil;
1125  case '=':
1126  if (*bca=='=') /* == : test for equality */
1127  if (val0!=NUMBER(++bca)) return (CHAR *)nil;
1128  else flag=0;
1129  else val1=NUMBER(bca);
1130  break;
1131  case 'r': /* rounding */
1132  val1=val0;
1133  frmat[2]=*bca++;
1134  break;
1135 
1136  default:
1137  flag=0;
1138  break;
1139  }
1140  if (flag) sprintf((char *)ax,frmat,val1); /* put that value back to ax */
1141  }
1142  break;
1143 
1144  case -33: /* M */
1145  rec->Ins(ax);
1146  ++pos;
1147  gri=rec->gri;
1148  gend=rec->gend;
1149 // postfi=0; /* prevent postfixes */
1150  return 0; /* sonst kein bed. Spr */
1151  case -21: /* C */
1152  cpc(CR);
1153  ++pos;
1154  break;
1155  case -22: /* N */
1156  nwpag();
1157  ++pos;
1158  break;
1159  case -19: /* fx or f"xyz" : elim leading x's */
1160  j=xk1[++pos]-1; /* 255 : string, else asci code */
1161  if (j!=254) while (*ax==j) ++ax;
1162  else
1163  {
1164  k=0;
1165  while ((zz[k++]=xk1[++pos])!=1) ;
1166  zz[k]=NL;
1167  while (*ax && strchr(zz,*ax)) ++ax;
1168  /* now remove these char's */
1169  }
1170  ++pos;
1171  break;
1172  case -23: /* Fx or F"xyz" : elim trailing x's */
1173  j=xk1[++pos]-1; /* 255 : string, else asci code */
1174  m=strlen(ax)-1; /* last char of ax */
1175  if (j!=254) while (m>-1 && ax[m]==j) ax[m--]=NL;
1176  else
1177  {
1178  k=0;
1179  while ((zz[k++]=xk1[++pos])!=1) ;
1180  zz[k]=NL;
1181  while (m>-1 && strchr(zz,ax[m])) ax[m--]=NL;
1182  /* now remove these char's */
1183  }
1184  ++pos;
1185  break;
1186  case -24: /* tx or t"xyz" : cut x chars at end / cut at "xyz" from rear */
1187  case -25: /* Tx or T"xyz" : take last x chars / take string behind "xyz" */
1188  if (xk1[++pos]==255)
1189  {
1190  eca=xk1+pos+1;
1191  while (xk1[++pos]!=1) ; /* put pos to end of string */
1192  ++pos;
1193  ax1=ax+strlen(ax);
1194  while (ax1>=ax) if (fndstr(--ax1,eca,0,1)==0) ;
1195  else break;
1196  if (ax1<ax && bec==-24) break; /* no result with t"xyz" */
1197  if (bec==-24) *ax1=NL; /* t"xyz" was found , trim it off */
1198  else if (ax1<ax) return ((CHAR *)nil); /* T"xyz" not found, leave off */
1199  else ax=ax1; /* T"xyz" found, set ptr on 'x' */
1200  }
1201  else
1202  {
1203  ax=ExRcode(ax);
1204  bcn=strlen(ax)-xk1[pos++]+1;
1205  if (bcn>=0) if (bec==-24) ax[bcn]=NL;
1206  else ax+=bcn;
1207  else return ((CHAR *)nil); /* workstring too short, break */
1208  }
1209  break;
1210  case -26: /* yi : 0:no coding 1:normal 2:alternate
1211  >2 : decode if 1st char < i */
1212 // if(xk1[++pos]==1) ;
1213  if (xk1[++pos]<6)
1214  {
1215  if (xk1[pos]==1) rcd=0; /* V23 $$030201 y0 */
1216  else
1217  {
1218  pix=xk1[pos]-2; /* y1/y2 ->0/1 Änderung $$16.11.92 */
1219  if (pix==2) rcd=2; /* y3 : nur v23 Ersetzungen */
1220  if (pix==3) rcd=5; /* y4 : UTF-8 -> &#nnn; oder \unnn? */
1221  if (pix>1) pix=0;
1222  ptx=ptb[pix];
1223  if (pix) utx=ucq;
1224  else utx=ucp;
1225  }
1226  ax=ExRcode(ax);
1227  }
1228  else if (xk1[pos]==255) /* y"?" : alnum $$990905 NEU $$010514 */
1229  {
1230 
1231  CHAR *ay, *az;
1232  int md=xk1[++pos]-'0';
1233  ay=az=ax;
1234  ++pos;
1235  if (md>0 && md<16)
1236  {
1237  while (*az)
1238  {
1239  *ay=*az;
1240  if (md&2 && islower(*az)) ++ay;
1241  if (md&4 && isupper(*az)) ++ay;
1242  if (md&1 && isdigit(*az)) ++ay;
1243  if (md&8 && !isalnum(*az)) ++ay;
1244  ++az;
1245  }
1246  *ay=0;
1247  }
1248  }
1249  else if (*ax<xk1[pos]) ax=ExRcode(ax); /* chinese extravaganza */
1250  rcd=dcd=0;
1251  ++pos;
1252  break;
1253  case -27: /* Z : does the same as e0 : stop this line without output */
1254  return 0;
1255  case -28: /* |im : retrieve secondary rec via index i, modus m */
1256  /* ax must contain the key now! */
1257 // postfi=0; /* prevent postfixes */
1258  if (main_ixl(rec->Adn, rec, ax,xk1[++pos]-1,xi4))
1259  {
1260  cri0=cri=rec->cri;
1261  gri=rec->gri; // evtl. veraendert!
1262  gend=rec->gend;
1263  replace(2,0);
1264  return 0; // positive reaction
1265  }
1266  return((CHAR *)nil); /* no result: ignore this whole line */
1267  case -30: /* _"_abc_xyz_" local replacements */ /*KAT*/
1268  {
1269  int crI, grI;
1270  CHAR *G, *G1, *GE, *st;
1271  st=xk1+pos+2;
1272  G=rec->ga[0];
1273  G1=rec->ga[1];
1274  GE=rec->gend;
1275  crI=rec->cri;
1276  grI=rec->gri;
1277  /* naechste Zeile: ax-1 statt ax ! */
1278  ax[-1]='1'; /* nur falls da zufaellig 0 stuende $$960715 */
1279  rec->ga[0]=ax-1;
1280  rec->ga[1]=rec->gend=ax+strlen(ax)+1;
1281  rec->cri=0;
1282  rec->gri=1;
1283  strcpy(rec->gend+120,st);
1284  while (xk1[++pos]!=1) ; /* put pos to end of string */
1285  rec->gend[120+(xk1+pos)-st]=0;
1286  ++pos;
1287  rec->SrRp(rec->gend+120,rec->ga[0],1,2,1);
1288  rec->ga[0]=G;
1289  rec->gend=GE;
1290  rec->ga[1]=G1;
1291  rec->gri=grI;
1292  rec->cri=crI; /* restore these values */
1293  if (!*ax) return((CHAR *)nil); /* $$071219 AT leer nach Ersetzung */
1294  }
1295  break;
1296 
1297  /* $$960320 : -31 und -29 jetzt hintereinander
1298  moeglich: #nnn p"123$s!" e"!" w
1299  macht Teilfeld s von #123 zum Arbeitstext
1300  */
1301  case -31: /* w : take workstring as tag and look for that field */ /*KAT*/
1302  {
1303  static char subf[]="a!"; /* SF statt  */
1304  int sf=0;
1305  ++pos;
1306  i=cix0;
1307  k=3; // cix0 statt cri $$020130 ax=123$a
1308  j=0;
1309  while (ax[j] && ax[j]!='$' && ax[j]!=kfg->SF) ++j;
1310  if (ax[j]=='$' || ax[j]==kfg->SF)
1311  {
1312  sf=j;
1313  *subf=kfg->SF;
1314  subf[1]=ax[j+1]; /* --j; */
1315  }
1316  while (strncmp(ax,ga[i]+k,j) && i<gri)
1317  {
1318  ++i;
1319  if (*ga[i]==RS) break;
1320  else k=1;
1321  }
1322  /* $$960416 : i<gri: */
1323  if (i<gri && !strncmp(ax,ga[i]+k,j)) ax1=ga[i]+k+xks-1;
1324  else return (CHAR *)nil;
1325  /* if((ax1=kat_adr(ax))==NULL) return (CHARA *)nil; $$951027 */
1326  strcpy(xbas,ax1-xks); /*$$950704 xbas statt aux */
1327  ax=xbas+xks;
1328  if (sf)
1329  {
1330  ax1=fndstr(ax,(CHAR *)subf,1,'!');
1331  }
1332  else break;
1333  }
1334  /* fallthru if subfield wanted */
1335  case -29: /* x : isolate subfield x */
1336  case -36: /* ~x : delete subfield x */ /* $$960604 NEU */
1337  {
1338  static char subf[]="a!"; /* SF statt  */
1339  if (bec==-29 || bec==-36) /* $$960604*/
1340  {
1341  *subf=kfg->SF;
1342  subf[1]=xk1[++pos]; /* $$941107 "-1" weggenommen */
1343  if (subf[1]=='$') ax1=ax; /* $$050117 $ = Feldanfangsteil */
1344  else ax1=fndstr(ax,(CHAR *)subf,1,'!');
1345  ++pos;
1346  }
1347  if (bec==-36)
1348  {
1349  CHAR *au;
1350  int i=2;
1351  if (ax1==(CHAR *)NULL) break; /* subf not found */
1352  au=ax1-2;
1353  ax1=ax;
1354  while (au[i] && au[i]!=kfg->SF) ++i; /* find nxt subf code */
1355  do
1356  {
1357  *au++=au[i];
1358  }
1359  while (au[i]); /* copy rest of field */
1360  *au=0;
1361  break;
1362  }
1363  if (ax1==(CHAR *)NULL) return (CHAR *)nil; /* subf not found */
1364  i=0;
1365  while (ax1[i] && ax1[i]!=kfg->SF) ++i; /* find end of subf */
1366  ax1[i]=NL;
1367  ax=ax1;
1368  break;
1369  }
1370  case 3: /* b B begin-codes */
1371  case 4:
1372  case -18: /* c : contain? */
1373  bec-=3; /* b=0, B=1 */
1374  /* 255 : string, else number */
1375  if (xk1[++pos]==255)
1376  {
1377  bca=xk1+pos+1;
1378  while (xk1[++pos]!=1) ; /* string is terminated by 1 */
1379  ++pos; /* now pos points behind the 1 */
1380  ax1=fndstr(ax,bca,1,1);
1381  if (ax1==0) /* no occurrence */
1382  {
1383  if (bec==1) ; /* B : leave ax unchanged */
1384  else return((CHAR *)nil); /* b c : no action */
1385  }
1386  else if (bec!=-21) ax=ax1; /* occurrence: ax unchanged if case c */
1387  }
1388  else
1389  {
1390  ax=ExRcode(ax);
1391  bcn=xk1[pos++]-1; /* number */
1392  if ((int)strlen(ax)>bcn) ax+=bcn;
1393  else if (!bec) return((CHAR *)nil); /* not long enough */
1394  else return(0); /* case B9999 : impossibly large # */
1395  }
1396  break;
1397  case 5:
1398  case 6: /* e E end-codes */
1399  /* NL: string, else number */
1400  bec-=5; /* e=0, E=1 */
1401  if (xk1[++pos]==255)
1402  {
1403  eca=xk1+pos+1;
1404  while (xk1[++pos]!=1) ; /* put pos to end of string */
1405  ++pos;
1406  ax1=fndstr(ax,eca,bec,1);
1407  if (ax1==0) ;
1408  else *ax1=NL;
1409  }
1410  else
1411  {
1412  ax=ExRcode(ax);
1413  ecn=xk1[pos++]-1; /* number */
1414  if ((int)strlen(ax)>ecn)
1415  {
1416  if (bec)
1417  {
1418  i=ecn+1;
1419  while (--i>0 && *(ax+i)!=' ') ;
1420  if (i>0) *(ax+i)=NL;
1421  }
1422  *(ax+ecn)=NL;
1423  }
1424  if (!ecn) return 0; /* e0 : length zero, but pre-/postfix
1425  will be used! */
1426  }
1427  break;
1428  case 1: /* R */
1429  case 2: /* r */
1430  if (!*ax) return((CHAR *)nil); /* $$050819 sonst Haenger */
1431  ax=ExRcode(ax);
1432  i=strlen(ax);
1433  if (bec==2)
1434  {
1435  j=xk1[++pos];
1436  m=xk1[++pos];
1437  }
1438  else j=i+1;
1439  ++pos;
1440  if (i>=j) break;
1441  --i;
1442  --j;
1443  k=j;
1444  while (k>=0) ax[k]=ax[k-(j-i)], --k;
1445  while (k<j-i) ax[k++]=m;
1446  ax[++j]=NL;
1447  if (bec==1) *ax=254; /* flag for R */
1448  break;
1449  case 0: /* s */
1450  ax=ExRcode(ax);
1451  i=strlen(ax);
1452  j=xk1[++pos];
1453  m=xk1[++pos];
1454  ++pos;
1455  if (i>=j) break;
1456  while (i<j) ax[i++]=m;
1457  ax[j]=NL;
1458  break;
1459  case -1: /* umn : elim everything between m and n, both included */
1460  case -2: /* Umn : same, but capitalize 1st word */
1461  j=k=0;
1462  m=xk1[++pos];
1463  n=xk1[++pos];
1464  ax1=Awx+20;
1465  strcpy(ax1,ax);
1466  /* $$20070131 : NEU 2ndlist */
1467  if (m=='>')
1468  {
1469  bkey=ax1;
1470  if (!ntfind(nt1,ntn-1)) *ax=0;
1471  j=strlen(ax);
1472  }
1473  else if (kfg->nsm==4) /* MARC non-filing mode, new *KAT*/
1474  { /* $$931025 : naechste Zeile */
1475  if (isdigit(ad[tgl+3])) ax+=(ad[tgl+3]-'0');
1476  j=strlen(ax);
1477  }
1478  else while (ax1[k])
1479  {
1480  while (ax1[k] && (ax[j]=ax1[k])!=m) ++k,++j;
1481  if (!ax1[k]) break;
1482  if (m==kfg->NS && n==kfg->NS && !kfg->nsm) /* change NSmode 0 to 1 */
1483  {
1484  while (ax1[k] && !strchr(" '-",ax1[k])) ax[j++]=ax1[k++];
1485  ax[j++]=kfg->NS;
1486  ax[j++]=ax1[k];
1487  }
1488  else if (m==kfg->NS && kfg->nsm==0)
1489  {
1490  while (ax1[++k] && !strchr(" '-",ax1[k]));
1491  if (ax1[k]) ++k;
1492  }
1493  else while (ax1[++k] && ax1[k]!=n);
1494  if (ax1[k]==n) ++k;
1495  if (ax1[k] && strchr(" '-",ax1[k])!=NULL) ++k;
1496  } /* $$931025 naechste Zeile: bec==-2 statt p==245 */
1497  if (bec==-2) ++ups; /* U : set uppercase flag */
1498  ax[j]=NL;
1499  UtRemsp((CHAR *)ax); /* there may be a trailing space if last word was nonsort */
1500  ++pos; // $$071219 nil statt 0
1501  if (!*ax)
1502  {
1503  *ax='1'; /* nothing left after removals! */
1504  return (CHAR *)nil;
1505  } // (CHAR *)nil; }
1506  break;
1507  case -4: /* 244 : k */
1508  case -3: /* 243 : K */
1509  ax=ExRcode(ax);
1510  ax1=ax0=ax;
1511  ax=Awx+500;
1512  i=0;
1513  n=1;
1514  while (p==243 || p==244) /* key process */
1515  {
1516  m=0;
1517  j=xk1[++pos]-1;
1518  ++pos;
1519  if (p==243 && xk1[pos]!=243 && xk1[pos]!=244) n=0;
1520  while (m<j)
1521  {
1522  if (ptx[k= *ax1++]>2)
1523  {
1524  ax[i++]=ptx[k];
1525  ++m;
1526  }
1527  else if (n || !k)
1528  if ((k==' ') || !k)
1529  {
1530  --ax1;
1531  while (m++<j) ax[i++]=' ';
1532  p=244;
1533  }
1534  }
1535  m=0;
1536  while (strchr(" :,./-",(k=ax1[m++]))==NULL && k!=NL) ;
1537  if (k)
1538  {
1539  ax1+=m;
1540  while (ptx[*ax1]<33) ++ax1;
1541  }
1542  else if (p==244)
1543  {
1544  ax1+=m-1; /* k */
1545  *ax1=NL;
1546  }
1547  else ax1=++ax0;
1548  p=xk1[pos];
1549  ax0=ax1;
1550  }
1551  ax[i]=NL;
1552  break;
1553  case -5: /* =nm,k internally, we have 242 n m k or 242 n m 242 x */
1554  {
1555  int p; /* =nm+x */
1556  /* ax=ExRcode(ax); */
1557  n=xk1[++pos]; /* relates to user variable #unm */
1558  m=xk1[++pos];
1559  ++pos;
1560  p=UtFindX(n-'a'+2049,m,tgl); /* find #unm */
1561  if (p==EOF || strcmp(ax,fa[p]+kfg->skt)) /* ax is not equal */
1562  {
1563  strcpy(Awx,"#unm ");
1564  Awx[2]=n;
1565  Awx[3]=m; /* copy it to f-space *KAT*/
1566  strcpy(Awx+kfg->skt,ax); /* and leave ax as is */
1567  /* if(p!=EOF) UtFdel(p); */
1568  UtFinst(Awx,n-'a'+2049,tgl); /* for further preproc */
1569  if (xk1[pos]==1) return 0; /* =nm : assign only */
1570  if (xk1[pos++]==242) ++pos;
1571  }
1572  else /* ax is equal: use fix or label instead */
1573  {
1574  m=xk1[pos++]; /* and don't print text */
1575  if (m==242) /* =nm+x goto label #-x */
1576  {
1577  m=xk1[pos++];
1578  *ixx=0;
1579  while ((xk1[*ixx]!=127 || xk1[*ixx+1]!=241 || xk1[*ixx+2]!=m) && xk1[*ixx]!=NL)
1580  while (xk1[(*ixx)++]!=0) ;
1581  if (!xk1[*ixx]) --(*ixx); /* else error possible */
1582  pos= *ixx;
1583  }
1584  else
1585  {
1586  pr_fix(m); /* =nm,k */
1587  }
1588  return (CHAR *)nil;
1589  }
1590  break;
1591  }
1592  case -6: /* n or "xxx" embedded prefix */
1593  rep=repflg; /* don't if this is a repetition */
1594  case -9: /* mn or m"xxx" embedded prefix for repetition */
1595  if (bec==-9) rep=1-repflg; /* only if it's a repetition! */
1596  /* 255: string, else number */
1597  if (xk1[++pos]==255)
1598  {
1599  j=0;
1600  while (xk1[++pos]!=1) ++j; /* precede our string with it */
1601  aux=xk1+pos-1;
1602  if (!rep)
1603  {
1604  if (*ax && !ptx[*ax]) ++ax; /* stopmark */
1605  ax-=j;
1606  while (j) ax[--j]= *aux--;
1607  }
1608  } /* else put this fix to the list */
1609  else if (!rep)
1610  {
1611  prefs[prefnr++]=xk1[pos];
1612  prefs[prefnr]=0;
1613  }
1614  ++pos;
1615  break;
1616  case -7: /* Pn or P"xxx" embedded postfix */
1617  /* NL: string, else number */
1618  if (xk1[++pos]==255) /* append it to current string */
1619  {
1620  aux=xk1+pos+1;
1621  j=0;
1622  while (xk1[++pos]!=1) ++j;
1623  m=strlen(ax);
1624  ax[m+j]=NL;
1625  while (--j>-1) ax[m+j]=aux[j];
1626  }
1627  else postfix0=xk1[pos]; /* postf # */
1628  ++pos;
1629  break;
1630  case -8: /* embedded prefix control string {..} */
1631  rep=repflg; /* don't if this is a repetition */
1632  case -10:
1633  if (bec==-10) rep=1-repflg; /* only if it's a repetition! */
1634  ++pos;
1635  if (!rep) prefix0=xk1+pos;
1636  while (xk1[pos]!=255 || xk1[pos+1]!=1) ++pos;
1637  pos+=2;
1638  break;
1639  case -12: /* emb postfix control string */
1640  ++pos;
1641  postfix1=xk1+pos;
1642  while (xk1[pos]!=255 || xk1[pos+1]!=1) ++pos;
1643  pos+=2;
1644  break;
1645  case -39: /* Yj : $$051008 : ak=nn+xi */
1646  ax-=2;
1647  *ax=rG[0];
1648  ++pos;
1649  if (rG[1]) ax[1]=rG[1]; /* wenn rG[1]==0: */
1650  else if (xk1[pos] && xk1[pos]!=1) ax[1]=xk1[pos];
1651  else ax[1]='1';
1652  ++pos;
1653  break;
1654 
1655  /* $$951231 NEU : v und V */
1656  case -35: /* vk,x is char at pos k < 'x' ? */
1657  case -34: /* Vk,x is char at pos k > 'x' ? */
1658  case -16: /* ik,x is 'x' at position k ? (k=1..255) */
1659  case -17: /* Ik,x is 'x' not at position k ? */
1660  n=xk1[++pos];
1661  m=xk1[++pos];
1662  ++pos;
1663  if (n>=(int)strlen(ad)) return (CHAR *)nil; /* $$941221 Absicherung */
1664  if (bec==-35) if (ad[n]>=m) return (CHAR *)nil; /* v */
1665  if (bec==-34) if (ad[n]<=m) return (CHAR *)nil; /* V */
1666  if (bec==-16) if (ad[n]!=m) return (CHAR *)nil; /* i */
1667  if (bec==-17) if (ad[n]==m) return (CHAR *)nil; /* I */
1668  break;
1669  case -38: /* Lxy : put label from CFG into #uxy $$980131 */
1670  case -32: /* lxy : put length to #uxy */
1671  case -13: /* axy : affix */
1672  case -14: /* Axy : append workstring to user variable #uxy */
1673  case -15: /* delete #uxy */
1674  n=xk1[++pos]; /*relates to user variable #unm */
1675  m=xk1[++pos];
1676  ++pos;
1677  p=UtFindX(n-'a'+2049,m,tgl); /* do we have #unm ? */
1678 // $$981123 : fDel(n) NEU: dx~ : alle #uxy loeschen
1679  if (bec==-15)
1680  {
1681  if (m=='~') UtFDel(n);
1682  else if (p!=EOF) UtFdel(p);
1683  break;
1684  }
1685  strcpy(Awx,"#unm "); /*KAT*/
1686  Awx[2]=n;
1687  Awx[3]=m; /* prepare w */
1688  if (bec==-32) /* lxy */
1689  if (n=='<' || n=='>') /* l<i l>i */
1690  { // m=atoi(xk1+pos-1); // $$020603
1691  if (n=='<' && (int)strlen(ax)>=m) return (CHAR *)nil;
1692  if (n=='>' && (int)strlen(ax)<=m) return (CHAR *)nil;
1693  break;
1694  }
1695  else sprintf((char *)Awx+kfg->skt,"%d%c",strlen(ax),0);
1696  else if (bec==-38) // Lxy
1697  { /* $$001110 -skt */
1698  kfg->KoGetLabel((CHAR *)ax-kfg->skt,(CHAR *)Awx+kfg->skt);
1699  // find label of field ax and write it to Awx+skt
1700  }
1701  else if (p==EOF) strcpy(Awx+kfg->skt,ax); /*KAT* no, #unm not present */
1702  else /*KAT*/
1703  {
1704  if (bec==-13)
1705  {
1706  strcpy(Awx+kfg->skt,ax);
1707  strcat(Awx,fa[p]+kfg->skt);
1708  }
1709  else
1710  {
1711  strcpy(Awx,fa[p]);
1712  strcat(Awx,ax);
1713  }
1714  UtFdel(p);
1715  }
1716  UtFinst(Awx,n-'a'+2049,tgl); /* copy to background space */
1717  return 0;
1718 #ifndef CALCUL
1719  case 'x':
1720  while (xk1[++pos]!=1) ; /* string is terminated by 1 */
1721  ++pos; /* pts behind 1 */
1722  break;
1723 #endif
1724  case -11: /* postf chain begins */
1725  default:
1726  goto ccode;
1727  }
1728  } /* end while(1) another code? */
1729 ccode:
1730  if (rcd) ax=ExRcode(ax);
1731  if (xkt && (int)strlen(ax)>xkt) ax[xkt]=NL;
1732  if (ups) *ax=toupper(*ax);
1733  return ax;
1734 } // ENDE pre_chk()
1735 
1736 #include <math.h> // Rechenfunktionen
1737 
1738 double EXET::ATOF(CHAR *nnn) /* find number in char array nnn and return value */
1739 {
1740  char nmb[36];
1741  int i=0;
1742  while (*nnn && !isdigit(*nnn) && !(*nnn=='-' && isdigit(nnn[1]))) ++nnn;
1743  if (nnn[-1]=='.' && nnn[-2]==' ') --nnn; /* numbers like " .75" */
1744  strncpy(nmb,(char *)nnn,35);
1745  while (++i<33) if (nmb[i]==',')
1746  {
1747  nmb[i]='.'; /* change , into . */
1748  break;
1749  }
1750  if (*nmb) return atof(nmb);
1751  else return 0;
1752 }
1753 
1754 // ******** Zahl ausrechnen
1755 double EXET::NUMBER(CHAR *adr) /* adr=ab or number or #xxf */
1756 {
1757  char a,b;
1758  int p;
1759  a=*adr; /*relates to user variable #unm */
1760  if (isalpha(a)) /* x"+ab" */
1761  {
1762  b=adr[1];
1763  p=UtFindX(a-'a'+2049,b,tgl); /*$$950402 2049 */ /* do we have #uab ? */
1764  if (p!=EOF) return ATOF(fa[p]+4);
1765  else return 0;
1766  }
1767  else if (a=='#')
1768  {
1769  CHAR *yy;
1770  char xx[9];
1771  strncpy(xx,(char *)adr,kfg->tgl+2);
1772  if (xx[kfg->tgl+1]==1) xx[kfg->tgl+1]=32;
1773  xx[kfg->tgl+2]=0;
1774  if ((yy=rec->Adr((CHAR *)xx))!=0) return ATOF(yy);
1775  else return 0;
1776  }
1777  else return ATOF(adr); /* x"+number" */
1778 }
1779 
1780 // *************** Umcodierung mit p und q usw.
1781 
1782 CHAR *EXET::ExRcode(CHAR *ax) /* decode, remove codes with values 1..3,4,5 */
1783 {
1784  static int i, j, k, m, A, B, C;
1785  static CHAR cx;
1786  static CHAR *ax1;
1787  static CHAR a,b,pc;
1788  static CHAR *fkey, *key, *skey, *u;
1789  i=j=0;
1790  if (!rcd || !xpy) return ax; /* $$930719 !xpy */
1791  ax1=ax+strlen(ax)+1; // Achtung: Zeichenfolge muss in Feld mit mind. doppelte Laenge stehen!
1792  // denn Resultat kommt nach hinten.
1793 
1794  while (1) /* now eliminate codes 1..3 (non-sort and such) */
1795  { // $$20021210 : NEU code 8 = Zwischenteil, 9 = Sequ.Ersetzung
1796  while (2)
1797  {
1798  cx=ax[i++]; // naechstes Zeichen
1799  if (!cx) break;
1800  if (xuc && cx>127) // $$030428 NEU Unicode meth 2
1801  {
1802  u=utx; // that's ucp or ucq (P or Q list)
1803  if (u) while (*u) // UTF-Code in der Liste finden
1804  {
1805  if (*u==cx)
1806  { // > 223: 3-Byte code
1807  if (*++u==ax[i] && (cx<224 || u[1]==ax[i+1]))
1808  {
1809  ++i;
1810  if (cx>223) ++u,++i;
1811  while (*++u) ax1[j++]=*u;
1812  cx=255;
1813  break;
1814  }
1815  else while (*++u);
1816  }
1817  else while (*++u); // nxt code
1818  ++u;
1819  }
1820  if (cx==255) continue;
1821  // if(!*u) break; // not found { ax1[j++]=cx; ax1[j++]=ax[i++]; if(cx>223) ax1[j++]=ax[i++]; }
1822  }
1823  // else
1824  pc=ptx[cx]; // Tabellenwert des Zeichens
1825  if (rcd==2) // y3
1826  if (pc!=9 && pc!=8) ax1[j++]=cx;
1827  else break;
1828  else if (rcd==5 && cx>193) // y4 : UTF-8 -> Entity $$20090210
1829  {
1830  A=cx;
1831  B=ax[i++];
1832  if (!B)
1833  {
1834  --i;
1835  break;
1836  }
1837  if (A>223) // 3 byte
1838  {
1839  C=ax[i++];
1840  if (!C)
1841  {
1842  --i;
1843  break;
1844  }
1845  A= (A-224)*4096 + (B-128)*64 +C -128;
1846  }
1847  else if (A>193) // 2 byte // 2011-03-14: vorher 194
1848  {
1849  A=(A-196)*64 + B -128 +256;
1850  }
1851  extern char U1[], U2[]; // from statement like u&# ;
1852  sprintf((char *)ax1+j,"%s%d%s",U1,A,U2);
1853  j=strlen(ax1);
1854  }
1855  else if (rcd>1)
1856  {
1857  ax1[j++]=cx;
1858  continue;
1859  }
1860  else if (pc>9) ax1[j++]=(xpy)?pc:cx;
1861  else break; // TabWert<9
1862  }
1863 
1864  if (cx==NL)
1865  {
1866  ax1[j]=NL; /* exit from while(1) */
1867  break;
1868  }
1869  --i;
1870  switch (pc)
1871  {
1872  case NL: /* p x 0 : global stop */
1873  if (j) ax1[j++]=0;
1874  break;
1875  case 1: /* p x 1 : elim x */
1876  break;
1877  case 2: /* p x 2 : elim x and following char */
1878  if (ax[i+1]) i++; /* $$930818 sonst Absturz, wenn das Zeichen genau
1879  am Ende der Kategorie steht */
1880  break;
1881  case 3: /* p x 3 : same, repl both by ' ' */
1882  if (ax[i+1]) i++; /* $$930818 sonst Absturz, wenn das Zeichen genau
1883  am Ende der Kategorie steht */
1884  ax1[j++]=' ';
1885  break;
1886  case 4: /* p x "abc" : string replacements */
1887  m=0;
1888  if (!pix) k=10000+Gns*300+ax[i];
1889  else k=20000+Gns*300+ax[i]; /* which tble? */
1890  while (m<phi && pi[m]!=k) ++m;
1891  if (m==phi) break;
1892  k=0;
1893  while ((ax1[j++]=pa[m][k++])!=NL) ;
1894  --j; /* the terminating 0 ! */
1895  break;
1896  case 5: /* p x 5 : don't decode this and the following (CHINESE !) */
1897  ax1[j++]=cx;
1898  if (ax[i+1]) ax1[j++]=ax[++i]; /* $$930803 sonst crash */
1899  break;
1900  case 8: // $$20021210 : use texel
1901  if (ax[++i]) // _A -> replace by texel 65
1902  {
1903  int l,k=ax[i];
1904 // if(isdigit(k)) { k=atoi(ax+i); while(isdigit(ax[++i])); --i; } // _nnn
1905  if (isdigit(k))
1906  {
1907  k=atoi(ax+i); // _nnn
1908  while (isdigit(ax[++i]));
1909  --i;
1910  }
1911  l=findfix(k+1);
1912  if (!ptx[8]) break; /* set p .8 0 to eliminate the coded sequence*/
1913  if (l!=EOF)
1914  {
1915  CHAR *zt=pa[l];
1916  while (*zt)
1917  {
1918  char c=*zt;
1919  if (c!='"' && c!=39) ax1[j++]=*zt++;
1920  else
1921  {
1922  while (*++zt!=c && *zt) ax1[j++]=*zt;
1923  if (*zt==c) ++zt;
1924  }
1925  }
1926  }
1927  else ; /* ax1[j++]=k; */
1928  } /* hinter dem Code ist nichts mehr: nichts ausgeben */
1929  else --i ; /* ax1[j++]=cx; */
1930  break;
1931  case 9: // $$2003-01-30 : Sequenz-Ersetzung
1932  { // cx=ax[i], ax1+j = naechste Position in ax1 als Hilfsspeicher
1933  fkey=key=ax1+j; // da kommt die gefundene Sequenz hin
1934  k=i++; // cx=ax[k]=='&'
1935  skey=ax+k; // ax+k = &#nnn; muss gesucht werden
1936  if (ib>13)
1937  {
1938  while (ax[i] && ax[i]!=ib) ++i; // bis Zeichen ib kommt
1939 // if(!ax[i] || ax[k+1]==' ') { ax1[j++]=cx; i=k; break; } /* falls hinter & nichts steht */
1940  if (!ax[i])
1941  {
1942  ax1[j++]=cx; /* falls hinter & nichts steht */
1943  i=k;
1944  break;
1945  }
1946  }
1947  else i=k+ib;
1948  b=ax[i+1];
1949  ax[i+1]=0; // mit 0 abschliessen
1950  if (ia)
1951  {
1952  a=ax[k-1];
1953  ax[k-1]=ia;
1954  --skey;
1955  }
1956  if (!main_find(rec->Adn,i6+Adn*15,(CHAR*)skey,(CHAR*)fkey))
1957 // { strncpy(ax1+j,ax+k,i-k+1); j+=(i-k+1); break; } // nicht gefunden
1958  {
1959  ax1[j++]=cx; // Sequ. nicht gefunden
1960  i=k;
1961  break;
1962  }
1963  ax[i+1]=b;
1964  if (ia)
1965  {
1966  *skey=a;
1967  ++fkey;
1968  }
1969  key=fkey+i-k+1; // key= abc
1970 // gefundene Sequ. ungleich? Dann mit naechstem Zeichen weiter
1971 // if(strncmp(ax+k,fkey,i-k+1)) { strncpy(ax1+j,ax+k,i-k+1); j+=(i-k+1); break; }
1972  if (strncmp(ax+k,fkey,i-k+1))
1973  {
1974  i=k; // wenn z.B. ... A & O ...
1975  ax1[j++]=ax[i];
1976  }
1977  else while (*key) ax1[j++]=*key++; // abc nach w kopieren
1978  break;
1979  }
1980  default: /* 6 and 7 : print ersatz tables, done at last stage */
1981  ax1[j++]=ax[i];
1982  break;
1983  }
1984  ++i;
1985  } /* end while(1) */
1986  rcd=0;
1987  return ax1;
1988 } // ENDE ExRcode()
1989 
1990 // ******** Pauschalexport mit ##
1991 int EXET::kat_pr(int md) /* prt all kats xcpt xk0[] */
1992 /* 1:with subrec 7:without */
1993 {
1994  int i,m; /* $$941116 vereinfacht und fuer V13 angepasst */
1995  unsigned int j;
1996  CHAR *cn, ccn; /* kat#s */
1997  char lab[160];
1998  char leer[]=" "; /* $$941209 */
1999  i=cri0;
2000  xk0=x0;
2001  cn=ga[i]+3;
2002  do
2003  {
2004  j=m=0;
2005  if (!(kat[gi[i]][tgl]&4))
2006  {
2007  ++i; /*KAT* invisible*/
2008  continue;
2009  }
2010  while (xk0[j]!=NL)
2011  {
2012  m=0;
2013  while (xk0[j] && xk0[j]!='.')
2014  if (cn[m]!=xk0[j])
2015  {
2016  m=0;
2017  break;
2018  }
2019  else ++m,++j;
2020  if (m) break;
2021  while (xk0[j]) ++j; /*$$941118*/
2022  ++j;
2023  }
2024  if (!m) /* not in list */
2025  {
2026  ccn=ga[i][3];
2027  cn=ga[i];
2028  if (*cn==RS) cn+=2;
2029 // $$010128 : xkb war inkorrekt!
2030  if (xkb==1) cn[kfg->tgl+1]=' ';
2031  else if (xkb==2) strcpy(cn+kfg->tgl+1,cn+kfg->tgl+2);
2032  if (xfl) crc=0; /* no indent */
2033  if (md&8) /* $$980131 NEU */
2034  {
2035  kfg->KoGetLabel((CHAR *)cn, (CHAR *)lab); /* Label von cn */
2036  strcat(lab,": ");
2037  rcd=1;
2038  cpr(ExRcode((CHAR *)lab),0);
2039  }
2040  cpr(pre_chk(cn,&j,0,(CHAR *)leer),0); /* print this kat *//*$$950502 ,1 */
2041  if (*xke) PR_CS(); // xke=255 255 3 for kat end on screen
2042  else pr_cs((CHAR *)"\r"); // Zeilenvorschub, wenn xke leer
2043  ga[i][3]=ccn;
2044  }
2045  ++i;
2046  /* k1=ga[i][1]; k2=ga[i][2]; k3=ga[i][3]; $$941116 KAT */
2047  if (i<gri) cn=ga[i]+1;
2048  // $$010127 : umgedreht, weil ga[i] sonst evtl. undefiniert!
2049  }
2050  while (i<gri && ga[i][1]>(md&7));
2051  return 0;
2052 }
2053 
2054 
2055 // ********** Hilfsfunktionen
2056 
2057 /* xke nicht bei Index-Par. ausgeben */
2058 /* oben 4mal PR_CS statt pr_cs */
2059 void EXET::PR_CS()
2060 {
2061  if (xmod) return;
2062  else pr_cs(xke);
2063  return;
2064 }
2065 
2066 void EXET::cpr(CHAR *adr,int md) /* cardpr procedure: get out what you find at adr */
2067 {
2068  int i, j,m,n;
2069  register CHAR ca, cb;
2070  int k, rflag;
2071  i=0;
2072  cb=BK;
2073  k=cp[crl][crc];
2074  rflag=0;
2075  /* $$950509 : crc>xli */
2076  if (md && crc>xli) if (*adr=='.' && strchr(".!?;:,",ct[crl][crc-1])) ++adr; /*$$950502*/
2077  if (*adr) nlfl=1;
2078  else return;
2079  if (*adr==254 && xll<=MC) /* R-flag : right align, $$941011 xll<= neu */
2080  {
2081  rflag=1;
2082  *adr=' ';
2083  j=strlen(adr);
2084  if (j+k>xll)
2085  {
2086  nxtlin();
2087  k=cp[crl][crc];
2088  }
2089  if (j+k>xll) ++adr;
2090  else /* fill left side with spaces */
2091  {
2092  --k;
2093  cps(' '); /*$$950507 NEU sonst klappt R nicht */
2094  m=xll-k;
2095  while (j>=0) adr[m--]=adr[j--];
2096  while (m>0) adr[m--]=' ';
2097  }
2098  }
2099  while (1) /* adr now ready for output */
2100  { /*$$950428 : 3 Zeilen waren weiter unten und anders: */
2101  /*$$950524 xll<MC */
2102  if (xll<MC && crc==xli) /*$$ 26.6.92 : nur ausfueuehren, wenn Zeilenumbruch gewuenscht*/
2103  /* kein '-' oder ' ' am Zeilenanfang! */
2104  if (md && !rflag) /*$$950502 NEU $$950524 !rflag */
2105  while (adr[i]==' ' || adr[i]=='-') ++i;
2106  while (k<xll+2 && (cb=adr[i++])!=NL)
2107  {
2108  ca=ptx[cb]; /* what is the output code of this char */
2109  if (xpy && dcd) /* are we actually going to decode? */
2110  {
2111  /* .-replacements,
2112  will be decoded in the last stage before output */
2113  /* 6, 7: these chars will be repl by strings */
2114  if ((ca==6 || ca==7) && ptx[adr[i-2]]!=5) /* CHINESE */
2115  {
2116  ct[crl][crc]=255;
2117  cp[crl][crc++]=k;
2118  ct[crl][crc]=ca ;
2119  cp[crl][crc++]=k;
2120  }
2121  }
2122  n=0;
2123  while (n<xbl) if (cb==xpb[n++])
2124  {
2125  --k; /* backsp */
2126  break;
2127  }
2128  ct[crl][crc]=cb;
2129  if (cb==27) k-=2; /* ESC+following char must not be counted */
2130  cp[crl][crc++]=k++; /* problematic at front of line?? k==0 */
2131  if (ca==FF)
2132  {
2133  --k;
2134  --crc;
2135  ct[crl][crc]=(ct[crl][crc+1])?' ':NL; /* remove the code*/
2136  if (k==xll+1) --i;
2137  break;
2138  } /* forced line break */
2139  }
2140  cp[crl][crc]=k;
2141  if (rflag)
2142  {
2143  ct[crl][crc]=' ';
2144  cp[crl][++crc]=k;
2145  }
2146  /* add ' ' at end to prevent breaking in case of right align */
2147  if (cb==NL || adr[i]==NL) break;
2148  nxtlin();
2149 // if(!stopc) break;
2150  k=cp[crl][crc];
2151  /*$$950428 3 Zeilen nach oben unter while(1) */
2152  md=1; /* $$950509 nach erstem Umbruch */
2153  }
2154  /*$$ 16.8.92 folgende Zeile neu wg. PA.APR bei langen Aufn. */
2155  /* NEU $$941206 */
2156  if (xll>MC) /*$$950626 wg v14a */
2157  {
2158  ct[crl][crc]=NL;
2159  if (!xmod)
2160  {
2161  pr_ct1(0);
2162  c_init(0);
2163  crl=crc=0;
2164  }
2165  }
2166  return;
2167 }
2168 
2169 void EXET::nxtlin() /* start nxt line, print if buffer full */
2170 {
2171  int i, j=crc, k, l, m=0, n=crc+1;
2172  if (xll>MC)
2173  {
2174  pr_ct1(0);
2175  c_init(0);
2176  pr_cso(xle);
2177  crc=0;
2178  return;
2179  }
2180  // { get_txt_out(); pr_cso(xfb); return; }
2181  if (crl==ML+1) // we are in the foot area
2182  {
2183  pr_ct1(ML); // print 1st line
2184  m=0;
2185  lap=0;
2186  while (m<=crc)
2187  {
2188  ct[ML][m]=ct[ML+1][m]; /* copy last line */
2189  cp[ML][m]=cp[ML+1][m];
2190  ++m;
2191  }
2192  ct[ML][m]=NL;
2193  l=0;
2194  while (l<MC) ct[ML+1][l++]=NL; /* clr last line */
2195  crc=0;
2196  return;
2197  }
2198  if (cp[crl][crc]<=xll || !xfl) ;
2199  else
2200  {
2201  cp[crl][n]=cp[crl][n-1];
2202  /* where is a break? xlb contains the line break characters */
2203  while (!strchr(xlb,ct[crl][--crc]) && crc>xli);
2204  if (crc>xli && ct[crl][crc]==' ') --crc;
2205  if (crc<=xli) crc=j-1; /* no brk found, print it as it is */
2206  n=crc+1;
2207  }
2208  i=n; /* new line */
2209  k=cp[crl][i];
2210  ++crl; /* foot */ /* $$3.3.93 this line + next */
2211  if (ct[crl][0]==NL) /* this is really a nwlin */
2212  {
2213  ++lap;
2214  l=1;
2215  while (l<MC) ct[crl][l++]=NL; /* fill with zeros */
2216  nlfl=0;
2217  }
2218  crc=xli;
2219  if (ct[crl][crc]==NL)
2220  {
2221  m=strlen(ct[crl]);
2222  while (m<crc) /* fill indent space with spaces */
2223  {
2224  if (ct[crl][m]==NL)
2225  {
2226  ct[crl][m]=' ';
2227  ct[crl][m+1]=NL;
2228  cp[crl][m+1]=cp[crl][m]+1;
2229  }
2230  ++m;
2231  }
2232  if (ct[crl-1][i]==' ') ++i,++k;
2233  m=xli+1;
2234  if (i<=j)
2235  {
2236  while (i<=j) /* copy from last line */
2237  {
2238  ct[crl][crc]=ct[crl-1][i];
2239  ct[crl-1][i]=NL;
2240  cp[crl][crc]=cp[crl-1][i]-k+m;
2241  ++i;
2242  ++crc;
2243  nlfl=0;
2244  }
2245  if (crc>xli) --crc;
2246  ct[crl][crc]=ct[crl-1][n]=NL;
2247  }
2248  }
2249  if (crl==ML-1 || !xfl)
2250  { /* $$3.3.93 Žnderungen in diesem Block */
2251  get_txt_out();
2252  m=l=0;
2253  crl=hdl+1;
2254  lap=crl; /* if(lop && lop-2!=hdl) --lop; */ /* odd!!*/
2255  while (l<MC) ct[crl][l++]=NL;
2256  strcpy(ct[crl],ct[ML-1]);
2257  crc=strlen(ct[crl]);
2258  strncpy((char *)cp[crl],(char *)cp[ML-1],crc+1);
2259  ct[crl][crc]=0;
2260  cp[ML-1][0]=1;
2261  ct[ML-1][0]=NL;
2262  cp[crl][crc]=crc+1; /*$$950705 neu */
2263  }
2264  return;
2265 }
2266 
2267 void EXET::get_txt_out()
2268 {
2269  pr_ct(0); /* print out what's there */
2270  c_init(hdl); /* init lines from hdl down */
2271  return;
2272 }
2273 
2274 void EXET::pr_ct(int rce) // print contents of buffer
2275 // 1:rec end was reached 0:not yet
2276 {
2277  int i=0, j=0, k, r=xri, m=xlm; /* r==0/1 : list/card mode = xfm */
2278  if (xll>MC) ct[crl][crc]=NL; /* continuous output */
2279  /* is text longer than 1 card? then put card# in place */
2280  if (r && (lap>xfl+1 || !rce || cnr>0))
2281  {
2282  if (!cnr) ++cnr;
2283  if (cnr<2) cont_card();
2284  } /* m==0/1 : endless/page mode */
2285  if (lop) i=hdl+1; /* $$3.3.92 wieder aktiviert wg. Befehl N */
2286  k=ln+lap-m-xl2+1; /* k = overflow over page max + tolerance */
2287  /* k>0 : it won't fit on page */
2288  if (!r && m)
2289  if (m/*+xl2*/-ln<xl1 && k>0) /*$$30.4.93*/
2290  {
2291  ++xfca; /* not enough room left on this page */
2292  nwpag();
2293  }
2294  while (j<lap) /* prt all lines produced */
2295  {
2296  while (j<lap && lop<=xfl)
2297  {
2298  if (i<ML) pr_ct1(i++);
2299  if (++j==lap) break;
2300  if (!r && m) /* we are in list+page mode */
2301  if (ln>m+xl2-2 || (ln>m-1 && k>0)) nwpag();
2302  }
2303  if (j<lap && lop>=xfl) /* finish old, begin new card */
2304  { /* rec doesn't fit on one card */
2305  lop=0;
2306  if (!ftf && r)
2307  { /*if(cmd=='d') ++tcn;*/
2308  pr_foot();
2309  form_brk();
2310  }
2311  if (hdl) cont_card(); /* cut headings line at #w point */
2312  k=0;
2313  if (r) while (k<crl)
2314  {
2315  pr_ct1(k);
2316  ++k;
2317  }
2318 // if(stream!=stdout)
2319  pr_fixo(repfix);
2320  }
2321  }
2322  if (r && rce) // end-of-rec reached, card mode: write empty lines
2323 // if(stream!=stdout)
2324  {
2325  while (lop++<=xfl)
2326 // if (*xle==NL) fprintf(stream,"\r\n");
2327 // else
2328  pr_cso(xle);
2329  }
2330 // if (rce) if(cmd=='d') ++tcn;
2331  return;
2332 }
2333 
2334 int EXET::cont_card() // continuation card handling
2335 {
2336  int LAP=lap; // wg. Kartendruck
2337 // $$970714 unnoetig?? if(Apgnb=='1') return 1; // not for screen display
2338  crl=hdl-1;
2339  crc=strlen(ct[crl]);
2340  if (cnr==1) ; // this is the 1st card
2341  else while (crc>hdc) ct[crl][crc--]=NL; // else erase text from #w mark
2342  if (*xfa!=1) if (cnr>1) pr_cs(xfa);
2343  else ;
2344  else pr_cs(xfa+1); // if xfa begins with code 1: apply also on card 1
2345  ct[crl][crc]=NL;
2346  crl=hdl;
2347  crc=0;
2348  if (cnr>1) ct[crl++][crc]=NL;
2349  ++cnr; // begin on nxt line
2350  lap=++LAP; // wg. Kartendruck
2351  return 1;
2352 }
2353 
2354 void EXET::pr_foot() // print foot (ftf=1) or head (ftf=2) text
2355 {
2356  int k=ML;
2357  if (xff) // any foot desired?
2358  {
2359  if (ftf==1) pr_cso(xrf); // foot ctrl
2360  while (k<ML+xff) pr_ct1(k++); // foot text
2361  }
2362  return;
2363 }
2364 
2365 // Neue Seite
2366 void EXET::nwpag()
2367 {
2368  if (xri) /* $$26.10.92 neu Befehl N fuer Karten , schwierig!! */
2369  {
2370  if (xri==1) return;
2371  ++lap;
2372  if (!cnr) ++cnr;
2373  pr_ct(1);
2374  crl=lap=hdl;
2375  lop=0;
2376  pr_foot();
2377  form_brk();
2378  cont_card(); /*stop();*/
2379  c_init(hdl);
2380  return;
2381  /* $$950512 ^^^^^^^^^^^^ NEU */
2382  }
2383 // if(stream==stdout) return;
2384  while (ln++<xlm+xl2)
2385  {
2386  outChar('\r');
2387  outChar('\n');
2388  }
2389  if (xfc) ++xfc;
2390  pghf(0); /* foot */
2391  pr_cso(xfs); /* page feed */
2392  ln=0; /*$$950520 umgeordnet! erste Seite sonst laenger*/
2393  pghf(1); /* head of page */
2394  pr_fixo(repfix);
2395  return;
2396 }
2397 
2398 // Kopf- oder Fussabschnitt abarb., auch von aussen nutzbar
2399 
2400 void EXET::pghf(int hf) /* page or card head: hf=1 or foot: hf=0 */
2401 {
2402  int a,b,c,d,rc,rl,px,po;
2403  CHAR *p, *xk2, *xkh; /* PV $$950320 xkh*/
2404  if (Apgnb=='7') return; /*PV $$950328*/
2405 // Abschnitt vorhanden?
2406  if (xft==(CHAR *)nil && !hf) return;
2407  if (xhd==(CHAR *)nil && hf) return;
2408  xk2=xk1;
2409  xkh=xk; /* PV $$950320 xkh*/
2410  if (hf) xk1=xhd;
2411  else xk1=xft;
2412  xk=xk1; /* PV $$950320 xkh*/
2413  ftf=0;
2414  rl=crl;
2415  rc=crc;
2416  crc=0;
2417  po=pos; /* save these values */
2418  a=ami;
2419  b=cnr;
2420  c=lap;
2421  d=lop;
2422  p=ptx;
2423  px=pix;
2424  if (!hf || !xri)
2425  {
2426  ftf=hf+1; /* page head or foot */
2427  crl=ML;
2428  c_init2();
2429  }
2430  else
2431  {
2432  crl=0; /* card heading */
2433  c_init(0);
2434  if (xri) ftf=1;
2435  }
2436  lop=lap=0;
2437  /* ++reclv; */
2438 if(!tcn) c_init(0); // Sonst u.U. unkontrollierter Output
2439  if (!ch1) ch1=(CHAR *)" "; /* $$941011 Vorsichtsmassnahme */
2440  form_pr(0,0);
2441  /* --reclv; */
2442  if (hf) /* head */
2443  {
2444  if (xri)
2445  {
2446  hdl=rl=crl+1; /* for nxt card */
2447  hdc=crc;
2448  }
2449  }
2450  ftf=0;
2451  crl=rl;
2452  crc=rc; /* restore these values */
2453  ami=a;
2454  cnr=b;
2455  lap=c;
2456  lop=d;
2457  ptx=p;
2458  pix=px;
2459  pos=po;
2460  xk1=xk2;
2461  xk=xkh; /* PV $$950320 xkh*/
2462  return;
2463 }
2464 
2465 // Nach Aufbereitung: Zeile ausgeben
2466 // Dabei sind noch die Drucker-Ersatzdarstellungen zu verarbeiten
2467 void EXET::pr_ct1(int i) /* actually print 1 line *//* char set? */
2468 /* print-ersatz used here */
2469 {
2470  CHAR *adr;
2471  int m,k,n;
2472 // if (stream==stdin) return;
2473  adr=ct[i];
2474  if (!adr[xli] && i>=lap-1) /*$$950521 >= statt == */
2475  {
2476  m=-1; /* empty last line! */
2477  while (adr[++m]==' ');
2478  if (m==xli) return;
2479  }
2480  /* remsp(adr); */ /* remove trailing spaces */
2481  if (i!=ML-1)
2482  {
2483  if (xpx/* || stream!=stdout*/)
2484  {
2485  while ((k= *adr)!=NL)
2486  {
2487  if (adr[1] && k==255)
2488  {
2489  k= *(++adr);
2490  m=0;
2491  switch (k)
2492  {
2493  case 255: /* 255 1 -> 0 255 2 -> 254 255 3 -> 255 */
2494  k= *(++adr); /* 255 34 --> 34 255 39 --> 39 */
2495  /* if(k==1) { outChar(0); if(xll<=MC) *adr--=0; } */ /* $$29.1.93 */
2496  if (k==1) outChar(0); /* $$20.6.93 */
2497  else if (k<4) outChar(k+252);
2498  else outChar(k-1); /* quotes : sonst 35/40 statt 34/39*/
2499  break;
2500  case 7: /* print ersatz: alt table */
2501  ++m;
2502  case 6: /* print ersatz: normal table */
2503  ++adr;
2504  if (!m) k=10000+*adr+300*Gns;
2505  else k=20000+*adr+300*Gns; /* which tble? */
2506  m=0;
2507  while (m<phi && pi[m]!=k) ++m;
2508  if (m!=phi) pr_cso(pa[m]);
2509  break;
2510  case 252: /* #T command f. page break (Seitenumbruch-Steuerfolge) */
2511  repfix= *++adr; /* for page breaks! */
2512  break;
2513  } /* end switch */
2514  }
2515  else outChar(k);
2516 // if (stream!=stdout) // backsp
2517  {
2518  n=0;
2519  while (n<xbl) if (k==xpb[n++])
2520  {
2521  outChar(8);
2522  break;
2523  }
2524  }
2525  ++adr;
2526  }
2527  }
2528  else
2529  { /* if(stream!=stdout)*/
2530  while (*adr) outChar(*adr++);
2531 // else CPRINTF("%s",adr); // screen : Turbo-C for speed!!!
2532  }
2533  if (!xfl) ; /* cont outp */
2534  else
2535  {
2536  pr_cso(xle); /* ++ln; */
2537  }
2538  }
2539  if (i<ML) ++lop;
2540  return;
2541 }
2542 
2543 // Formularbruch
2544 void EXET::form_brk() /* finish current form / begin nxt form */
2545 { /* $$941122 xll>MC */
2546  ++fct;
2547  if (xll>MC) return;
2548  if (fct==xfn)
2549  {
2550  pr_cso(xfs); /* form separ at page */
2551  fct=0;
2552  }
2553  else pr_cso(xfb); /* form break */
2554  return;
2555 }
2556 
2557 
2558 
2559 // ***************************************
2560 // Datenfeld im aktuellen Datensatz suchen, fni = interne Nr. laut CFG
2561 // bzw. Sonderkategorien finden
2562 
2563 CHAR *EXET::ExFindKat(int fni,CHAR fmk,int crib) /* find kat fni with multcode fmk */
2564 /* ret: addr of kat or NULL */
2565 { /* NULL if < xks */
2566  static int i;
2567  static CHAR *adr;
2568  static int hi;
2569  adr=0;
2570  i=crib;
2571  hi= *(ga[crib]+1);
2572  if (fni<0) return(specl(-fni,fmk,crib)); /* 2049 = #ua */ /*KAT*/
2573  if (fni<3)
2574  {
2575  if (fni==2)
2576  if (ch2 && ch2!=(CHAR *)nil) return(ch2);
2577  else;
2578  else if (ch1) return(ch1);
2579  }
2580  while (i<gri && fni>gi[i] && *ga[i+1]!=RS) ++i; //$$990207 umgestellt
2581  while (fni==gi[i])
2582  {
2583  adr=ga[i];
2584  if (*ga[i]==RS)
2585  {
2586  if (i>crib)
2587  {
2588  i=0;
2589  adr=0;
2590  break;
2591  }
2592  else adr+=2;
2593  if (fni==3) break;
2594  }
2595  if (fni<3 || fmk==adr[tgl+1] || fmk=='.') break; /*KAT*/
2596  ++i;
2597  }
2598  if (fni==gi[i]) /* $$931004 neue Zeile */
2599  if (fni==3 && fmk>'/' && fmk<'7')
2600  if (fmk==adr[2]) return adr; // #u1 oder #u2 gefunden
2601  else return 0; /* #0.. */
2602  if (fni!=gi[i] || adr==0)
2603  {
2604  /* $$15.6.92 */
2605  if (/* !xmod ** && hi>1 // && */ ami) /* not on this level, look further up/down */
2606  {
2607  if (ami==1)
2608  {
2609  if (crib==cri_base) return 0;
2610  if (hi==2) crib=cri_base;
2611  else
2612  while (crib>0 && hi<= *(ga[crib]+1))
2613  {
2614  --crib;
2615  while (*ga[crib]!=RS) --crib;
2616  }
2617  }
2618  else
2619  {
2620  ++crib;
2621  while (*ga[crib]!=RS && crib<gri) ++crib;
2622  if (crib>=gri) return 0; /* $$940823 vorher ==gri */
2623  }
2624 
2625  adr=ExFindKat(fni,fmk,crib); /* recursive */
2626  return(adr);
2627  }
2628  else return 0;
2629  }
2630  if (fni!=gi[i]) return 0;
2631  if (hi>1 && ami) if (adr[1]=='%') return 0; /* subrec */
2632 
2633  curr_kn=i; // Normalfall, adr = #nnn
2634  return(adr);
2635 } // ENDE ExFindKat()
2636 
2637 
2638 // ********* Sonderkategorien (auch #u-Variablen) finden bzw. erstellen
2639 CHAR *EXET::specl(int fni,CHAR fmk,int cris) /* special kats for output */
2640 {
2641  CHAR *ax, *ax1;
2642  long k=xCount;
2643  int i=0, j=0;
2644 // ax=ax1=Aextra+strlen(Aextra)+1;
2645  ax=ax1=AExtra;
2646  if(curr_kat==ax) { strcpy(gx+20000,ax); } // #cc
2647  strcpy(ax1,"#xx000000"); // precaution
2648  ax1+=kfg->skt;
2649  *ax1=NL;
2650  switch (fni)
2651  { // 240 statt 253: $$980709
2652  case 240: /* #dt : date German #dts : date/time sortable, #zz = #dt */
2653  if (fmk=='s') SyTime(ax1);
2654  else SyDat(ax1);
2655  break;
2656  case 252: // #op : file name
2657  strcpy(ax1,Optor);
2658  break;
2659  case 241: // #fn : file name // $$970603 NEU
2660  if (Adn==-1)
2661  {
2662  ax=0;
2663  break;
2664  }
2665  else sprintf((char *)ax1,"%s_%d%c",((ABASE *)Abase[Adn])->dbN,rec->rFi,0);
2666  break;
2667  case 251: /* #cc : current category */ /*$$950512 : #cca */
2668 // if(fmk='a') ax=curr_kat-xks; else ax=curr_kat;
2669 if(curr_kat!=ax)
2670  if (fmk=='a')
2671  {
2672  strcpy(gx+20000,"xxxxxxxxxx");
2673  strcpy(gx+20000+xks,curr_kat);
2674  }
2675  else strcpy(gx+20000,curr_kat);
2676  strcpy(ax,gx+20000);
2677  break;
2678  case 250: /* #nr : rec # */ // $$981109 #nra = nachgeladener Satz
2679  if (fmk=='a')
2680  {
2681  if (rec->rNa) sprintf((char *)ax1,"%ld%c",rec->rNa,0); // write rec# to ax1
2682  else ax=0;
2683  }
2684  else sprintf((char *)ax1,"%ld%c",xrn,0); // write rec# to ax1
2685  break;
2686 // #ifdef ALCA
2687  case 247: // #ax : (MultiX) index file, default "d"
2688  {
2689 // extern void ixc(int,char *);
2690 // ixc(rec->Adn,(char *)ax1);
2691  if (Adn==-1)
2692  ax=0;
2693  else
2694  sprintf((char *)ax1,"%c", ((ABASE *)Abase[Adn])->aix);
2695 
2696  }
2697  break;
2698 // #endif
2699  case 249: /* #hi : hierarchy in multivol work */
2700  if (xri==2) i=1;
2701  else i=0;
2702  if (*(ga[cris]+1)>1/* && cris!=crix*/) /* is it a subrecord? */
2703  /*$$17.8.92, statt ax */
2704  {
2705  hier(ax1,i,cris,fmk);
2706  if (*ax1) ;
2707  else strcpy(ax1,"enth.: ");
2708  }
2709  else ax=0;
2710  break;
2711  case 248: /* #gt : supertitle */
2712  *ax1=NL;
2713  ax=0;
2714  i=0;
2715  if (*(ga[cris]+1)>1 && cris==cri) /* is it a sub-rec? */
2716  {
2717  k=cri;
2718  while (*(ga[--k]+1)!=1) ; /* go to level #00 */
2719  if (ga[k][3]!='2') while (ga[++k][1]!='2'); /* #20 */
2720  ax=ga[k];
2721  if (*ga[k]==RS) ax+=2;
2722  while ((ax1[i]=ax[i])!=NL) ++i;
2723  while (ga[k][1]!='4' && gi[k]>6) ++k; /* #2 */
2724  if (ga[k][1]=='4' && ga[k][2]=='0') /* #40 */
2725  {
2726  ax1[i]=' ';
2727  ax1[++i]='/';
2728  ax1[++i]=' ';
2729  ax1[++i]=NL;
2730  ax=ga[k]-i+xks;
2731  while ((ax1[i]=ax[i])!=NL) ++i;
2732  }
2733  ax1[i]=' ';
2734  ax1[++i]=';';
2735  ax1[++i]=' ';
2736  ax1[++i]=NL;
2737  hier(ax1+i,1,cris,' '); /* add hierarchy */
2738  ax=ax1; /* $$8.9.92 */
2739  }
2740  break;
2741  /* case 247: */ /* #cn : card # set position to current position */
2742  /* cnpos=ct[crl]+crc;
2743  ax=NULL;
2744  break;
2745  obsolete */
2746  case 246: /* #p0 : page# even */
2747  case 245: /* #p1 : odd */
2748  case 244: /* #p2 : any */
2749  sprintf((char *)ax1,"%d%c",xfc,0); // $$990806 %d statt %s
2750  j=xfc%2;
2751  i=fni%2;
2752  if (fni!=244 && i!=j) ax=0;
2753  break;
2754  case 243: /* #pa : actual page# */
2755  sprintf((char *)ax1,"%d",xfca);
2756  break;
2757  case 242: /* #w : set lines for heading of follow-up cards */
2758  if (xri)
2759  {
2760  hdl=crl+1;
2761  hdc=crc;
2762  }
2763  if (hdl>xfl-2) hdl=xfl-2; /* header too long, cut */
2764  ax=0;
2765  break;
2766  case 231: /* #ch : current heading from ak=... */
2767  strcpy(ax,curr_head);
2768  break;
2769  case 230: /* #mv : is it a multivol work? */
2770  i=crix;
2771  ax=0;
2772  while (++i<gri) if (*ga[i]==RS)
2773  {
2774  ax=ga[i]+2;
2775  break;
2776  }
2777  break;
2778  /* $$961207 NEU case 229: */
2779  case 229: /* #pz : number of current line */
2780  if (fmk=='0') UtKitoa(crl+1,ax1);
2781  else if (fmk=='1') UtKitoa(lap,ax1);
2782  else if (fmk=='2') UtKitoa(ln,ax1);
2783  else if (fmk=='p') UtKitoa(crc,ax1);
2784  break;
2785  default: /* #uax : user variables */
2786  /*$$950402: 2000 statt 155 */
2787  if (fni==2000) /* #u0x */ /* $$931212 neue #u-Kategorien */
2788  {
2789  static int field=0;
2790  switch (fmk)
2791  {
2792  // $$000425 da stand %s statt %d
2793  case '0':
2794  sprintf((char *)ax1,"%d%c",gri-cri,0);
2795  break;
2796 // $$960711: statt field=++cri;
2797  case '1':
2798  strcpy(ax,ga[cri0]+2);
2799  field=cri0;
2800  ++field;
2801  break;
2802  case '2':
2803  if (field<gri) strcpy(ax,ga[field++]);
2804  else return (CHAR *)nil;
2805  if (*ax==RS) return (CHAR *)nil;
2806  break;
2807  case '3':
2808  field=cri+1;
2809  while (*ga[field]!=RS && field<gri-1) ++field;
2810  strcpy(ax,ga[field]);
2811  break;
2812  }
2813  return ax;
2814  }
2815  i=UtFindX(fni,fmk,tgl);
2816  if (i==EOF) ax=0;
2817  else ax=fa[i];
2818  break;
2819  }
2820  return(ax);
2821 }
2822 
2823 // ****** Hierarchieangabe #hi
2824 void EXET::hier(CHAR *adr,int h0, int crih,CHAR fmk)
2825 /* write hierarchy to adr */
2826 /* h0=0: go back to crix; 1: to #00 */
2827 {
2828  int i,k,j,n,hi=0;
2829  int h[6];
2830  static char *x1, *x2;
2831  k=crih;
2832  i=j=n=0;
2833  if (!h0) h0= *(ga[cri_base]+1); /* or [crix] ?? */
2834  hi= *(ga[k]+1);
2835  *adr=NL;
2836  while (hi!=h0) /* get positions of #0. fields */
2837  {
2838  h[n]=k;
2839  ++n;
2840  do
2841  {
2842  --k;
2843  while (*ga[k]!=RS) --k;
2844  }
2845  while (hi<= *(ga[k]+1));
2846  hi= *(ga[k]+1);
2847  }
2848  while (--n>=0) /* copy their contents */
2849  {
2850  k=h[n];
2851  while (gi[k]<3) ++k;
2852 //sprintf((char *)adr,"n=%d,gi=%d,ga=%s",gi[k],ga[k]);
2853 //return;
2854  if (gi[k]<7 && strlen(ga[k])>3)
2855  {
2856  j=kfg->skt;
2857  if (*ga[k]==RS) j+=2;
2858  x1=(char *)ga[k]+j;
2859  if (*x1) /* any text? */
2860  {
2861  if (fmk==' ') /* #hi : parts preceding '=' */
2862  {
2863  strcat(adr,x1);
2864  if ((x2=strchr(adr,(int)'='))!=0) x2[-1]=0;
2865  }
2866  else /* #hi1 : parts behind '=' */
2867  {
2868  if ((x2=strchr(x1,(int)'='))!=NULL) x1=x2+1;
2869  if (*x1==' ') ++x1;
2870  strcat(adr,x1);
2871  }
2872  i=strlen(adr);
2873  if (i>0)
2874  {
2875  if (adr[i-1]=='.') adr[--i]=NL; /* remove '.' */
2876  adr[i++]=xkh;
2877  adr[i]=NL;
2878  }
2879  }
2880  }
2881  }
2882  if (adr[--i]==',') adr[i]=NL;
2883  return;
2884 }
2885 
2886 // Zwischenteil ausgeben
2887 int EXET::pr_fix(int nr) /* srch and print a fix */
2888 /* return 1:subroutine 0:fix */
2889 {
2890  if (nr==1) return 0;
2891  if (nr==255)
2892  {
2893  cpc(13);
2894  return 0;
2895  }
2896  if (nr>128)
2897  {
2898  subroutine((CHAR)nr-1);
2899  return 1;
2900  }
2901  if ((nr=findfix(nr))!=EOF) pr_cs(pa[nr]);
2902  return 0;
2903 }
2904 
2905 int EXET::pr_fixo(int nr) /* srch and print a fix : used for repfix only */
2906 /* return 0:subroutine 1:fix */
2907 {
2908  if (nr==1) return 1;
2909  if ((nr=findfix(nr))!=EOF) pr_cso(pa[nr]);
2910  return 1;
2911 }
2912 
2913 // Steuerzeichenfolge ausgeben
2914 void EXET::pr_cs(CHAR *adr) /* print text-related contr string */
2915 {
2916  int i= -1;
2917  CHAR co;
2918  int k,f;
2919  while ((co=adr[++i])!=NL)
2920  {
2921  if (co!=QT && co!='\47')
2922  {
2923  if (co==255)
2924  {
2925  if (adr[i+1]==1) break; /* 255 1 ends contr.string */
2926  if (adr[i+1]==254)
2927  {
2928  ctrl_cmd(adr[i+2],adr[i+3]);
2929  i+=3;
2930  continue;
2931  }
2932  else
2933  {
2934  cpc(255);
2935  cpc(255);
2936  i+=2;
2937  co=adr[i];
2938  }
2939  }
2940  cpc(co);
2941  if (adr[i+1]==127) /* factor */
2942  {
2943  f=adr[i+2];
2944  while (--f) cpc(co);
2945  i+=2;
2946  }
2947  }
2948  /* QT */
2949  else
2950  {
2951  k=pr_cs1(adr+i+1,co);
2952  if (adr[i+k+1]==127) /* factor */
2953  {
2954  f=adr[i+k+2];
2955  while (--f) pr_cs1(adr+i+1,co);
2956  i+=2;
2957  }
2958  i+=k;
2959  }
2960  }
2961  return;
2962 }
2963 
2964 // Textzeichenfolge ausgeben, dabei u.U. Zeilenbruch
2965 int EXET::pr_cs1(CHAR *adr, CHAR co) /* QT output, special regard to line breaking */
2966 /* this is the quote character, " or ' */
2967 {
2968  int i=0;
2969  int k=0;
2970  CHAR *a;
2971  /* !crc ersetzt durch crc==xli $$950428 */
2972  if (xll<=MC) /* $$960429 Punkt am Ende beseitigen, aber nicht bei zl=0 */
2973  {
2974  if (*adr=='.') if (crc==xli || ct[crl][crc-1]=='.') ++adr,++k;
2975  /* crc>1 ersetzt durch crc>xli+1 $$950428 */
2976  else if (crc>xli+1 && ct[crl][crc-1]==' ' && ct[crl][crc-2]=='.') ++adr,++k;
2977  }
2978  a=Awx;
2979  while ((a[i]=adr[i])!=co && a[i]) ++i;
2980  a[i]=NL;
2981  k+=i;
2982  /* $$950509: NL strchr */
2983  while (*a!=NL && strchr(".,;- :)>]",*a))
2984  {
2985  cps(*a);
2986  ++a;
2987  }
2988  /* no line breaking before punctuation */
2989  i=xpy;
2990  xpy=0; /* don't decode fix texts */
2991  /* $$950509 : a-1!=co */
2992  if (*a!=NL) cpr(a,0); /* this is the main part !!! */ /*$$950502 ,0 */
2993  xpy=i; /* reset */
2994  return k+1; /* len of str in quotes +1 */
2995 }
2996 
2997 // Hier nur die formularbezogenen Steuerzeichenfolgen, kein & % $ #
2998 void EXET::pr_cso(CHAR *adr) /* print form-related contr string */
2999 /* ctrl-cmds &%$# not allowed here */
3000 { /* 255 255 1 changed to 0 */
3001  CHAR co;
3002  int f,k;
3003 // if(stream==stdin) return;
3004  while ((co= *adr++)!=NL)
3005  {
3006  if (xpy/* || stream==PRT1*/)
3007  {
3008  if (co!=QT && co!='\47')
3009  {
3010  if (co==255) if (adr[0]==254)
3011  {
3012  if (adr[1]=='h')
3013  {
3014  co=ga[cri0][1]+adr[2]-1;
3015  outChar(co);
3016  adr+=3;
3017  continue;
3018  }
3019  else ++adr;
3020  continue; /* ignore other formatting */
3021  }
3022  else
3023  {
3024  ++adr;
3025  co=(*adr++)-1;
3026  if (co==1) co=254;
3027  if (co==2) co=255;
3028  }
3029  outChar(co);
3030  if (*adr==127) /* factor */
3031  {
3032  f= *++adr;
3033  while (--f) outChar(co);
3034  ++adr;
3035  }
3036  }
3037  else
3038  {
3039  k=pr_cs2(adr,co);
3040  if (adr[k+1]==127)
3041  {
3042  f=adr[k+2];
3043  while (--f) pr_cs2(adr+1,co);
3044  adr+=2;
3045  }
3046  adr+=k+1;
3047  }
3048  } /* $$941213 */
3049  else if (co=='\n' || co=='\r') outChar(co);
3050  if (co=='\n'/* && stream!=stdout*/) ++ln;
3051  }
3052  return;
3053 }
3054 
3055 // Textzeichenfolge zum Drucker/Datei
3056 int EXET::pr_cs2(CHAR *adr, CHAR co) /* QT-string to prn */
3057 /* line breaking not relevant */
3058 {
3059  CHAR a;
3060  int i=0;
3061  while ((a= *adr++)!=co && a!=NL)
3062  {
3063  ++i;
3064  outChar(a);
3065  }
3066  return i; /* len of string */
3067 }
3068 
3069 // Ein Steuerzeichen in den Output schreiben
3070 void EXET::cpc(CHAR co) /* get 1 ctrl char out to ct[] */
3071 // but don't raise counter
3072 {
3073  if (co==CR/* && xll<=MC*/)
3074  {
3075  nxtlin(); /* line overflow! */
3076  if (crc>xli) nxtlin();
3077  }
3078  else if (xpy)
3079  {
3080  ct[crl][crc]=co;
3081  cp[crl][++crc]=cp[crl][crc-1];
3082  if (xll>MC) ct[crl][crc]=NL; /* continuous output */
3083  }
3084  return;
3085 }
3086 
3087 void EXET::cps(CHAR co) /* get 1 char out (screen) */
3088 /* AND raise counter for line breaking! */
3089 {
3090  switch (co)
3091  {
3092  case CR:
3093 // if(xll<=MC) { nxtlin(); if(crc>xli) nxtlin(); break; } // line overflow!
3094  // else ; // flowthru if no line breaking!
3095  default:
3096  ct[crl][crc++]=co;
3097  cp[crl][crc]=cp[crl][crc-1]+1;
3098  if (xll>MC) ct[crl][crc]=NL;
3099  break;
3100  }
3101  return;
3102 }
3103 
3104 // Abarbeitung einer Spezif. in {...}, z.B. #t{ ... } oder p{...},
3105 // aber ausserhalb Quotes
3106 void EXET::ctrl_cmd(CHAR cm, CHAR co) /* cm= J $ % & # h s N t k */
3107 {
3108  int i, k;
3109  --co; /* is 1 too large */
3110  switch (cm)
3111  {
3112  case 'J': /* ak=nn+xi : Schl. soll ins Reg. i $$051008 */
3113  cps(rG[0]);
3114  if (rG[1]>1) cps(rG[1]);
3115  else if (co>1) cps(co+1);
3116  else cps('1');
3117  break;
3118  case '$': /* goto 1st line */
3119  cps(' '); /* add a space at end of current line */
3120  /* nxtlin(); */
3121  crl=0;
3122  co=xli;
3123  /* flothru */
3124  case '&': /* TAB function: move to this position in output line */
3125  i=0;
3126  while ((cp[crl][i])<co && ct[crl][i]!=NL) ++i;
3127  if (ct[crl][i]==NL)
3128  {
3129  if (!i) k=1;
3130  else k=cp[crl][i-1]+1;
3131  while (k<co)
3132  {
3133  cp[crl][i]= k++;
3134  ct[crl][i]=' ';
3135  ++i;
3136  }
3137  cp[crl][i]=k;
3138  ct[crl][i]=NL;
3139  }
3140  crc=i;
3141  break;
3142  case '%': /* adjust line length to co */
3143  if (co) xll=co;
3144  else xll=xl;
3145  break;
3146  case '#': /* adjust indentation to co */
3147  /* if > line len: indent to end of current line (#250) */
3148  if (co<xll) xli=co;
3149  else xli=cp[crl][crc]-1;
3150  if (xli>xll-8) xli=xll-8; /*$$ 18.8.92 um groessere Einrueckung zu erlauben */
3151  break;
3152  case 'h': /* add co to hierarchy byte */
3153  co+= *(ga[cri0]+1);
3154  cps(co);
3155  break;
3156  case 's': /* $$950514 NEU */
3157  xks=co;
3158  break;
3159  case 'N': /* new page */
3160  nwpag();
3161  break;
3162  case 't':
3163  pr_fix(co+1); /* insert fix# co here */
3164  break;
3165  case 'K': /* Card# XXX noch noetig?
3166  UtKitoa(cnr,pend+2);
3167  cps(pend[2]); if(pend[3]) { cps(pend[3]); if(pend[4]) cps(pend[4]); }
3168  */
3169  break;
3170  default:
3171  break;
3172  }
3173  return;
3174 }
3175 
3176 // Zwischenteil finden
3177 int EXET::findfix(int nr) // find fix #nr in phrase space
3178 {
3179  int p=phi-1;
3180  nr+=999+Gns*400; // fix numbers are 1000+Gns*400+j
3181  while (p>=0 && pi[p]!=nr) --p;
3182  if (pi[p]==nr) return p;
3183  else return EOF;
3184 }
3185 
3186 void EXET::c_init(int i) // init print area, set strings to 0
3187 {
3188  int j=0;
3189  while (j<MC) ct[i][j++]=NL; // clr 1st line
3190  while (i<ML-1)
3191  {
3192  ct[i][0]=NL;
3193  cp[i++][0]=1;
3194  }
3195  nlfl=0;
3196  return;
3197 }
3198 
3199 void EXET::c_init2(void) // init foot area, 2 lines
3200 {
3201  int i=0;
3202  while (i<MC)
3203  {
3204  ct[ML][i]=ct[ML+1][i]=NL; // clr 1st line
3205  ++i;
3206  }
3207  i=ML;
3208  while (i<ML+2) cp[i++][0]=1;
3209  return;
3210 }
3211 
3212 /*
3213  Copyright 2011 Universitätsbibliothek Braunschweig
3214 
3215  Licensed under the Apache License, Version 2.0 (the "License");
3216  you may not use this file except in compliance with the License.
3217  You may obtain a copy of the License at
3218 
3219  http://www.apache.org/licenses/LICENSE-2.0
3220 
3221  Unless required by applicable law or agreed to in writing, software
3222  distributed under the License is distributed on an "AS IS" BASIS,
3223  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3224  See the License for the specific language governing permissions and
3225  limitations under the License.
3226 */
3227