2 openisis - an open implementation of the CDS/ISIS database
3 Version 0.8.x (patchlevel see file Version)
4 Copyright (C) 2001-2003 by Erik Grziwotz, erik@openisis.org
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 see README for more information
24 $Id: lstr.c,v 1.13 2003/04/08 00:20:53 kripke Exp $
25 implementation of record cooking.
33 /* ************************************************************
36 /* ************************************************************
39 static const char * nameMfc[] = {
40 "Mfc", "CTLM", "NMFN", "NMFB", "NMFP", "TYPE", "RCNT", "MFX1", "MFX2", "MFX3"
43 static int descMfc[] = {
44 LSTRSIZE( 9, 0, 0 ), /* sizes (fix, rep, occ) */
58 static const char * nameMfr[] = {
59 "Mfr", "MFN", "RECL", "BWB", "BWP", "BASE", "NVF", "STAT",
62 static int descMfr[] = {
63 LSTRSIZE( 7, 3, 0 ), /* sizes (fix, rep, occ) */
80 static int descMfrA[] = {
81 LSTRSIZE( 7, 3, 0 ), /* sizes (fix, rep, occ) */
85 LSTRLOFF( LMBRINT, 8 ),
97 static const char * nameXrf[] = {
100 static int descXrf[] = {
101 LSTRSIZE( 1, 1, 127 ), /* sizes (fix, rep, occ) */
107 static const char ** nameMst[LSTR_MST] = {
108 nameMfc, nameMfr, nameXrf
111 static int* descMst[LSTR_MST] = {
112 descMfc, /* MST head */
113 descMfr, /* MST record */
114 descXrf /* XRF record */
117 static int* descMstA[LSTR_MST] = {
118 descMfc, /* MST head */
119 descMfrA, /* MST record */
120 descXrf /* XRF record */
124 static const char * nameCnt[] = {
125 "Cnt", "TYPE", "ORDN", "ORDF", "N", "K", "LEV", "POSR", "NMAX", "FMAX", "ABNO"
127 static int descCnt[] = {
128 LSTRSIZE( 10, 0, 0 ), /* sizes (fix, rep, occ) */
130 LMBRSHORT, /* TYPE */
131 LMBRSHORT, /* ORDN */
132 LMBRSHORT, /* ORDF */
142 static int descCntA[] = {
143 LSTRSIZE( 10, 0, 0 ), /* sizes (fix, rep, occ) */
145 LMBRSHORT, /* TYPE */
146 LMBRSHORT, /* ORDN */
147 LMBRSHORT, /* ORDF */
157 static const char * nameN0[] = {
158 "N0", "POS", "OCK", "TYPE", "'KEY", "REF"
160 static int descN01[] = {
161 LSTRSIZE( 3, 2, 10 ), /* sizes (fix, rep, occ) */
165 LMBRSHORT, /* TYPE */
170 static int descN01A[] = {
171 LSTRSIZE( 3, 2, 10 ), /* sizes (fix, rep, occ) */
175 LMBRSHORT, /* TYPE */
177 LSTRLOFF( LMBRINT, 12 ) /* REF */
180 static int descN02[] = {
181 LSTRSIZE( 3, 2, 10 ), /* sizes (fix, rep, occ) */
185 LMBRSHORT, /* TYPE */
189 static int descN02A[] = {
190 LSTRSIZE( 3, 2, 10 ), /* sizes (fix, rep, occ) */
194 LMBRSHORT, /* TYPE */
196 LSTRLOFF( LMBRINT, 32 ) /* REF */
199 static const char * nameL0[] = {
200 "L0", "POS", "OCK", "TYPE", "PS", "'KEY", "INFB", "INFP"
202 static int descL01[] = {
203 LSTRSIZE( 4, 3, 10 ), /* sizes (fix, rep, occ) */
207 LMBRSHORT, /* TYPE */
213 static int descL01A[] = {
214 LSTRSIZE( 4, 3, 10 ), /* sizes (fix, rep, occ) */
218 LMBRSHORT, /* TYPE */
221 LSTRLOFF( LMBRINT, 12 ), /* INFB */
226 static int descL02[] = {
227 LSTRSIZE( 4, 3, 10 ), /* sizes (fix, rep, occ) */
231 LMBRSHORT, /* TYPE */
237 static int descL02A[] = {
238 LSTRSIZE( 4, 3, 10 ), /* sizes (fix, rep, occ) */
242 LMBRSHORT, /* TYPE */
245 LSTRLOFF( LMBRINT, 32 ), /* INFB */
249 static const char * nameIfp[] = {
250 "IfH", "NXTB", "NXTP", "TOTP", "SEGP", "SEGC", "MFN", "INFO"
252 static int descIfp[] = {
253 #ifdef CONVERT_POSTINGS
255 to properly convert postings,
256 the repeated part needs to be a big-endian 64bit int
258 however, converting can't be done in a straightforward fashion anyway,
259 since posting segments have holes of one or two longs at block boundaries
261 LSTRSIZE( 5, 2, 1 ), /* sizes (fix, rep, occ) */
266 LSTRSIZE( 5, 0, 0 ), /* sizes (fix, rep, occ) */
276 static const char ** nameInv[LSTR_INV] = {
285 static int* descInv[LSTR_INV] = {
286 descCnt, /* CNT record */
287 descN01, /* N01 record */
288 descL01, /* L01 record */
289 descN02, /* N02 record */
290 descL02, /* L02 record */
291 descIfp /* Ifp record */
294 static int* descInvA[LSTR_INV] = {
295 descCntA, /* CNT record */
296 descN01A, /* N01 record */
297 descL01A, /* L01 record */
298 descN02A, /* N02 record */
299 descL02A, /* L02 record */
300 descIfp /* Ifp record */
304 /* ************************************************************
307 /* ************************************************************
310 const LstrSet lstrlib[LSET_SETS] = {
312 nameMst, { descMst, descMstA }
315 nameInv, { descInv, descInvA }
319 /* ************************************************************
322 /* ************************************************************
325 int lstr_auto ( int *str ) {
326 static int pow2[] = { 1, 2, 4, 8 };
329 int *xmbrs, txlen, tilen;
330 int nmbrs, off = 0, xlen[2] = {0,0}, blen[2] = {0,0}, x=0;
335 for ( i=0; i<(int)(sizeof(x)/sizeof(x[0])); i++ ) \
336 if ( NULL != x[i] ) ret |= lstr_auto( x[i] )
347 xmbrs = str + LSTR_XMBR;
350 for ( x=0; ; x++ ) { /* fix and rep */
351 for ( i=0; i<nmbrs; i++ ) {
354 if ( LONG2OFF( xmbr ) )
355 off = LONG2OFF( xmbr );
357 xmbrs[i] |= off << 16;
359 if ( LMBRISNUM(xmbr) )
360 len = pow2[ LMBRLD(xmbr) ];
362 len = LONG2LEN(xmbr);
365 LOG_DBG( LOG_ALL, "x.i %d.%d off %3ld, xmbr %08x len %d",
366 x, i, off, xmbrs[i], len );
371 /* done with one part */
372 if ( x || !rep ) /* was 2nd */
378 /* got length's and buffer lengths of both parts */
379 LOG_DBG( LOG_ALL, "%08x %08x %d %d: xl %d %d bl %d %d",
380 str[0], str[1], str[2], str[3],
381 xlen[0], xlen[1], blen[0], blen[1] );
382 if ( !(short)(str[LSTR_XRLO] >> 16) )
383 str[LSTR_XRLO] |= xlen[0] << 16;
384 else if ( xlen[0] > (short)(str[LSTR_XRLO] >> 16) )
385 log_msg( LOG_WARN, "short xlen[0] %hd < %d",
386 (short)(str[LSTR_XRLO] >> 16), xlen[0] );
387 if ( !(short)str[LSTR_XRLO] )
388 str[LSTR_XRLO] |= 0xffff & xlen[1];
389 else if ( xlen[1] > (short)str[LSTR_XRLO] )
390 log_msg( LOG_WARN, "short xlen[1] %hd < %d",
391 (short)str[LSTR_XRLO], xlen[1] );
392 /* build totals applying occ */
393 txlen = (short)(str[LSTR_XRLO] >> 16)
394 + (int)occ*(short)str[LSTR_XRLO];
395 if ( !str[LSTR_XLEN] )
396 str[LSTR_XLEN] = txlen;
397 else if ( txlen > str[LSTR_XLEN] )
398 log_msg( LOG_WARN, "short xlen %d < %d",
399 str[LSTR_XLEN], txlen );
400 tilen = LSTRLEN(*str) + blen[0] + (int)occ*blen[1];
401 if ( !str[LSTR_ILEN] )
402 str[LSTR_ILEN] = tilen;
403 else if ( tilen > str[LSTR_ILEN] )
404 log_msg( LOG_WARN, "short ilen %d < %d",
405 str[LSTR_ILEN], tilen );
406 LOG_DBG( LOG_ALL, "%08x xrlo %08x xl %d il %d",
407 str[0], str[1], str[2], str[3] );