/[webpac]/trunk/openisis/iAPI.txt
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /trunk/openisis/iAPI.txt

Parent Directory Parent Directory | Revision Log Revision Log


Revision 239 - (show annotations)
Mon Mar 8 17:49:13 2004 UTC (20 years ago) by dpavlin
File MIME type: text/plain
File size: 41321 byte(s)
including openisis 0.9.0 into webpac tree

1 /*
2 this file composed by Klaus Ripke from the iAPI files by Robert Janusz.
3 this is the test app "ix.c" with all the includes slurped in,
4 see // #include "isomething.c"
5
6 you may run this with:
7 cp iAPI.txt iAPI.c
8 gcc iAPI.c
9 ./a.out <dbpath>
10 */
11
12 /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
13 iAPI software: The Example of ISIS (UNIX v.3) Database Handle
14 Copyright (C) 2000 by Robert Janusz
15 E-mail: rj@jezuici.krakow.pl
16 Address: Robert Janusz, ul. Kopernika 26, 31-501 Krakow, Poland
17 tel: (0048-12) 4294416/432 ; fax: (0048-12) 4295003.
18
19 This program is free software; you can redistribute it and/or
20 modify it under the terms of the GNU General Public License
21 as published by the Free Software Foundation.
22
23 This program is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 GNU General Public License for more details.
27
28 You should have received a copy of the GNU General Public License
29 along with this program; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
32
33 // Linux gcc Compiler conventions !
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stdarg.h>
38 #include <string.h>
39
40 // Global variables +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
41
42 static
43 char DBpath [71];
44 char UpCase [256];
45
46 #define NFIND 3 // let's keep it for future
47
48 #define PACKED __attribute__((packed)) // it shoud work on Linux gcc ;-)
49
50 // #include "idef.c"
51 /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
52 iAPI software: The Type Definitions for Unix-ISIS databases
53 Copyright (C) 2000 by Robert Janusz
54 E-mail: rj@jezuici.krakow.pl
55 Address: Robert Janusz, ul. Kopernika 26, 31-501 Krakow, Poland
56 tel: (0048-12) 4294416/432 ; fax: (0048-12) 4295003.
57
58 This program is free software; you can redistribute it and/or
59 modify it under the terms of the GNU General Public License
60 as published by the Free Software Foundation.
61
62 This program is distributed in the hope that it will be useful,
63 but WITHOUT ANY WARRANTY; without even the implied warranty of
64 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
65 GNU General Public License for more details.
66
67 You should have received a copy of the GNU General Public License
68 along with this program; if not, write to the Free Software
69 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
71
72 // gcc Linux Compiler conventions !
73 // *** ONLY UNIX ISIS = the difference between DOS/UNIX structures
74
75 // *************************** TYPE DEFINITIONS *****************************
76
77 // Cross Reference File XRF structure +++++++++++++++++++++++++++++++++++++++
78
79 typedef /* Packed */ struct // /* Packed */ and order are necessary for block reading
80 {
81 long int xpos PACKED;
82 // Block nr: 1, 2...; < 0: last block
83 long int xrec [127] PACKED;
84 // References to Master File records...
85 // xrec [...] = 2048 *xrmfb [21 bit] & xrmfp [11 bit]
86 // rec. deleted log. < 0 & > 0 (restore: -xrmfb)
87 // rec. deleted phis. =-1 & = 0 (ref@MST.ctrl)
88 // rec. does not exist = 0 & = 0
89 // new rec. to invert bit 1024 = 1
90 // rec. edited to inv. (add & del post.) bit 512 = 1
91 }
92 xrfBlock;
93
94 // Master File (MST) record structures... +++++++++++++++++++++++++++++++++++
95
96 typedef /* Packed */ struct // The first record in Master File
97 {
98 long int ctlmfn PACKED // Always 0
99 , nxtmfn PACKED // Next Master File Number
100 , nxtmfb PACKED; // Next block in Master File, the 1st has 1
101 short int nxtmfp PACKED // Next position in the last block
102 , mftype PACKED; // 0 for user's bases; 1 for messages
103 long int reccnt PACKED // Reserved for future
104 , mfcxx1 PACKED // Reserved for future
105 , mfcxx2 PACKED // LAN, > 0: inversion, update not possible
106 , mfcxx3 PACKED; // LAN, = 1: exists exclusive user
107 }
108 mstControl;
109
110 typedef /* Packed */ struct // Fixed part of record header that must be...
111 { // included in the same block;
112 // the header can begin only on 0, 2, 4...498
113 long int mfn PACKED; // MFN number
114 short int mfrl PACKED; // Length of record (allways eaven)...
115 // LAN: < 0 ==> record blocked
116 long int mfbwb PACKED; // Block Pointer | If the record waits for inv...
117 short int mfbwp PACKED; // Position Pointer | ...ref. to old location
118 // mfbwb, mfbwp: = 0 at creation;
119 // after modif. = ref to the old record.
120 // xrmfp bit 1024 = 1 at creation
121 // (= waits to be inverted);
122 // xrmfp bit 512 = 1 at edit
123 // (=waits to be inv. & delete old references)
124 }
125 mstHdrFix;
126
127 typedef /* Packed */ struct
128 {
129 short int base PACKED // Position of data fields in the record
130 , nvf PACKED // Number of fields in the record
131 , status PACKED; // 0 = active, 1 = deleted logicaly (- xrfb < 0)
132 }
133 mstHdrTxt;
134
135 typedef /* Packed */ struct
136 {
137 mstHdrFix mhf PACKED; // This header is allways in MST file block
138 mstHdrTxt mht PACKED;
139 }
140 RecHeaders;
141
142 typedef /* Packed */ struct // Index for every field in the record
143 { // dimension = 6 *nvf; base = 18 + 6 *nvf
144 short int tag PACKED // Label of the field
145 , pos PACKED // Position of the first char in data part: 0, 1...
146 , len PACKED; // Length of the field
147 }
148 mstIndex;
149
150 // Inverted File structures +++++++++++++++++++++++++++++++++++++++++++++++++
151
152 // Control File (CNT) structure..............................................
153
154 typedef /* Packed */ struct
155 {
156 short int idtype PACKED // B*tree type; 1 = N01/L01, 2 = N02/L02
157 , ordn PACKED // = 5; a half of size of key-record in N0x
158 , ordf PACKED // = 5; a half of size of key-record in L0x
159 , n PACKED // = 15; number of buffers for nodes
160 , k PACKED // = 5; number of buffers for 1st index level (k < n)
161 , lev PACKED; // Current number of levels in index; -1: no N0x
162 long int posrx PACKED // Reference to the root in N0x
163 , nmaxpos PACKED // Next record in N0x
164 , fmaxpos PACKED; // Next record in L0x
165 short int abnormal PACKED; // 0: N0x has only the root
166 }
167 cntBlock;
168
169 // Index of Dictionary (N0x) structures......................................
170
171 typedef /* Packed */ struct
172 {
173 long int pos PACKED; // Number of record
174 short int ock PACKED // Number of active keys in the record: 1, 2, 3...2*ordn
175 , it PACKED; // B*tree type
176 }
177 nodeHeader;
178
179 typedef /* Packed */ struct
180 {
181 char key [10] PACKED;
182 long int ref PACKED; // > 0: reference to next node;
183 // < 0: ref. to leaf: idx [1st].key = key
184 // = 0: inactive
185 }
186 nodeIndex1;
187
188 typedef /* Packed */ struct
189 {
190 char key [30] PACKED;
191 long int ref PACKED;
192 }
193 nodeIndex2;
194
195 typedef /* Packed */ struct
196 {
197 nodeHeader hdr PACKED;
198 nodeIndex1 idx [10] PACKED; // Vector of 2*ordn elements
199 }
200 nodeBlock1;
201
202 typedef /* Packed */ struct
203 {
204 nodeHeader hdr PACKED;
205 nodeIndex2 idx [10] PACKED; // Vector of 2*ordn elements
206 }
207 nodeBlock2;
208
209 typedef /* Packed */ union
210 {
211 nodeBlock1 nb1 PACKED;
212 nodeBlock2 nb2 PACKED;
213 }
214 nodeBlock;
215
216 // Leaf File (L0x) structures (all index terms)..............................
217
218 typedef /* Packed */ struct
219 {
220 long int pos PACKED; // Number of leaf record: 1, 2...
221 short int ock PACKED // Number of active keys in the record: 1..2*ordf
222 , it PACKED; // = 1 for L01; = 2 for L02
223 long int ps PACKED; // Next record in the order: key [ock] < ps^ idx [1st].key
224 }
225 leafHeader;
226
227 typedef /* Packed */ struct
228 {
229 char key [10] PACKED;
230 short int xxx PACKED; // *** ONLY UNIX ISIS;
231 long int infb PACKED // Reference to IFP segment *** != ISIS.MANUAL ***
232 , infp PACKED;
233 }
234 leafKey1;
235
236 typedef /* Packed */ struct
237 {
238 char key [30] PACKED;
239 short int xxx PACKED; // *** ONLY UNIX ISIS;
240 long int infb PACKED // Reference to IFP segment *** != ISIS.MANUAL ***
241 , infp PACKED;
242 }
243 leafKey2;
244
245 typedef /* Packed */ struct
246 {
247 leafHeader hdr PACKED;
248 leafKey1 idx [10] PACKED; // 2*ordf keys
249 }
250 leafBlock1;
251
252 typedef /* Packed */ struct
253 {
254 leafHeader hdr PACKED;
255 leafKey2 idx [10] PACKED; // 2*ordf keys
256 }
257 leafBlock2;
258
259 typedef /* Packed */ union
260 {
261 leafBlock1 lb1 PACKED;
262 leafBlock2 lb2 PACKED;
263 }
264 leafBlock;
265
266 // Inverted File Posting structures..........................................
267 // ordained postings organized in segments: Index --> Master File
268
269 typedef /* Packed */ struct
270 {
271 long int ifblk PACKED // Number of block
272 , ifrec [127] PACKED; // Vector of long int *** != ISIS.MANUAL ***
273 // In 1st block ifrec [1st/2nd] = next pos. in IFP
274 }
275 ifpBlock;
276
277 typedef /* Packed */ struct // This header and 1st posting - always in IFP block
278 {
279 long int ifpnxtb PACKED // Pointer to the next segment: 1, 2... | = 0: last seg.
280 , ifpnxtp PACKED // 0, 1... | = 0: last seg.
281 , ifptotp PACKED // Tot. number of postings (o.k. only in the 1st segment)
282 // = Sum (segment=1, nseg; ifpsegp)
283 , ifpsegp PACKED // Number of postings in this segment
284 , ifpsegc PACKED; // Max. number of postings in this segment (<= 32768)
285 }
286 ifpHeader;
287
288 // ifpHeader & 1st ifpPosting always in the same ifpBlock
289 // Postings in Segment are always in chain of IFP blocks
290
291 typedef /* Packed */ struct // Stored left-->right + 0 --> 8 char
292 {
293 long int pmfn PACKED; // First 3 bytes --> Master File
294 short int ptag PACKED; // Field ident - according to File Selection Table (FST)
295 char pocc PACKED; // Number of occurence of the field
296 short int pcnt PACKED; // Counter of the termin inside the field
297 }
298 ifpPosting;
299
300 typedef struct
301 {
302 int opened; // Which files are opened (bit spec.)...
303 FILE *mst; // 1
304 FILE *xrf; // 2
305 FILE *ifp; // 4
306 FILE *n01; // 8
307 FILE *l01; // 16
308 FILE *n02; // 32
309 FILE *l02; // 64
310 mstControl mctrl; // MST ctrl record
311 cntBlock cnt1, cnt2; // Inv. Files ctrl records
312 long int ibm, ipm; // IFP new Segment Bock/Pos
313 char name [72]; // Database name
314 }
315 BaseCtrl;
316
317 typedef struct // This structer must be allways corelated with BaseCtrl
318 {
319 char st [31]; // Max. string to find
320 short int v; // Field to find; 0: all fields
321 short int it; // Type of B*Tree <== strlen (st)
322 leafBlock lbl; // Block L0x with index terms
323 short int ilk; // Position of term in lbl...idx
324 char *term; // The term in lbl...idx
325 long int ib, ip; // Number of block/position for IFP
326 ifpBlock ibl; // Block IFP with posting/s
327 ifpHeader ihd; // Header for Segment of postings
328 long int iiseg; // Number of posting in current Segment (index)
329 long int iitot; // Number of posting in total (index)
330 long int iall; // Number of posting in all Segments
331 char *ipst; // Ref. to last posting string [8 chars]
332 cntBlock *cntr; // BaseCtrl.cntr1/2 <== it
333 FILE *n0x; // N01 or N02 <== it, = BaseCtrl.n0x
334 FILE *l0x; // L01 or L02 <== it, = BaseCtrl.l0x
335 }
336 TableQuery;
337
338 #define RECLENGTH 8192
339
340 typedef union
341 {
342 char buf [RECLENGTH];
343 RecHeaders hdrs;
344 }
345 RecCtrl;
346
347 // *** MAIN DATABASE FILE RELATIONS (MST <--> XRF) ***
348 // 1 2 3
349 // MST |-mblk-|-mblk-|-mblk-|-mblk-|-mblk-|-mblk-|-mblk-|-mblk-|...
350 // ctrl |----record----|
351 // |--->|
352 // 1 2 3 | pointer: B/P (P in [0, 2, 4... 498])
353 // XRF |-xblk-|-xblk-|-xblk-|...
354 // MFN= 1... 128... 255...
355 // Record |-->-pos->--|
356 // |-mhf-mht-|-idx[1]...idx[nvf]-|---text...---|
357 // |-------------- record buffer --------------|
358
359 // *** INVERTED FILE RELATIONS (N0x <--> L0x <-->IFP) ***
360 // N0x |-nbl-|-nbl-|-nbl-|-nbl-|-nbl-|-nbl-|...
361 // -->-root->-| |-->--next-->--| |->-->-| r<0
362 // |
363 // L0x |--lbl--|--lbl--|--lbl--|--lbl--|--lbl--|--lbl--|...
364 // |
365 // |-<--------------<-------------<-| r<0
366 // *** POSTING *** |
367 // IFP |---ibl---|---ibl---|---ibl---|---ibl---|---ibl---|---ibl---|...
368 // |next |-ihd-|---Segment---| |-ihd-|---Segment---|
369 // |Seg. |-->------>------>-next->--| |||...
370 // MFN...
371 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
372
373 // #include "idef.c"
374
375 // Let's specify non int header ;-) just to keep order
376
377 void ShowRec (RecCtrl *rc);
378 void setQuery (BaseCtrl *bc, TableQuery *tq, char *sx, short int fld);
379 void isis ();
380
381 // #include "iutil.c"
382 /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
383 iAPI software: The UTIL procedures for Unix-ISIS databases
384 Copyright (C) 2000 by Robert Janusz
385 E-mail: rj@jezuici.krakow.pl
386 Address: Robert Janusz, ul. Kopernika 26, 31-501 Krakow, Poland
387 tel: (0048-12) 4294416/432 ; fax: (0048-12) 4295003.
388
389 This program is free software; you can redistribute it and/or
390 modify it under the terms of the GNU General Public License
391 as published by the Free Software Foundation.
392
393 This program is distributed in the hope that it will be useful,
394 but WITHOUT ANY WARRANTY; without even the implied warranty of
395 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
396 GNU General Public License for more details.
397
398 You should have received a copy of the GNU General Public License
399 along with this program; if not, write to the Free Software
400 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
401 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
402
403 // gcc Linux Compiler conventions !
404 // *** ONLY UNIX ISIS = the difference between DOS/UNIX structures
405
406 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
407
408 int ReadMem (void *ptr, FILE *f, long int nr, long int size)
409 { // Read "nr"'s block of size "size" from file "f" into "ptr"...
410 if (fseek (f, nr * size, SEEK_SET) != 0) return (-1);
411 if (fread (ptr, size, 1, f) == 0) return (-2);
412 return (0); // O.K.
413 }
414
415 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
416
417 void doUpcase (char *s, char *st, int slen)
418 { int i;
419 for (i = 0; i < slen; i++)
420 { if (i < strlen (st)) s [i] = UpCase [(int) st [i]]; else s [i] = ' '; }
421 s [slen] = 0;
422 }
423
424 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
425
426 int sComp (char *s1, char *s2, int len)
427 { int i;
428 for (i = 0; i < len; i++)
429 { if (s1 [i] > s2 [i]) return (1); // .gt.
430 if (s1 [i] < s2 [i]) return (-1); // .lt.
431 }
432 return (0); // .eq.
433 }
434
435 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
436
437 int bfOpen (FILE **f, BaseCtrl *bc, char *ext, char *opt)
438 { char st [81];
439 if (strlen (bc->name) + strlen (ext) > 80) return (-2);
440 strcpy (st, bc->name); strcat (st, ext);
441 if ((*f = fopen (st, opt)) == NULL) return (-1);
442 return (0);
443 }
444
445 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
446
447 int InitBase (BaseCtrl *bc)
448 // Error return: -1 base file/s; -2 inv. file/s; -3 mst. ctrl rec/s;
449 // -4 cnt param/s; -5 ifp param/s
450 { ifpBlock ib;
451 bc->opened = 0;
452 if (bfOpen (&bc->mst, bc, ".MST", "rb") != 0) return (-1);
453 bc->opened += 1; // MST opened
454 if (bfOpen (&bc->xrf, bc, ".XRF", "rb") != 0) return (-1);
455 bc->opened += 2; // XRF opened
456 if (bfOpen (&bc->ifp, bc, ".CNT", "rb") != 0) return (-2);
457 if (fread (&bc->cnt1, sizeof (cntBlock), 1, bc->ifp) == 0 ||
458 fread (&bc->cnt2, sizeof (cntBlock), 1, bc->ifp) == 0) return (-2);
459 if (fclose (bc->ifp) != 0) return (-3);
460 if (bfOpen (&bc->ifp, bc, ".IFP", "rb") != 0) return (-2);
461 bc->opened += 4; // IFP opened
462 if (bfOpen (&bc->n01, bc, ".N01", "rb") != 0) return (-2);
463 bc->opened += 8; // N01 opened
464 if (bfOpen (&bc->l01, bc, ".L01", "rb") != 0) return (-2);
465 bc->opened += 16; // L01 opened
466 if (bfOpen (&bc->n02, bc, ".N02", "rb") != 0) return (-2);
467 bc->opened += 32; // N02 opened
468 if (bfOpen (&bc->l02, bc, ".L02", "rb") != 0) return (-2);
469 bc->opened += 64; // L02 opened
470 if (fread (&bc->mctrl, sizeof (mstControl), 1, bc->mst) == 0) return (-3);
471 if (bc->cnt1.ordn != 5 || bc->cnt1.ordf != 5 || bc->cnt1.n != 15 ||
472 bc->cnt1.k != 5 || bc->cnt2.ordn != 5 || bc->cnt2.ordf != 5 ||
473 bc->cnt2.n != 15 || bc->cnt2.k != 5) return (-4);
474 if (fread (&ib, sizeof (ifpBlock), 1, bc->ifp) == 0) return (-5);
475 if (ib.ifblk != 1) return (-5);
476 bc->ibm = ib.ifrec [0]; bc->ipm = ib.ifrec [1];
477 return (0);
478 }
479
480 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
481
482 void Done (BaseCtrl *bc) // Close the database files
483 {
484 if (bc->opened && 1) fclose (bc->mst);
485 if (bc->opened && 2) fclose (bc->xrf);
486 if (bc->opened && 4) fclose (bc->ifp);
487 if (bc->opened && 8) fclose (bc->n01);
488 if (bc->opened && 16) fclose (bc->l01);
489 if (bc->opened && 32) fclose (bc->n02);
490 if (bc->opened && 64) fclose (bc->l02);
491 }
492
493 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
494
495 char UpMe (char c) // ^A = ^a etc.
496 {
497 if (c > 96) c = c - 32;
498 return (c);
499 }
500
501 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
502
503 void outS (char *st)
504 { char i;
505 if (st == NULL) return;
506 for (i = 0; i < strlen (st); i++)
507 // c = tblconvert [st [i]];
508 if (st [i] == (char) 145) printf ("<"); // This is HTML <
509 else if (st [i] == (char) 146) printf (">"); // and that is >
510 else printf ("%c", st [i]);
511 }
512
513 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
514
515 void outC (char ch)
516 { char st [2];
517 st [0] = ch; st [1] = 0; outS (st);
518 }
519
520 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
521
522 void outD (double x, int n)
523 { char s [80];
524 gcvt (x, n, s);
525 outS (s);
526 }
527
528 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
529
530 void outN (long int x) // long int -> sting @ base=10
531 {
532 // char st [33];
533 // ltoa (x, st, 10); outS (st);
534 printf ("%li", x);
535 }
536
537 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
538
539
540 // #include "imasterf.c"
541 /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
542 iAPI software: The Master File access to Unix-ISIS databases
543 Copyright (C) 2000 by Robert Janusz
544 E-mail: rj@jezuici.krakow.pl
545 Address: Robert Janusz, ul. Kopernika 26, 31-501 Krakow, Poland
546 tel: (0048-12) 4294416/432 ; fax: (0048-12) 4295003.
547
548 This program is free software; you can redistribute it and/or
549 modify it under the terms of the GNU General Public License
550 as published by the Free Software Foundation.
551
552 This program is distributed in the hope that it will be useful,
553 but WITHOUT ANY WARRANTY; without even the implied warranty of
554 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
555 GNU General Public License for more details.
556
557 You should have received a copy of the GNU General Public License
558 along with this program; if not, write to the Free Software
559 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
560 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
561
562 // gcc Linux Compiler conventions !
563 // *** ONLY UNIX ISIS = the difference between DOS/UNIX structures
564
565 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
566
567 int GetRec (BaseCtrl *bc, long int mfnr, RecCtrl *rc, int bufvol)
568 { char mblk [512]; // Master File block;
569 long int xmfb, xmfp; // Pointer to Master File (last read) record
570 // xMfB < 0 : record deleted (status = 1), -xMfB --> block;
571 // xMfP = 0: deleted phisicaly
572 // = 0 & = 0: does not exist
573 // 1st block: xMfB = 1, xMfP = 0; pointer = xMfB * 2048 + xMfP
574 // ==> mst < 500 MBy;
575 long int xn, xb;
576 int ret, nch;
577 xrfBlock xblk;
578 mstHdrFix *hf = &rc->hdrs.mhf;
579 mstHdrTxt *ht = &rc->hdrs.mht;
580 char *b = rc->buf;
581
582 if ((mfnr < 1) || (mfnr >= bc->mctrl.nxtmfn)) return (-2); // No record
583
584 // Find the address in XRF...
585 xn = mfnr - 1; xb = xn / 127;
586 if (ReadMem (&xblk, bc->xrf, xb, sizeof (xrfBlock)) != 0) return (-1);
587 xn = xblk.xrec [xn % 127]; // = address in MST
588 xmfb = xn / 2048; // Master File Block
589 xmfp = xn % 512; // Master File Position
590
591 // Find the record in MST...
592 if (xmfb < 1) return (1); // Record deleted
593 ret = 0; // Record o.k.
594 if (ReadMem (&mblk, bc->mst, xmfb - 1, sizeof (mblk)) != 0) return (-1);
595
596 // Copy headers into record buffer...
597 memcpy (b, &mblk [xmfp], sizeof (mstHdrFix));
598 if (hf->mfn != mfnr) return (-2); // Database corrupted
599 if (hf->mfrl >= bufvol) return (-3); // Buffer too small
600
601 // Get the rest of the record
602 xmfp += sizeof (mstHdrFix); // Posinion in block
603 xb = sizeof (mstHdrFix); // Position in buf
604 xn = labs (hf->mfrl) - xb; // Number of chars to read
605 if (xn <= 0) return (4); // No fields ??
606 for ( ; ; ) // We have some chars
607 { // Find number of chars to copy from this block
608 if (xn <= (nch = sizeof (mblk) - xmfp)) nch = xn;
609 memcpy (b + xb, &mblk [xmfp], nch);
610 xb += nch; xn -= nch; xmfp = 0;
611 if (xn <= 0) break; // Nothing more to read
612 if (fread (&mblk, sizeof (mblk), 1, bc->mst) == 0) return (-1);
613 }
614
615 if (ht->status != 0) ret = 1; // Record deleted logicaly
616 if (hf->mfbwb != 0 || hf->mfbwp != 0) ret = 2; // Record not inv.
617 if (hf->mfrl < 0) ret = 3; // Record blocked
618 return (ret);
619 }
620
621 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
622
623 int IsF (RecCtrl *rc, short int v, char ch, char *st)
624 { short int n, k, kk, flag;
625 char *b = rc->buf;
626 mstHdrTxt *mht = &rc->hdrs.mht;
627 mstIndex *ind = (mstIndex *) &rc->buf [sizeof (RecHeaders)];
628
629 flag = 0;
630 for (n = 0; n < mht->nvf; n++)
631 {
632 if (ind->tag == v) // there is a tag
633 {
634 if (ch == ' ') // field found
635 { flag = 1; break; }
636 else // there is sub-field
637 { flag = 1;
638 kk = 0; k = mht->base + ind->pos;
639 while (b [k] != '^' || b [k + 1] != ch) // convention ;-)
640 { k += 1; kk += 1;
641 if (kk >= ind->len) // out of field
642 return (0);
643 }
644 break;
645 }
646 }
647 ind += 1; // next index ref.
648 }
649 if (flag == 0) return (0); // false
650 if (st == NULL) return (1); // true
651 else
652 if (sComp (&b [mht->base + ind->pos], st, ind->len) == 0)
653 return (1);
654 else return (0);
655 }
656
657 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
658
659 void RepF (RecCtrl *rc, char nf, ...)
660
661 // Repeated "nf" fields in record "rc", the left label appears only if:
662 // - begins with "\n", - there was another field and there is defined
663 // filed; the right label appears only if ther was defined field.
664
665 { va_list pinfo; // for ... parameter list
666 int i, c, flag, n, k, kk, v;
667 int hit = 0;
668 char *sl, *sr;
669 char *b = rc->buf;
670 mstHdrTxt *mht = &rc->hdrs.mht;
671 mstIndex *ind = (mstIndex *) &rc->buf [sizeof (RecHeaders)];
672
673 for (n = 0; n < mht->nvf; n++)
674 {
675 va_start (pinfo, nf);
676 for (i = 0; i < nf; i++)
677 {
678 kk = 0;
679 k = mht->base + ind->pos;
680 sl = va_arg (pinfo, char *); // left
681 v = va_arg (pinfo, short int); // field
682 c = va_arg (pinfo, char); // sub-field
683 c = UpMe (c);
684 sr = va_arg (pinfo, char *); // right
685 if (v != ind->tag) // another Tag
686 break;
687 if (c != ' ') // sub-field
688 { flag = 1;
689 while (b [k] != '^' || UpMe (b [k + 1]) != c) // convention ;-)
690 { k += 1; kk += 1;
691 if (kk >= ind->len)
692 { flag = 0; break; }
693 }
694 if (flag) { k += 2; kk += 2; }
695 }
696 else flag = 1;
697 if (flag)
698 { // Reference to NULL = NW error !!!
699 if (sl == NULL) flag = 0;
700 else if (*sl == '\n') flag = 1; else flag = 0;
701 if (hit != 0 || flag) outS (sl);
702 hit += 1;
703 if (c == ' ')
704 while (kk < ind->len)
705 {
706 if (b [k] != '<' && b [k] != '>') // HTML special ;-)
707 outC (b [k]);
708 k += 1; kk += 1;
709 }
710 else
711 while (kk < ind->len && b [k] != '^') // convention ;-)
712 {
713 if (b [k] != '<' && b [k] != '>') // HTML special ;-)
714 outC (b [k]);
715 k += 1; kk += 1;
716 }
717 outS (sr);
718 }
719 }
720 va_end (pinfo);
721 ind += 1;
722 }
723 }
724
725 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
726
727 // #include "iinvterm.c"
728 /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
729 iAPI software: The Inv. File Terms access for Unix-ISIS databases
730 Copyright (C) 2000 by Robert Janusz
731 E-mail: rj@jezuici.krakow.pl
732 Address: Robert Janusz, ul. Kopernika 26, 31-501 Krakow, Poland
733 tel: (0048-12) 4294416/432 ; fax: (0048-12) 4295003.
734
735 This program is free software; you can redistribute it and/or
736 modify it under the terms of the GNU General Public License
737 as published by the Free Software Foundation.
738
739 This program is distributed in the hope that it will be useful,
740 but WITHOUT ANY WARRANTY; without even the implied warranty of
741 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
742 GNU General Public License for more details.
743
744 You should have received a copy of the GNU General Public License
745 along with this program; if not, write to the Free Software
746 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
747 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
748
749 // gcc Linux Compiler conventions !
750 // *** ONLY UNIX ISIS = the difference between DOS/UNIX structures
751
752 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
753
754 int FindFirst (TableQuery *tq)
755 {
756 short int i, j // Indexes for idx []
757 , srec, klen, sidx; // Size (rec), key length, size (idx)
758 long int r; // Reference (record number); < 0: --> L0x --> IFP
759 char *ref;
760 leafHeader *lhdr = &tq->lbl.lb1.hdr; // = ...lb2.hdr
761 nodeBlock nbl;
762 nodeHeader *nhdr = &nbl.nb1.hdr; // = ...nb2.hdr
763
764 if (tq->it == 1)
765 { klen = 10; srec = sizeof (nodeBlock1); sidx = sizeof (nodeIndex1); }
766 else
767 { klen = 30; srec = sizeof (nodeBlock2); sidx = sizeof (nodeIndex2); }
768
769 r = tq->cntr->posrx; // Root in N0x
770 while (r > 0L)
771 {
772 if (ReadMem (&nbl, tq->n0x, r - 1, srec) != 0) return (-1);
773 j = nhdr->ock;
774 if (nhdr->pos != r || nhdr->it != tq->it ||
775 j < 1 || j > 10) return (-3); // 10 = 2*ordn
776 ref = (char *) &nbl.nb1.idx; // Reference to first elem. of index
777 ref += sidx; // The first key is allways <= st, skip it
778 for (i = 1; i < j; i++)
779 if (sComp (ref, tq->st, klen) > 0) break;
780 else ref += sidx;
781 ref -= sidx; // Correct value
782 r = *(long int *) (ref + klen); // We have the "ref" value
783 if (r > tq->cntr->nmaxpos) return (-3); // Out of N0x
784 }
785
786 // Now find the term in L0x index
787 if (tq->it == 1)
788 { srec = sizeof (leafBlock1); sidx = sizeof(leafKey1); }
789 else
790 { srec = sizeof(leafBlock2); sidx = sizeof(leafKey2); }
791
792 r = - r;
793 if (ReadMem (&tq->lbl, tq->l0x, r - 1, srec) != 0) return (-1);
794 j = lhdr->ock;
795 if (lhdr->pos != r || lhdr->it != tq->it ||
796 j < 1 || j > 10) return (-2); // 10 = 2*ordf
797
798 tq->ilk = 0;
799 ref = (char *) &tq->lbl.lb1.idx; // Reference to first elem. of index
800 ref += sidx; // The first key is allways <= s, skip it
801 for (i = 1; i < j; i++)
802 if (sComp (ref, tq->st, klen) > 0) break;
803 else { ref += sidx; tq->ilk += 1; }
804
805 ref -= sidx;
806 tq->term = ref; // We have the term address
807 if (tq->it == 1)
808 ref += 12; // += 10; *** NOT UNIX
809 else ref += 32; // += 30; *** NOT UNIX
810 tq->ib = *(long int *) ref; // = infb
811 ref += sizeof (long int);
812 tq->ip = *(long int *) ref; // = infp
813 return (0); // O.K.
814 }
815
816 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
817
818 int FindNext (TableQuery *tq)
819 { int srec; // Block size
820 long int r; // Reference (record number); < 0: --> L0x --> IFP
821 leafHeader *lhdr = &tq->lbl.lb1.hdr; // = ...lb2.hdr
822
823 if (tq->it == 1) srec = sizeof (leafBlock1);
824 else srec = sizeof (leafBlock2);
825
826 tq->ilk += 1; // Next key in the index
827 if (tq->ilk >= lhdr->ock) // Out of index
828 { r = lhdr->ps; // Next L0x record in order
829 if (r <= 0)
830 { tq->ilk -= 1; return (1); } // Nothing more, end of index
831 if (ReadMem (&tq->lbl, tq->l0x, r - 1, srec) != 0) return (-1);
832 if (lhdr->pos != r || lhdr->it != tq->it ||
833 lhdr->ock < 1 || lhdr->ock > 10) return (-2); // 10 = 2*ordf
834 tq->ilk = 0;
835 }
836
837 srec = tq->ilk;
838 if (tq->it == 1)
839 { tq->term = tq->lbl.lb1.idx [srec].key;
840 tq->ib = tq->lbl.lb1.idx [srec].infb;
841 tq->ip = tq->lbl.lb1.idx [srec].infp;
842 }
843 else
844 { tq->term = tq->lbl.lb2.idx [srec].key;
845 tq->ib = tq->lbl.lb2.idx [srec].infb;
846 tq->ip = tq->lbl.lb2.idx [srec].infp;
847 }
848 return (0); // We have the new key
849 }
850
851 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
852
853 int Find (BaseCtrl *bc, TableQuery tabq [], int ifind, long int *npg
854 , RecCtrl *rc, long int recvol)
855 { int i;
856
857 if (ifind <= 0 || ifind > NFIND) return (-1);
858 for (i = 0; i < ifind; i++)
859 if (FindFirst (&tabq [i]) < 0) return (-1);
860
861 i = Postings (bc, tabq, ifind, npg, rc, recvol);
862 return (i);
863 }
864
865 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
866
867 int IndexPrep (BaseCtrl *bc, TableQuery *tq1, TableQuery *tq2, char *st)
868 { char sx [31]; // tqx->v contains the status of L0x index
869 int i;
870
871 if (st == NULL)
872 for (i = 0; i < 30; i++) sx [i] = ' ';
873 else
874 for (i = 0; i < 30; i++)
875 if (i < strlen (st)) sx [i] = st [i]; else sx [i] = ' ';
876
877 sx [30] = 0;
878 setQuery (bc, tq2, sx, 0); // We have a long term in tq2; v := 0
879 if (FindFirst (tq2) < 0) return (-1);
880
881 sx [10] = 0;
882 setQuery (bc, tq1, sx, 0); // We have a short term in tq1; v := 0
883 if (FindFirst (tq1) < 0) return (-1);
884
885 while (sComp (tq1->term, tq1->st, 10) < 0)
886 if ((tq1->v = FindNext (tq1)) != 0) break; // At the end or error
887 if (tq1->v < 0) return (-1);
888
889 while (sComp (tq2->term, tq2->st, 30) < 0)
890 if ((tq2->v = FindNext (tq2)) != 0) break; // At the end or error
891 if (tq2->v < 0) return (-1);
892
893 return (IndexTest (tq1, tq2));
894 }
895
896 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
897
898 int IndexTest (TableQuery *tq1, TableQuery *tq2)
899 {
900 if (tq1->v == 1) // At the end of 1st
901 if (tq2->v == 1) // At the end of 2nd
902 return (0); // All done
903 else return (2); // We have only 2nd
904 else
905 if (tq2->v == 1) return (1); // We have only 1st
906 else if (sComp (tq1->term, tq2->term, 10) <= 0) return (1);
907 else return (2);
908 }
909
910 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
911
912 int IndexTerm (int i, TableQuery *tq1, TableQuery *tq2)
913 {
914 if (i == 1) tq1->v = FindNext (tq1); // The term was in 1st
915 else if (i == 2) tq2->v = FindNext (tq2); // The term was in 2nd
916 else return (-1);
917 return (IndexTest (tq1, tq2));
918 }
919
920 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
921
922 void setQuery (BaseCtrl *bc, TableQuery *tq, char *sx, short int fld)
923 { // Must be activated AFTER the initialization of database
924
925 tq->v = fld;
926 if (strlen (sx) <= 10)
927 { tq->it = 1; doUpcase (tq->st, sx, 10);
928 tq->cntr = &bc->cnt1; tq->n0x = bc->n01; tq->l0x = bc->l01;
929 }
930 else
931 { tq->it = 2; doUpcase (tq->st, sx, 30);
932 tq->cntr = &bc->cnt2; tq->n0x = bc->n02; tq->l0x = bc->l02;
933 }
934 }
935
936 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
937
938
939 // #include "ipost.c"
940 /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
941 iAPI software: The Inv. File Postings access for Unix-ISIS databases
942 Copyright (C) 2000 by Robert Janusz
943 E-mail: rj@jezuici.krakow.pl
944 Address: Robert Janusz, ul. Kopernika 26, 31-501 Krakow, Poland
945 tel: (0048-12) 4294416/432 ; fax: (0048-12) 4295003.
946
947 This program is free software; you can redistribute it and/or
948 modify it under the terms of the GNU General Public License
949 as published by the Free Software Foundation.
950
951 This program is distributed in the hope that it will be useful,
952 but WITHOUT ANY WARRANTY; without even the implied warranty of
953 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
954 GNU General Public License for more details.
955
956 You should have received a copy of the GNU General Public License
957 along with this program; if not, write to the Free Software
958 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
959 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
960
961 // gcc Linux Compiler conventions !
962 // *** ONLY UNIX ISIS = the difference between DOS/UNIX structures
963
964 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
965
966 int PostSeg (BaseCtrl *bc, TableQuery *tq)
967 {
968 if (ReadMem (&tq->ibl, bc->ifp, tq->ib - 1, sizeof (ifpBlock)) != 0)
969 return (-1);
970 if (labs (tq->ibl.ifblk) - tq->ib != 0) return (-2);
971 memcpy (&tq->ihd, &tq->ibl.ifrec [tq->ip], sizeof (ifpHeader));
972 tq->ip += 3; // = long int.s / (header - posting) ***!= ISIS.MANUAL ***
973 tq->iiseg = 0;
974 return (0);
975 }
976
977 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
978
979 int PostNext (BaseCtrl *bc, TableQuery *tq)
980 {
981 if (tq->iitot >= tq->iall) return (1); // No more postings
982 if (tq->iiseg >= tq->ihd.ifpsegp) // No more postings in this seg.
983 { // Get next Segment...
984 tq->ib = tq->ihd.ifpnxtb; tq->ip = tq->ihd.ifpnxtp;
985 if (PostSeg (bc, tq) != 0) return (-2);
986 }
987 tq->iiseg += 1; tq->iitot += 1;
988 tq->ip += 2; // = Number of long int / posting ***!= ISIS.MANUAL ***
989 if (tq->ip > 125) // ***!= ISIS.MANUAL ***
990 { // Get next block for this segment; we HAVE TO find the right block!
991 tq->ib += 1; tq->ip = 0;
992 if (ReadMem (&tq->ibl, bc->ifp, tq->ib - 1, sizeof (ifpBlock)) != 0)
993 return (-1);
994 if (labs (tq->ibl.ifblk) != tq->ib) return (-3);
995 }
996 tq->ipst = (char *) &tq->ibl.ifrec [tq->ip];
997 return (0);
998 }
999
1000 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1001
1002 void PostMake (long int mfn, short int tag, char occ, short int pcnt
1003 , char *s, char *slen)
1004 { ifpPosting rnp;
1005 char *p = (char *) &rnp;
1006
1007 rnp.pmfn = mfn; rnp.ptag = tag; rnp.pocc = occ; rnp.pcnt = pcnt;
1008 if (tag == 0) *slen = 3; // Only MFN
1009 else *slen = 5; // MFN and TAG
1010 s [2] = p [0]; s [1] = p [1]; s [0] = p [2]; // = pmfn
1011 s [4] = p [4]; s [3] = p [5]; s [5] = p [6]; s [7] = p [7]; s [6] = p [8];
1012 }
1013
1014 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1015
1016 void PostInv (ifpPosting *ifpp, void *ps)
1017 { char *p = (char *) ifpp;
1018 char *s = (char *) ps;
1019
1020 // Posting string: |0 a |1 b |2 c |3 d |4 e |5 f |6 g |7 h | ps *s
1021 // ifpPosting: |0 c|1 b |2 a |3 0 |4 e |5 d |6 f |7 h |8 g | ifpp *p
1022 // |pmfn |ptag |pocc|pcnt |
1023
1024 p [0] = s [2]; p [1] = s [1]; p [2] = s [0]; p [3] = 0; // = pmfn
1025 p [4] = s [4]; p [5] = s [3]; p [6] = s [5]; p [7] = s [7]; p [8] = s [6];
1026 }
1027
1028 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1029
1030
1031 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1032
1033 int main (int argc, char **argv) // char *argv []
1034 { char c;
1035
1036 printf ("ix <database>\n");
1037 printf ("<database> ::= UNIX-ISIS (v.3) MF without .MST\n");
1038 printf ("ix ver. 0.3, Copyright (C) 2000 by Robert Janusz\n");
1039 printf ("ix comes with ABSOLUTELY NO WARRANTY\n");
1040 printf ("License: GPL; see http://www.gnu.org/ for details\n");
1041
1042 for (c = 'A'; c <= 'z'; c++) // Let's prepare it, we use API, not an example
1043 UpCase [c] = UpMe (c);
1044
1045 if (argv [1] != NULL) {
1046 strcpy (DBpath, argv [1]); // Database; no test ! ;-) it's only an example
1047 isis ();
1048 }
1049
1050 return (0);
1051 }
1052
1053 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1054
1055 void isis ()
1056 {
1057 int j, v, k;
1058 long int nrc;
1059 BaseCtrl bc;
1060 RecCtrl rc;
1061 char st [31];
1062 TableQuery tabq [NFIND];
1063
1064 strcpy (bc.name, DBpath);
1065 InitBase (&bc);
1066
1067 // ShowRec but not all...
1068
1069 printf ("\n*** ShowRec ***\n\n");
1070
1071 //for (nrc = 1L; nrc < bc.mctrl.nxtmfn; nrc++) {
1072 for (nrc = 10L; nrc < 20L; nrc++) {
1073 if ((j = GetRec (&bc, nrc, &rc, RECLENGTH)) == 0) {
1074 ShowRec (&rc);
1075 }
1076 }
1077
1078 // ShowIndex
1079
1080 printf ("\n*** ShowIndex: %s ***\n\n", st);
1081
1082 strcpy (st, "TEST"); // just an Inv. File term
1083
1084 v = 0; // term counter
1085 k = IndexPrep (&bc, &tabq [0], &tabq [1], st); // prepare indexes
1086 while (k > 0) {
1087 j = 20 * k - 10; // We have the term length ;-)
1088 memcpy (&st, &tabq [k - 1].term [0], j); // keep it in st
1089 st [j] = 0;
1090 if ((v += 1) > 12) // we want 12 terms in a list
1091 {
1092 printf ("->%s\n", st); // the next term
1093 break;
1094 }
1095 printf ("%s\n", st);
1096 k = IndexTerm (k, &tabq [0], &tabq [1]); // Next term
1097 }
1098
1099 // Find a term & show records
1100
1101 printf ("\n*** Search for: %s ***\n\n", st); // Let's use the last term
1102
1103 setQuery (&bc, &tabq [0], st, 0); // String to search in a filed 0 = any
1104
1105 j = Find (&bc, tabq, 1, &nrc, &rc, RECLENGTH); // 1 term to search for
1106
1107 // Clean all
1108
1109 printf ("\nO.K.\n");
1110
1111 Done (&bc);
1112 }
1113
1114 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1115
1116 void ShowRec (RecCtrl *rc)
1117 { long int nr;
1118 short int n, k, kk;
1119 char st [256];
1120 char *b = rc->buf;
1121 mstHdrTxt *mht = &rc->hdrs.mht;
1122 mstIndex *ind = (mstIndex *) &rc->buf [sizeof (RecHeaders)];
1123
1124 nr = rc->hdrs.mhf.mfn; // Record header
1125
1126 printf ("=== %li\n", nr);
1127 for (n = 0; n < mht->nvf; n++)
1128 { // Show fileds without formating
1129 printf ("*** [%li] ", (long int) ind->tag);
1130 k = mht->base + ind->pos;
1131 for (kk = 0; kk < ind->len; kk++)
1132 printf ("%c", b [k++]);
1133 printf ("\n");
1134 ind += 1; // Next index
1135 }
1136 printf ("___\n");
1137 }
1138
1139 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1140
1141 // This procedure is prepared to do a simple AND operator after some
1142 // extensions, so it can be localy a little strange ;-)
1143
1144 int Postings (BaseCtrl *bc, TableQuery tabq [], int ifind, long int *npg
1145 , RecCtrl *rc, long int recvol)
1146 { int j, state;
1147 long int ipg, rn;
1148 ifpPosting ip;
1149 TableQuery *tq;
1150
1151 if (ifind < 1) goto finish; // nothing to do
1152
1153 ipg = 1L; // Index for page break
1154
1155 { tq = &tabq [0]; // Let's think only about one term to handle (example)
1156 if (PostSeg (bc, tq) != 0) return (-1);
1157 tq->iall = tq->ihd.ifptotp; // Only 1st Segment has tot. post. number
1158 tq->iitot = 0;
1159 if (PostNext (bc, tq) != 0) return (-1);
1160 PostInv (&ip, tq->ipst);
1161 if (sComp (tq->st, tq->term, 20 * tq->it - 10) != 0)
1162 ipg = 0L; // the term not found
1163 }
1164
1165 if (ipg != 1L) goto finish;
1166
1167 for ( ; ; ) // Global loop...
1168 {
1169
1170 // Is there a field
1171 { tq = &tabq [0];
1172 if (tq->v != 0)
1173 while (ip.ptag != tq->v)
1174 {
1175 if (PostNext (bc, tq) > 0) goto finish; // No more postings
1176 PostInv (&ip, tq->ipst);
1177 }
1178 }
1179
1180 rn = ip.pmfn;
1181
1182 state = 1;
1183 if (ip.pmfn != rn)
1184 state = 0;
1185
1186 if (state) // We have a record to show
1187 {
1188 if ((j = GetRec (bc, rn, rc, recvol)) == 0)
1189 ShowRec (rc);
1190 else
1191 printf ("Record state = %li\n", j);
1192
1193 do // Shift all postings
1194 { tq = &tabq [0];
1195 if (PostNext (bc, tq) > 0) goto finish; // No more postings
1196 PostInv (&ip, tq->ipst);
1197 }
1198 while (ip.pmfn <= rn); // MFN equals
1199 }
1200 else // state == 0, Shift all postings
1201 while (ip.pmfn < rn) // The last is to examin
1202 { tq = &tabq [0];
1203 if (PostNext (bc, tq) > 0) goto finish; // No more postings
1204 PostInv (&ip, tq->ipst);
1205 }
1206 }
1207
1208 finish:
1209 return (0); // The output is finished
1210 }
1211
1212 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1213

Properties

Name Value
svn:executable

  ViewVC Help
Powered by ViewVC 1.1.26