a99  V32.6
allegro Windows Hauptprogramm
 Alle Klassen Dateien Funktionen Variablen Typdefinitionen Aufzählungen Aufzählungswerte Makrodefinitionen
aifind.cpp
gehe zur Dokumentation dieser Datei
1 // aifind.cpp/.c : Indexeintrag finden, im Index bewegen, ident. f. .c und .cpp
2 // 1991 / 1995-05-23 / 2011
3 // Copyright 2011 Universitätsbibliothek Braunschweig, more see bottom
4 
5 #include "includes.h"
6 #include "ai-const.h" // allg. Konstanten
7 #include "aisetup.h" // allg. Einstellungen
8 #include "aierrors.h" // Fehlernummern
9 #include "aistruc.h" // Strukturen
10 #include "aiglobal.h" // glob. Variablen
11 #include "aideclar.h" // Funktionsdeklarationen
12 
13 
14 // ------------------------------------------------------------------
15 // Liefert die interne Satznummer zum Schluessel srcval im Reg. rgnum
16 
17 PTRL aiEntEq(SHORT rgnum, CHAR *srcval)
18 {
19  aiINDX *aixf;
20  STATC PTRL temp;
21 
22  aiG_fhln = 0;
23 
24  if ((aixf = aichktf(rgnum)) == 0)
25  return(aiDRNULL);
26 
27  temp = aifent(aixf,srcval,'E');
28  aixf->knotel = aiG_pos;
29  aixf->curknt = aiG_knot;
30  return(temp);
31 }
32 
33 
34 /* -----------------------------------------------------------------
35  Liefert die interne Satznumer zum ersten Schl. im Register rgnum,
36  der groesser oder gleich srcval ist. Falls es keinen gibt: 0
37  Der betr. Schl. wird nach aikey kopiert.
38 */
39 
40 PTRL aiEntGe(SHORT rgnum,CHAR *srcval, CHAR *aikey)
41 
42 {
43  aiINDX *aixf;
44  STATC PTRL temp;
45  aiG_fhln = 0;
46  if ((aixf = aichktf(rgnum)) == 0)
47  return(aiDRNULL);
48 
49  if ((temp = aifent(aixf,srcval,'G')))
50  {
51  aixf->knotel = aiG_pos;
52  aixf->curknt = aiG_knot;
53  aicopy(aikey,aiG_keyar,aixf->kylgth);
54  }
55  else
56  {
57  aixf->knotel = 0;
58  aixf->curknt = aiNODNUL;
59  *aikey=0;
60  }
61  return(temp);
62 }
63 
64 
65 /* ---------------------------------------------------------------------
66  Liefert die interne Satznummer zum naechsten Eintrag im Register rgnum,
67  Der betr. Schl. wird nach aikey kopiert.
68  Kein weiterer Eintrag: Ergebnis 0
69 */
70 
71 PTRL aiEntNx(SHORT rgnum, CHAR *aikey)
72 
73 {
74  aiINDX *aixf;
75  SHORT temp;
76  aiTRSTR *ret;
77 
78  aiG_fhln = 0;
79  if ((aixf = aichktf(rgnum)) == 0)
80  return(aiDRNULL);
81 
82 again:
83  if (!aixf->curknt)
84  {
85  *aikey=0;
86  return(aiDRNULL);
87  }
88  if ((ret = aiknoget(aixf->curknt,aixf)) == 0) // Fehler
89  return(aiDRNULL);
90  if ((temp = aixf->knotel) < ret->ckyv)
91  {
92  aicopy(aikey,aidatpoi(ret,++temp),aixf->kylgth);
93  aixf->knotel = temp;
94  return(aipoidor(ret,temp));
95  }
96  else
97  {
98  aixf->curknt = ret->rgtkey;
99  aixf->knotel = 0;
100  goto again;
101  }
102 }
103 
104 
105 /* ---------------------------------------------------------------------
106  Liefert die interne Satznummer zum vorigen Eintrag im Register rgnum,
107  Der betr. Schl. wird nach aikey kopiert.
108  Kein weiterer Eintrag: Ergebnis 0
109 */
110 
111 PTRL aiEntPr(SHORT rgnum, CHAR *aikey)
112 {
113  aiTRSTR *ret;
114  SHORT prdtst,temp;
115  aiINDX *aixf;
116  RECNR oldknot;
117 
118 
119  aiG_fhln = 0;
120  if ((aixf = aichktf(rgnum)) == 0)
121  return(aiDRNULL);
122 
123  if (!aixf->curknt)
124  {
125  *aikey=0;
126  return(aiDRNULL);
127  }
128 
129  prdtst = aiRETRY;
130 
131 split:
132  if ((ret = aiknoget((oldknot = aixf->curknt),aixf)) == 0)
133  return(aiDRNULL); // then error
134 again2:
135  if ((temp = aixf->knotel) > 1)
136  {
137  aicopy(aikey,aidatpoi(ret,--temp),aixf->kylgth);
138  aixf->knotel = temp;
139  return(aipoidor(ret,temp));
140  }
141  else if ((aixf->curknt = ret->lftkey))
142  {
143  if ((ret = aiknoget(aixf->curknt,aixf)) == 0) // Fehler
144  return(aiDRNULL);
145  if ((temp = ret->ckyv) < 0)
146  aiAbort(211);
147  if (oldknot != ret->rgtkey)
148  {
149  if (!(prdtst--))
150  {
151  aierro(FHLRPFL);
152  return(aiDRNULL);
153  }
154  aixf->curknt = oldknot;
155  goto split; // Knotenteilung
156  }
157  aixf->knotel = temp;
158  if (!temp)
159  {
160  oldknot = aixf->curknt;
161  goto again2;
162  }
163  aicopy(aikey,aidatpoi(ret,temp),aixf->kylgth);
164  return(aipoidor(ret,temp));
165  }
166  else
167  {
168  *aikey=0;
169  return(aiDRNULL);
170  }
171 }
172 
173 // -----------------------------------
174 // Ersten Eintrag im Reg. rgnum finden
175 
176 
177 PTRL aiEntFi(SHORT rgnum, CHAR *aikey)
178 {
179  STATC RECNR knot;
180  aiTRSTR *aibloc;
181  aiINDX *aixf;
182 
183  aiG_fhln = 0;
184  if ((aixf = aichktf(rgnum)) == 0)
185  return(aiDRNULL);
186 
187  if (!(knot = aigrtrot(aixf)))
188  goto empty;
189 
190  while (knot) // Baum nach unten abgrasen, bis Knoten lfflg gefunden
191  {
192  if ((aibloc = aiknoget(knot,aixf)) == 0)
193  return(aiDRNULL);
194  if (aibloc->lfflg == BLATT)
195  break;
196  knot = aidatkno(aibloc,1);
197  }
198  if (!knot) // => no lfflg knot found
199  aiAbort(212);
200 
201  while (!aibloc->ckyv) // Leere Knoten nach links abpruefen
202  if (!(knot = aibloc->rgtkey))
203  goto empty;
204  else if ((aibloc = aiknoget(knot,aixf)) == 0)
205  return(aiDRNULL);
206 
207  aixf->curknt = knot;
208  aixf->knotel = 1;
209  aicopy(aikey,aidatpoi(aibloc,1),aixf->kylgth);
210  return(aipoidor(aibloc,1));
211 
212 empty:
213  *aikey=0;
214  aixf->knotel = 0;
215  aixf->curknt = aiNODNUL;
216  return(aiDRNULL);
217 
218 }
219 
220 
221 // ----------------------------------------
222 // Letzten Eintrag im Register rgnum finden
223 
224 
225 PTRL aiEntLa(SHORT rgnum, CHAR *aikey)
226 {
227  STATC RECNR knot;
228  aiTRSTR *aibloc;
229  aiINDX *aixf;
230  SHORT tmpsiz;
231 
232 
233  aiG_fhln = 0;
234  if ((aixf = aichktf(rgnum)) == 0)
235  return(aiDRNULL);
236 
237  if (!(knot = aigrtrot(aixf)))
238  goto empty2;
239 
240  while (knot) // Nach unten, bis Knoten lfflg gefunden
241  {
242  if ((aibloc = aiknoget(knot,aixf)) == 0)
243  return(aiDRNULL);
244  if (aibloc->lfflg == BLATT)
245  break;
246  if (!(knot = aibloc->rgtkey))
247  knot = aidatkno(aibloc,aibloc->ckyv);
248  }
249  if (!knot) // => kein lfflg-Knoten gefunden
250  aiAbort(213);
251 
252  while (!aibloc->ckyv) // leere Knoten nach rechts ueberspringen
253  if (!(knot = aibloc->lftkey))
254  goto empty2;
255  else if ((aibloc = aiknoget(knot,aixf)) == 0)
256  return(aiDRNULL);
257 
258  aixf->curknt = knot;
259  aixf->knotel = tmpsiz = aibloc->ckyv;
260  aicopy(aikey,aidatpoi(aibloc,tmpsiz),aixf->kylgth);
261  return(aipoidor(aibloc,tmpsiz));
262 
263 empty2:
264  *aikey=0;
265  aixf->knotel = 0;
266  aixf->curknt = aiNODNUL;
267  return(aiDRNULL);
268 }
269 
270 // -------------------------------------------------------
271 // Liefert den auf srcval alphanumerisch folgenden Eintrag
272 
273 
274 PTRL aiEntGt(SHORT rgnum, CHAR *srcval, CHAR *aikey)
275 {
276  PTRL temp;
277 
278  if ((temp = aiEntGe(rgnum,srcval,aikey)) == aiDRNULL || aiG_cpr)
279  return(temp);
280  else
281  return(aiEntNx(rgnum,aikey));
282 }
283 
284 // -------------------------------------------------------
285 // Liefert den srcval alphanumerisch vorangehenden Eintrag
286 
287 
288 PTRL aiEntLt(SHORT rgnum, CHAR *srcval, CHAR *aikey)
289 {
290 
291  aiEntEq(rgnum,srcval);
292  return(aiEntPr(rgnum,aikey));
293 }
294 
295 
296 /* -----------------------------------------------------------------
297  Liefert die interne Satznumer zum ersten Schl. im Register rgnum,
298  der kleiner oder gleich srcval ist. Falls es keinen gibt: 0
299  Der betr. Schl. wird nach aikey kopiert.
300 */
301 
302 PTRL aiEntLe(SHORT rgnum, CHAR *srcval, CHAR *aikey)
303 {
304  PTRL rsult;
305 
306 
307  if ((rsult = aiEntEq(rgnum,srcval)))
308  {
309  aicopy(aikey,srcval,(aiG_ky + rgnum)->kylgth);
310  return(rsult);
311  }
312  else
313  return(aiEntPr(rgnum,aikey));
314 }
315 
316 
317 /* --------------------------------------------------------------------
318  Allgemeine Suchfunktion, nicht direkt aus der Anwendung zu rufen
319  sondern aus anderen Suchroutinen: aiEntGe() etc.
320 */
321 
322 PTRL aifent(aiINDX *aixf, CHAR *aikey, CHAR ai_str)
323 
324 // aixf Zeiger auf eine aiG_ky Struktur (eine Art Nummer des Eintrags)
325 // aikey Zeiger auf einen Schluesselstring
326 // ai_str Suchrichtung: 'E'== Gleichheit, 'G' == groesser oder gleich
327 {
328 
329  STATC RECNR knot;
330  STATC SHORT ai_nump;
331  aiTRSTR *aibloc;
332 
333 
334  aiG_knot = aiG_last = 0; // fuer die zuletzt besuchten Knoten
335  *aiG_keyar=0; // Rueckgabestring mit Nullen fuellen
336  if (!(knot = aigrtrot(aixf))) // Baum u.U. leer, oder Fehler
337  {
338  aiG_pos = 0;
339  return(aiDRNULL);
340  }
341 
342  while (knot) // Baum abgrasen, bis Knoten lfflg gefunden
343  {
344  aiG_last = knot;
345  if ((aibloc = aiknoget(knot,aixf)) == 0) // Fehler
346  return(aiDRNULL);
347  if (aibloc->lfflg == BLATT) // unteres Ende getroffen
348  break;
349  if ((ai_nump = aifkno(aibloc,aikey,'L')) != -1)
350  {
351  if (ai_nump == -2) // Baum fehlerhaft
352  aiAbort(214);
353  /* get child knot */
354  knot = aidatkno(aibloc,ai_nump);
355  }
356  else
357  // nach rechts bewegen wegen unvollst. Angaben
358  knot = aibloc->rgtkey;
359  }
360 
361  if (!knot) // Kein lfflg gefunden, Indexstruktur schadhaft
362  aiAbort(215);
363  return(leftix(aikey,aixf,aibloc,ai_str)); // Den Knoten lfflg durchsuchen
364 }
365 
366 
367 // ----------------------------
368 // Den Knoten lfflg durchsuchen
369 
370 
371 PTRL leftix(CHAR *aikey, aiINDX *aixf, aiTRSTR *aibloc, CHAR ai_str)
372 
373 // aikey Zeiger auf einen Schluesselstring
374 // aixf Schluesselnummer
375 // aibloc Block, der den KNoten lfflg enthaelt
376 // ai_str 'E/G': siehe aifent
377 
378 {
379  STATC SHORT temp;
380 
381 // ist es noetig, die lfflg-Konten nach rechts abzusuchen?
382 
383  while ((temp = aifkno(aibloc,aikey,ai_str == 'E' ? 'E' : 'S')) == -1)
384  if ((aibloc = aiknoget((aiG_last = aibloc->rgtkey),aixf)) == 0)
385  return(aiDRNULL); // Fehler in aiknoget
386 
387  aiG_knot = aiG_last;
388  if (temp != -2) // lfflg Suche erfolgreich
389  {
390  aicopy(aiG_keyar,aidatpoi(aibloc,temp),
391  aixf->kylgth); // Schluesselstring aus aiG_keyar kopieren
392  return(aipoidor(aibloc,temp));
393  }
394  else // srcval nicht gefunden
395  return(aiDRNULL);
396 }
397 
398 /*
399  Copyright 2011 Universitätsbibliothek Braunschweig
400 
401  Licensed under the Apache License, Version 2.0 (the "License");
402  you may not use this file except in compliance with the License.
403  You may obtain a copy of the License at
404 
405  http://www.apache.org/licenses/LICENSE-2.0
406 
407  Unless required by applicable law or agreed to in writing, software
408  distributed under the License is distributed on an "AS IS" BASIS,
409  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
410  See the License for the specific language governing permissions and
411  limitations under the License.
412 */
413