/[webpac]/openisis/current/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

Annotation of /openisis/current/iAPI.txt

Parent Directory Parent Directory | Revision Log Revision Log


Revision 237 - (hide annotations)
Mon Mar 8 17:43:12 2004 UTC (20 years ago) by dpavlin
File MIME type: text/plain
File size: 41321 byte(s)
initial import of openisis 0.9.0 vendor drop

1 dpavlin 237 /*
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