a99  V32.6
allegro Windows Hauptprogramm
 Alle Klassen Dateien Funktionen Variablen Typdefinitionen Aufzählungen Aufzählungswerte Makrodefinitionen
rpnfind.cpp
gehe zur Dokumentation dieser Datei
1 // RPNFIND.CPP ve 980930. ACHTUNG: acon-Version siehe avfind.cpp
2 // 2002 : ho und ve, spaeter bu
3 // Aenderungen: //XX ev
4 // strnicmp() statt strncmp !
5 
6 #include "program.h"
7 #include "platform.h"
8 
9 #ifdef AVANTI
10 #include "avinc.h"
11 #endif
12 
13 
14 #include <windows.h>
15 
16 // #define AV_WRITE // Schreibfunktionen sollen kompiliert werden
17 // wegnehmen, wenn Version ohne Schreibf. gewuenscht ist
18 // #undef NO_EXT_KEYS // 2 Zeilen, die fuer WATCOM noetig sind
19 
20 
21 #include "konfig.hpp" // Konfiguration
22 
23 #include "exet.hpp" // Exportparameter
24 
25 #include "record.hpp" // Datensatz
26 
27 #include "index.hpp" // Indexdatei
28 
29 #include "abase.hpp" // Datenbank
30 
31 #ifdef AVANTI
32 #include "avanti.hpp" // allgemeine Deklarationen und Definitionen
33 #endif
34 
35 #include "rpnfind.hpp"
36 #include "parser.hpp"
37 #include "a99.h"
38 
39 
40 // Globale Variablen
41 extern int Rmod; // Flag Restriktion ein/aus
42 extern int codflag; // Umkodierung ja (1) /nein (0)
43 extern int accu; // Berechtigung des Users 0<=accu<=3
44 extern long anzErg; // Anzahl der Treffer
45 extern CHAR restri[]; // current restriction $$970405 NEU
46 extern CHAR ixname[]; // Indexname als default
47 //XX statt *ixname
48 
49 ABASE *Bank; // Datenbankobjekt
50 //XX Bank statt BANK
51 
52 //XX extern void E3Coding(CHAR *,int); // Umkodierung
53 
54 //XX extern void Info(ABASE *,int md=3); // Info ueber Datenbank zeigen
55 
56 
57 int GetRegisterNummer(CHAR *Register,int accu);
58 char* GetRestrictArgument(char*buffer,char*argument);
59 long FindCommand(char *eing, RECNR *pResultSet,RECNR lRes, RECNR lMaxRes);
60 void ResetResult( RECNR* pResultSet,long lMaxRes );
61 long Ergebnis(long maxr, CHAR *eingabe,RECNR *pResultSet);
62 int strip(CHAR* suchwort,int iPos=0);
63 
64 
65 
66 
67 //****************************************************************
68 
69 char esp; // fuer Mehrfachspatien-Ersatzcode
70 
71 long NewSearch(char *eing, RECNR *pResultSet,long lMaxRes, char ex='!')
72 // Variablen: eing: Suchstring, z.B. "( PER goethe? or TIT faust ) and TIT weimar?
73 // pResultSet: Vektor Satznummern; pResultSet=new RECNR[lMaxRes];
74 // lMaxRes: Maximale Groesse des Ergebnisvektors
75 // ex: Code fuer Mehrfachspatien [uebergeben wird i.d.R. Code 7 ]
76 // Rueckgabe: Anzahl der Treffer, -1:zu viele, 0:nichts
77 {
78  int string_pos=0,index_pos;
79  long lRes=NO_SEARCH;
80  BOOL bRestriction=FALSE;
81  char* suchstring,*lpExtract=NULL;
82  extern a99 *dlg;
83  Bank=dlg->Bank;
84  esp=ex;
85  // kommt space " vor? Dann " anhaengen
86 // if(strstr(eing," \"") && eing[strlen(eing)-1]!='"') strcat(eing,"\"");
87 
88 // faengts mit einem Befehlswort an? wegnehmen
89 
90  if (!strnicmp(eing,"and ",4)) strcpy(eing,eing+4);
91  else if (!strnicmp(eing,"or ",3)) strcpy(eing,eing+3);
92  else if (!strnicmp(eing,"not",3)) strcpy(eing,eing+4);
93  Parser parser(eing);
94 
95  RStack *keller;
96  ResultElem *pResElem,*pReturnElem;
97  keller=(RStack*)new RStack(Bank,restri,lMaxRes);
98  pResElem=(ResultElem*)new ResultElem(lMaxRes);
99  if (keller ==(RStack*)NULL)
100  {
101  sprintf(Aerror,"Error:can't create result stack!");
102  return NO_RESULT;
103  }
104 
105  parser.form_rpn_query();
106 
107 //test
108 // sprintf(Aerror,"postf=%s, query=%s",parser.postfix_str,parser.query); return NO_RESULT;
109 
110  while ((unsigned)string_pos != strlen(parser.postfix_str))
111  {
112  switch (parser.postfix_str[string_pos])
113  {
114  case '+': // or- Verknuepfung
115  pReturnElem=keller->or(pResultSet);
116  if (pReturnElem!=(ResultElem*)NULL)lRes=pReturnElem->lNum;
117  break;
118  case '-': //not-Verknuepfung
119  pReturnElem=keller->not(pResultSet);
120  if (pReturnElem!=(ResultElem*)NULL)lRes=pReturnElem->lNum;
121  break;
122 
123  case '*':// and - Verknuepfung
124  pReturnElem=keller->and(pResultSet);
125  if (pReturnElem!=(ResultElem*)NULL)lRes=pReturnElem->lNum;
126  break;
127  default: // einzelnes find-ARGUMENT
128  index_pos=parser.postfix_str[string_pos]-'0';
129  if (index_pos>=0 && (suchstring=parser.GetArgument(index_pos))!=NULL)
130  {
131  if (!strncmp(suchstring, "#u",2))suchstring=extract(suchstring,&lpExtract);// find-Argument steht in #uxy
132  if ((bRestriction=IsItRestriction(Bank, suchstring))==FALSE)
133  lRes=FindCommand(suchstring, pResultSet,lRes,lMaxRes);
134  keller->push(pResultSet,suchstring,bRestriction);
135  }
136  else
137  {
138  sprintf(Aerror,"Error:unknown command in: %s",eing);
139  delete keller;
140  return(FALSE);
141  }
142  break;
143  }
144  string_pos++;
145 
146  } // Ende: while()
147  keller->pop(pResElem);
148 
149  if (pResElem)
150  {
151  if (pResElem->bRestriction)
152  {
153  Rmod=keller->Restriction(pResElem,'A');
154  lRes=pResElem->lNum;
155  }
156  else if (pResElem->lNum>=0 && lRes!= NO_SEARCH)
157  {
158  memcpy(pResultSet,pResElem->pResultSet,lMaxRes*sizeof(RECNR));
159  lRes=pResElem->lNum;
160  }
161  }
162  if (lpExtract)delete[]lpExtract;
163  delete keller;
164  delete pResElem;
165  if (lRes==lMaxRes-1) // $$961001 zuviel gefunden
166  {
167  sprintf(Aerror,"%5ld : %s\n",lRes,eing); //test Zwischenergebnis
168  return -1; // that means too many
169  }
170  return lRes;
171 }
172 
173 
174 
175 /*************************************************************/
176 // Abarbeitung _eines_ eingegebenen Suchbefehls
177 // $$970405 Aenderungen wg restric
178 
179 /*************************************************************/
180 long FindCommand(char *eing, RECNR *pResultSet,RECNR lRes, RECNR lMaxRes)
181 // z.B. eing= per goethe?
182 // wenn rnu>0, dann wird die Erg.Menge in result weiter veraendert!
183 {
184  CHAR *sstr=(CHAR *)NULL, *sst=(CHAR *)NULL;
185  RECNR rnum=0; // Startpunkt in result[]
186  int i,j,k;
187  i=j=0;
188  ResetResult(pResultSet,lMaxRes); // result[] zuruecksetzen
189  lRes=0L;
190  if (!strncmp(eing+j,"*new",4))
191  {
192  *restri=0;
193  j+=4;
194  return((lRes=NO_SEARCH));
195  }
196  // faengt Befehl mit Operator an?
197 
198  sst=sstr=(CHAR *)new CHAR[strlen(eing)+5]; //$$051123 5 statt 3
199  if (sstr)
200  {
201 
202  *sst=0;
203  if (eing[j])
204  {
205  i=0;
206  k=0;
207  RECNR rnr;
208  switch (eing[j])
209  {
210  case '#':
211  strip((CHAR*)eing);// fuehrende Leerz. und Anfuehrungsz. beseitigen
212  i=j+1;
213  while (eing[i]==' ') i++;
214  while (eing[i] && lRes < lMaxRes)
215  {
216  rnr=atol((char*)eing+i);
217  if (Bank->AbRecChk(rnr)>0) pResultSet[lRes++]=rnr;
218  if (pResultSet[anzErg]>0)anzErg++;
219  while (eing[i] && eing[i]!=',' && eing[i]!='-') ++i;
220  if (eing[i]=='-') // find ... #nnn-mmm
221  {
222  ++i;
223  rnr=pResultSet[lRes-1L];
224  long bis=atol((char *)eing+i)+1L;
225  while (++rnr<bis && lRes<lMaxRes)
226  {
227  if (Bank->AbRecChk(rnr)>0)
228  {
229  pResultSet[lRes++]=rnr;
230  ++anzErg;
231  }
232  }
233  while (eing[i] && eing[i]!=',') ++i;
234  }
235  if ( eing[i] ) i++;
236  }
237  delete[]sstr;
238  return lRes;
239  break;
240  case '|': // |i statt RegName
241  strcpy(sst,eing+j);
242  strncpy((char *)ixname,(char *)sst,3); // aufbewahren fuer wiederholung
243  break;
244  case '~': // ~zi statt RegName MultiX
245  strcpy(sst,eing+j);
246  strncpy((char *)ixname,(char *)sst,4); // aufbewahren fuer wiederholung
247  break;
248  default:
249  while (isalnum(eing[j])) sst[i++]=toupper(eing[j++]); // per -> PER
250  sst[i++]=' ';
251  sst[i]=0;
252 
253  while (k<Bank->tnix) // beginnt eingabe mit gueltigem Indexnamen?
254  {
255  if (strnicmp((char *)sst,Bank->InamE[k],4)) ++k;
256  else // gueltiger Indexname: nach ixname kopieren
257  {
258  strncpy((char *)ixname,(char *)sst,4); // fuer den naechsten Befehl auf Reserve
259  break;
260  }
261  }
262  if (k==Bank->tnix)
263  { // kein gueltiger Indexname
264 // j-=i; if(j==-1) j=0; strncpy((char *)sst,(char *)ixname,4);
265 // sst[4]=0; //XX NEU sonst sst evtl. zu lang
266 // NEU: 0 zurueckgeben, nicht stillschweigend den vorigen nehmen! $$051222
267  delete[]sstr;
268  return 0;
269  } // dann den vorigen nehmen
270  strcpy(sst+strlen(sst),eing+j);
271  break;
272  } //Ende: switch()
273 
274  lRes=Ergebnis(lMaxRes-1,sst,pResultSet); // elementaren Befehl ausf.
275  }
276  delete[]sstr;
277  } //ende if(sstr)
278  return lRes;
279 }
280 
281 
282 // Elementaren Suchbefehl in eingabe ausfuehren,
283 // Ergebnisse ab result[rnum] eintragen
284 // eingabe: XXX string (XXX = Registername
285 // oder: |istring i = Registernummer
286 // oder: ~zistring z = indexfile .AzX MultiX
287 // return: Anzahl Ergebnisse;
288 // 0: nichts
289 // -1: zuviel (result[] zu klein)
290 //
291 
292 long Ergebnis(long maxr, CHAR *eingabe,RECNR *pResultSet)
293 {
294  int i=0,ulen=0, res=NO_RESULT, expmd=0,iRegistNr=0; // $$970404 expmd NEU fuer SR
295  char sc,*ptr,*lpExtract=NULL; // auxil
296  int tmd; // 1: Trunc 0:precise
297  CHAR *sstr=(CHAR *)NULL,*sst=(CHAR *)NULL,*temp=(CHAR *)NULL; // srch string
298  CHAR *kom=(CHAR *)NULL; // command string
299  int len=strlen(eingabe)+2;
300  kom=(CHAR*)new CHAR[len];
301  sstr=(CHAR*)new CHAR[len];
302 
303 
304 //test Aerror wird dann in a99 angezeigt!
305 // sprintf(Aerror+strlen(Aerror)," -- %s",(char *)eingabe);
306  if (kom && sstr)
307  {
308  sst=sstr;
309  *sstr=0;
310  *kom=0;
311  strcpy(kom,eingabe); // $$9970922 ab hier *kom statt *eingabe
312  // $$970922 : find #uxy ermoeglichen:
313  if (ptr=strstr(kom, "#u")) ptr=extract(ptr,&lpExtract); // Anvendervariable #uxy im Eingabestring suchen
314 
315  if (*kom!='|') // $$060425
316  while (kom[i] && kom[i]!=' ')
317  {
318  kom[i]=toupper(kom[i]);
319  ++i;
320  }
321  if ((ptr=strchr(kom,' '))!=NULL && *(ptr+1) && strlen(ptr+1)>0)
322  {
323  strcpy(sstr,ptr+1);
324  *ptr=0;
325  strip(sstr);// Anfuehrungszeichen entfernen
326  }
327  else
328  {
329  delete[]kom;
330  delete[]sstr;
331  return res; // kein Suchbegriff folgt
332  }
333  while (*sst==' ') ++sst;
334  if (*sst=='"')
335  {
336  ++sst;
337  sc='"';
338  }
339  else if (*sst==39)
340  {
341  ++sst;
342  sc=39;
343  }
344  else sc=0;
345  if (*sst=='&')
346  {
347  expmd=*sst++; // $$970404 NEU $$060425 verschoben
348  }
349  i=0;
350  if (sc)
351  {
352  while (sst[i] && sst[i]!=sc) ++i; // $$060425
353  sst[i--]=0;
354  }
355  else i=strlen(sst)-1;
356  if (sst[i]=='?')
357  {
358  tmd=1;
359  sst[i]=0;
360  }
361  else tmd=0; // '?' am Ende: Trunc
362  while (sst[i]==' ') sst[--i]=0; // Leerz.am Ende weg
363  i=0; // $$981221 : sst,0,1 !
364  if (codflag) Bank->E3Coding(sst,0,1); //ANSI->ASCII XX
365  if (strchr(sst+1,esp))
366  // $$ 2002-11-09 NEU, ! zum Maskieren von Leerz. im Suchstring
367  {
368  while (sst[++i]) if (sst[i]==esp) sst[i]=' '; // esp = Ersatzzeichen fuer Mehrfachspatien
369  }
370  i=0;
371  if (*kom=='|') // MultiX
372  Bank->InSwix(Bank->ixf[kom[1]-49]);
373  if (*kom=='~') // MultiX
374  {
375  Bank->InSwix(kom[1]);
376  *kom='|';
377  strcpy(kom+1,kom+2);
378  }
379  if (*kom=='|')
380  {
381  iRegistNr=GetRegisterNummer(kom+1,accu);
382  if (iRegistNr)
383  {
384  if (!Rmod)
385  res=Bank->InGetSet(iRegistNr,(char *)sst,tmd,maxr,pResultSet,0,0/*rex0*/);
386  else
387  res=Bank->InGetSet(iRegistNr,(char *)sst,tmd,maxr,pResultSet,restri,0/*rex0*/);
388  }
389  }
390  else // logischer Registername
391  {
392  char *iz; // MultiX
393  while (i<Bank->tnix) // beginnt eingabe mit gueltigem Indexnamen?
394  {
395  if (strnicmp((char *)kom,Bank->InamE[i],3)) ++i; // InamE = REG iPref (.ADX)
396  else // oder REG zipref (.AzX)
397  {
398  if ((temp=(CHAR*)new CHAR[strlen(sst)+1])!=(CHAR*)NULL)
399  {
400  iz=Bank->InamE[i]+4;
401  memcpy(temp,sst,strlen(sst)+1);
402  if (*iz>'Z') Bank->InSwix(*iz++); // REG zipref MultiX
403  else Bank->InSwix('d'); // REG ipref
404  // $$19990323 ve: Speicherbereich fuer Registerpraefix vergroessern
405  sst=sstr=(CHAR*)realloc(sstr,len+strlen(iz));
406  sprintf((char*)sst,"%s%s%c",iz+1,temp,0); // bei virtuellen Registern Praefix vorsetzen
407  delete[]temp;
408  }
409  iRegistNr=GetRegisterNummer((CHAR*)iz,accu);
410  if (iRegistNr)
411  {
412  if (!Rmod)
413  res=Bank->InGetSet(iRegistNr,(char *)sst,tmd,maxr,pResultSet,0,0/*rex0*/);
414  else
415  res=Bank->InGetSet(iRegistNr,(char *)sst,tmd,maxr,pResultSet,restri,0/*rex0*/);
416  }
417 //test sprintf(Aerror+strlen(Aerror),"sst=%s, maxr=%d, res=%d\n",(char *)sst,maxr,res);
418  break;
419  }
420  } // ende while()
421  if (i==Bank->tnix) // kein gueltiger Indexname
422  {
423  sprintf(Aerror,"Suchbefehl: %s nicht korrekt%c",kom,0);
424 //XX Info(Bank,2);
425  }
426  } // ende else
427 
428  if (res>0 && expmd!=0) res=Bank->InExpand(maxr,pResultSet,res); // $$970404 NEU
429 
430  delete[]kom;
431  delete[]sstr;
432  if (lpExtract)delete[]lpExtract;
433  }
434  return res;
435 }
436 
437 // Registernummer ermitteln
438 // Fuer das Register 11 ist die Anwenderberechtigung 3 erforderlich
439 int GetRegisterNummer(CHAR *Register,int accu)
440 {
441  int iRegist=0;
442  if (Register[0]=='|')Register++; // |RegNr ausschalten
443  switch (Register[0])
444  {
445  case '1':
446  switch (Register[1])
447  {
448  case '0':
449  iRegist=10;
450  break;
451  case '1':
452  if (accu>=0) iRegist=11;
453  break;
454  default:
455  iRegist=1;
456  break;
457  }
458  break;
459  case '2':
460  case '3':
461  case '4':
462  case '5':
463  case '6':
464  case '7':
465  case '8':
466  case '9':
467  case ':':
468  iRegist=Register[0]-'0';
469  break;
470  case ';': // Register 11 auf die konvenionelle Art deklariert
471  if (accu>=0) iRegist=11;
472  break;
473  }
474  return iRegist;
475 }
476 
477 /*************************************************************/
478 // $$ 980115 ve: Argument für den find-Befehl aus der
479 // Anwendervariablen "#uxy" auspacken.
480 char* extract(char* lpUxy, char** ppExtract)
481 {
482  CHAR *ptr;
483  int ulen,len;
484  ulen=strlen(lpUxy);
485  if (ptr=UtFind(lpUxy))
486  {
487  len=strlen(ptr);
488  *ppExtract=new char[len-ulen+1];
489 // Anfang "#uxy" aus "#uxyBelegung" abschneiden
490  memmove(*ppExtract,ptr+ulen,min(L_STRING-6,len-ulen));
491  (*ppExtract)[len-ulen]=0;
492  }
493  return *ppExtract;
494 }
495 /****************************************************************/
496 char* GetRestrictArgument(char* buffer,char* argument)
497 {
498  int i=0;
499  char relation[3];
500  memset(relation,0,3);
501  while(*argument==' ') ++argument; // Leerzeichen entf.
502  i=0;
503  do
504  {
505  if (*argument=='=' ||*argument=='>' ||*argument=='<' ||*argument=='!')
506  relation[i]=*argument;
507  else break;
508  }
509  while (i++<2 && *(++argument)!=0);
510  while (*argument==' ') ++argument; // Leerzeichen entf.
511  sprintf(buffer,"%s%s",relation,argument);
512  return buffer;
513 }
514 
515 /****************************************************************/
516 BOOL IsItRestriction(ABASE *Bank, char* argument)
517 {
518  int m=0; // gueltige Restriktion? z.B. erj >1990
519  BOOL bRestriction=FALSE;
520  while (m<Bank->ress)
521  { // restrics = rpXXX0rpXXX0... r=r/s, p=position
522  if (strnicmp((char *)argument,(char *)Bank->restrics+m*6+2,3)) ++m;
523  else
524  {
525  bRestriction=TRUE;
526  break;
527  }
528  }
529  return(bRestriction);
530 }
531 /****************************************************************/
532 int WhichRestr(ABASE *Bank, char* argument)
533 {
534  int m=0; // gueltige Restriktion? z.B. erj >1990
535  int bRestriction=-1;
536  while (m<Bank->ress)
537  { // restrics = rpXXX0rpXXX0... r=r/s, p=position
538  if (strnicmp((char *)argument,(char *)Bank->restrics+m*6+2,3)) ++m;
539  else
540  {
541  bRestriction=m;
542  break;
543  }
544  }
545  return(bRestriction);
546 }
547 
548 void ResetResult( RECNR* pResultSet,long lMaxRes )
549 {
550 //XX unnoetig??
551  memset(pResultSet,0,lMaxRes*sizeof(RECNR));
552  anzErg=0;
553  return;
554 }
555 
556 
557 
558 int strip(CHAR* suchwort,int iPos)
559 {
560  UtRemspB((CHAR*)suchwort,32);//Leerzeichen am Anfang entfernen
561  UtRemsp(suchwort); // Leerzeichen am Ende entfernen
562  CHAR* ptr;
563  int len;
564  ptr=(CHAR*)strchr(suchwort,34);
565  if (ptr!=(CHAR*)NULL && ((iPos>=0)?ptr<=suchwort+iPos:1))
566  {
567  len=strlen(ptr)-1;
568  if (len>0 && ((ptr[0]=='"' && ptr[len]=='"') || (ptr[0]==39 && ptr[len]==39))) // '"' an erster UND letzer Position?
569  {
570  memmove( ptr, ptr+1, --len );
571  ptr[len--]=0;// trunc wurde insg. zweimal dekrementiert
572  return TRUE;
573  }
574  }
575  return FALSE;
576 }
577 
578 /******************************************************/
579 // Memberfunktionen der Klasse "ResultElem"= ein Element des Stacks //
580 
582 {
583  pNext= (ResultElem*)NULL;
584  pResultSet= (RECNR*)NULL;
585  lNum=0;
586  bSorted=FALSE;
587  argument=NULL;
588  lMaxRes=lMaxr;
589 }
590 
592 {
593  delete [] pResultSet;
594  delete [] argument;
595 }
596 
597 BOOL ResultElem::Initialize(char* Argument,BOOL bRestrict)
598 {
599  bRestriction=bRestrict;
600  if (bRestriction)
601  {
602  if ((argument=new char[strlen(Argument)+1])==NULL)return FALSE;
603  strcpy(argument,Argument);
604  }
605  else
606  {
607  if ((pResultSet=new RECNR[lMaxRes])== (RECNR*)NULL)return FALSE;
608  memset(pResultSet,0,lMaxRes);
609  }
610  return TRUE;
611 }
612 
614 {
615  if (pResultSet == (RECNR*)NULL) return FALSE;
616  memcpy(pResultSet,pSource,lMaxRes*sizeof(RECNR));
617  lNum=0;
618  while (lNum< lMaxRes && pResultSet[lNum]!=0)lNum++;
619  return TRUE;
620 }
621 
623 {
624 
625  if (pDestination->pResultSet==(RECNR*)NULL)
626  pDestination->Initialize(argument,bRestriction);
627  if (bRestriction==FALSE)
628  {
629  memcpy(pDestination->pResultSet,pResultSet,lMaxRes*sizeof(RECNR));
630  pDestination->lNum=lNum;
631  }
632  else pDestination->lNum=NO_SEARCH; // Restriction
633 
634  pDestination->bSorted=bSorted;
635 }
636 
637 // Die Nummern eines Resultsets aufsteigend ordnen
638 
639 int ascend(const void *Num1,const void *Num2)
640 {
641  return( *(long*)Num1 - *(long*)Num2);
642 }
643 
645 {
646  qsort(pResultSet,(size_t)lNum,sizeof(RECNR),ascend);
647  bSorted=TRUE;
648 }
649 
651 {
652  RECNR l=0,k=lNum,m;
653  if (!bSorted)Sort();
654  do
655  {
656  m=(l+k)/2;
657  if (pResultSet[m]>lRef)k=m-1;
658  else l=m+1;
659  }
660  while (pResultSet[m]!=lRef && l<=k && l<=lNum);
661 
662  if (pResultSet[m]==lRef)
663  return TRUE;
664  else return FALSE;
665 }
666 
667 //**********************************************************//
668 // Memberfunktionen der Klasse RStack = Stack als verkette Liste
669 
671 {
673  return( pStackBegin);
674 }
675 
677 {
678  ResultElem* pLast=pStackBegin,*pNew;
679  if ((pNew=(ResultElem*) new ResultElem(lMaxRes))== (ResultElem*)NULL ||
680  pNew->Initialize(pNeuElem->argument,pNeuElem->bRestriction) == FALSE)
681  {
682  ClearStack();
683  return( (ResultElem*)NULL);
684  }
685  else
686  {
687  pNeuElem->CopyResultElem(pNew);
688  pNew->pNext=pLast;
689  pStackBegin=pNew;
690  iCount++;
691  }
692  return pStackBegin;
693 
694 }
695 
696 ResultElem* RStack::push(RECNR* pResultSet,char* Argument,BOOL bRestrict)
697 {
698  ResultElem* pLast=pStackBegin,*pNew;
699  if ((pNew=(ResultElem*) new ResultElem(lMaxRes))== (ResultElem*)NULL ||
700  pNew->Initialize(Argument,bRestrict) == FALSE)
701  {
702  ClearStack();
703  return( (ResultElem*)NULL);
704  }
705  else
706  {
707  if (bRestrict==FALSE)
708  if (pNew->CopyResultSet(pResultSet)==FALSE)return((ResultElem*)NULL);
709  pNew->pNext=pLast;
710  pStackBegin=pNew;
711  iCount++;
712  }
713  return pStackBegin;
714 }
715 
717 {
718 
719  if (iCount<1)return (ResultElem*)NULL;
720  ResultElem* pNext=pStackBegin->pNext;
721  pStackBegin->CopyResultElem(pDestination);
722  delete pStackBegin;
723  pStackBegin=pNext;
724  iCount--;
725  return pDestination;
726 
727 }
728 
729 // Boolscher UND-Vergleich von den zwei letzten Ergebnismengen auf dem Stack.
730 // Die verknuepfte Ergenbnismenge wird wieder auf den Stack geschoben
732 {
733  ResultElem* pTemp=(ResultElem*)NULL,*pTemp2=(ResultElem*)NULL;
734  RECNR l,k=0L;
735  if ((pTemp=(ResultElem*) new ResultElem(lMaxRes))== (ResultElem*)NULL)
736  {
737  return( (ResultElem*)NULL);
738  }
739  else
740  {
741  if (pop(pTemp)==(ResultElem*)NULL)
742  {
743  delete pTemp;
744  return((ResultElem*)NULL);
745  }
746  if (pTemp->bRestriction)Restriction(pTemp,'A');
747  else if (pStackBegin->bRestriction)
748  {
749  if ((pTemp2=(ResultElem*) new ResultElem(lMaxRes))== (ResultElem*)NULL)
750  return( (ResultElem*)NULL);
751  pop(pTemp2);
752  push(pTemp);
753  Restriction(pTemp2,'A');
754  delete pTemp2;
755  }
756  else
757  {
758  for (l=0L; l<min(pStackBegin->lNum,lMaxRes); l++)
759  if (pTemp->BinSearch (pStackBegin->pResultSet[l])==TRUE)
761  pStackBegin->lNum=k;
762  pStackBegin->Sort();
763  memset(pStackBegin->pResultSet+k,0,lMaxRes-k);
764  memcpy(pResultSet,pStackBegin->pResultSet,lMaxRes*sizeof(RECNR));
765  }
766  delete pTemp;
767  return(pStackBegin); // erstes Element auf dem Stack zurueck
768  }
769 }
770 
771 // Boolscher ODER-Vergleich von den zwei letzten Ergebnismengen auf dem Stack.
772 // Die verknuepfte Ergenbnismenge wird wieder auf den Stack geschoben
774 {
775  ResultElem* pTemp=(ResultElem*)NULL;
776  RECNR l,k=0L;
777  if ((pTemp=(ResultElem*) new ResultElem(lMaxRes))== (ResultElem*)NULL)
778  {
779  return( (ResultElem*)NULL);
780  }
781  else
782  {
783  if (pop(pTemp)==(ResultElem*)NULL)
784  {
785  delete pTemp;
786  return((ResultElem*)NULL);
787  }
788  for (l=0L; l<min(pTemp->lNum,lMaxRes-1); l++)
789  {
790  // alle verschiedenen Nummern in pTemp->pResultset sortieren
791  if (pStackBegin->BinSearch (pTemp->pResultSet[l])==FALSE)
792  pTemp->pResultSet[k++]=pTemp->pResultSet[l];
793  }
794 
795  memcpy(pStackBegin->pResultSet+pStackBegin->lNum,pTemp->pResultSet,min(lMaxRes-1-pStackBegin->lNum,k)*sizeof(RECNR));
796  delete pTemp;
798  pStackBegin->Sort();
800  memcpy(pResultSet,pStackBegin->pResultSet,lMaxRes*sizeof(RECNR));
801  return(pStackBegin); // erstes Element auf dem Stack zurueck
802  }
803 }
804 
805 // Boolscher NOT-Vergleich von den zwei letzten Ergebnismengen auf dem Stack.
806 // Die verknuepfte Ergenbnismenge wird wieder auf den Stack geschoben
808 {
809  ResultElem* pTemp=(ResultElem*)NULL,*pTemp2=(ResultElem*)NULL;
810  RECNR l,k=0L;
811  if ((pTemp=(ResultElem*) new ResultElem(lMaxRes))== (ResultElem*)NULL)
812  {
813  return( (ResultElem*)NULL);
814  }
815  else
816  {
817  if (pop(pTemp)==(ResultElem*)NULL)
818  {
819  delete pTemp;
820  return((ResultElem*)NULL);
821  }
822  if (pTemp->bRestriction)Restriction(pTemp,'N');
823  else if (pStackBegin->bRestriction)
824  {
825  if ((pTemp2=(ResultElem*) new ResultElem(lMaxRes))== (ResultElem*)NULL)
826  return( (ResultElem*)NULL);
827  pop(pTemp2);
828  push(pTemp);
829  Restriction(pTemp2,'N');
830  delete pTemp2;
831  }
832  else
833  {
834  for (l=0L; l<min(pStackBegin->lNum,lMaxRes); l++)
835  if (pTemp->BinSearch (pStackBegin->pResultSet[l])==FALSE)
837  pStackBegin->lNum=k;
838  pStackBegin->Sort();
839  memset(pStackBegin->pResultSet+k,0,lMaxRes-k);
840  memcpy(pResultSet,pStackBegin->pResultSet,lMaxRes*sizeof(RECNR));
841  }
842  delete pTemp;
843  return(pStackBegin); // erstes Element auf dem Stack zurueck
844  }
845 }
846 
847 
848 int RStack::Restriction(ResultElem* pRestrictElem,char modus)
849 {
850 
851  int m=0,rri=1; // gueltige Restriktion? z.B. erj >1990
852  int Rmod=0;
853  char* buffer;
854  ResultElem* pRef=pStackBegin;
855  while (pRef && pRef->bRestriction==TRUE)
856  {
857  pRef=pRef->pNext;
858  }
859  while (m<bank->ress)
860  { // restrics = rpXXX0rpXXX0... r=r/s, p=position
861  if (strnicmp((char *)pRestrictElem->argument,(char *)bank->restrics+m*6+2,3)) ++m;
862  else
863  {
864  buffer=new char[80];
865  if (buffer)
866  {
867  memset(buffer,0,80);
868  strncpy((char *)restri,bank->restrics+m*6,2);
869  while (isalpha(pRestrictElem->argument[++rri])); // now: pStackBegin->argument+rri = ">xxxx" etc.
870  GetRestrictArgument(buffer,pRestrictElem->argument+rri);
871  strcpy(restri+2,buffer);
872  delete[]buffer;
873  }
874  break;
875  }
876  }
877  if (pRef==(ResultElem*)NULL) Rmod=1;
878  else
879  pRef->lNum=bank->InRestrict(pRef->lNum,pRef->pResultSet,restri,modus);
880  return Rmod;
881 }
882 
884 {
885  ResultElem* pTemp,*pTempNext;
886  pTemp=pTempNext=pStackBegin;
887  while (pTempNext!= (ResultElem*)NULL)
888  {
889  pTempNext=pTemp->pNext;
890  delete pTemp;
891  }
892 }
893 
894 
895 
896