DtSearch/raima: remove register keyword
[oweals/cde.git] / cde / lib / DtSearch / raima / libfcns.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: libfcns.c /main/2 1996/05/09 04:11:16 drk $ */
24 /*
25  *   COMPONENT_NAME: austext
26  *
27  *   FUNCTIONS: ADDRcmp
28  *              INTcmp
29  *              Pi
30  *              check_dba
31  *              ctblcmp
32  *              dbn_check
33  *              fldcmp
34  *              nfld_check
35  *              nrec_check
36  *              nset_check
37  *              null_dba
38  *              rec_okay
39  *
40  *   ORIGINS: 157
41  *
42  *   OBJECT CODE ONLY SOURCE MATERIALS
43  */
44 /*****************************************************************************
45    Miscellaneous db_VISTA library functions
46 *****************************************************************************/
47
48 /* ********************** EDIT HISTORY *******************************
49
50  SCR    DATE    INI                   DESCRIPTION
51 ----- --------- --- -----------------------------------------------------
52   255 30-Jun-88 RSC check_dba: don't assume page 0 read
53   115 19-Jul-88 RSC Integrate VAX/VMS changes
54       04-Aug-88 RTK MULTI_TASK changes
55   310 10-Aug-88 RSC Cleanup function prototype.
56       18-Aug-88 RSC Moved rn_type/dba to separate table
57   424 21-Sep-88 RSC Integrate international character set (ESM)
58   420 06-Dec-88 WLW Updated Curr_db_table when using setdb.
59 */
60
61 #include <stdio.h>
62 #include "vista.h"
63 #include "dbtype.h"
64
65 /* Internal function prototypes */
66 static int rec_okay(P1(int) Pi(int *) 
67                                    Pi(RECORD_ENTRY FAR * FAR *));
68 static int ctblcmp(P1(CONST unsigned char FAR*)
69                                   Pi(CONST unsigned char FAR*) Pi(int));
70
71 #ifndef  ONE_DB
72 /* Check for valid db number and set curr_db, curr_db_table and curr_rn_table
73 */
74 int
75 dbn_check(dbn)
76 int dbn;
77 {
78    if ( ! dbopen ) 
79       return( dberr(S_DBOPEN) );
80
81    if ( no_of_dbs > 1 && ! setdb_on ) {
82       if ( dbn < 0 || dbn >= no_of_dbs )
83          return( dberr(S_INVDB) );
84       db_table[curr_db].curr_dbt_rec = curr_rec;
85       curr_db_table = &db_table[curr_db = dbn];
86       curr_rn_table = &rn_table[curr_db];       /* point to new rn_table */
87       curr_rec = curr_db_table->curr_dbt_rec;
88    }
89    return( db_status = S_OKAY );
90 }
91 #endif
92
93
94 /* Check for valid (external) set number and return (internal) set number
95    and set_table pointer.
96 */
97 int
98 nset_check(nset, set, set_ptr )
99 int nset;
100 int *set;
101 SET_ENTRY FAR * FAR *set_ptr;
102 {
103    nset -= SETMARK;
104    if ((nset < 0) || (nset >= TABLE_SIZE(Size_st)))
105       return( dberr(S_INVSET) );
106
107    *set_ptr = &set_table[*set = NUM2INT(nset, st_offset)];
108    return( db_status = S_OKAY );
109 }
110
111
112 /* Check for valid (external) field number and return (internal) record
113    and field numbers and pointers.
114 */
115 int
116 nfld_check(nfld, rec, fld, rec_ptr, fld_ptr )
117 long nfld;
118 int *rec;
119 int *fld;
120 RECORD_ENTRY FAR * FAR *rec_ptr;
121 FIELD_ENTRY FAR * FAR *fld_ptr;
122 {
123    int trec;
124    int tfld;
125
126    if (!rec_okay(trec = (int)(nfld/FLDMARK), rec, (RECORD_ENTRY FAR * FAR *)rec_ptr) ||
127        ((tfld = (int)(nfld - trec*FLDMARK)) < 0) ||
128        (tfld >= TABLE_SIZE(Size_fd)))
129       return( dberr(S_INVFLD) );
130
131    *fld_ptr = &field_table[*fld = tfld + (*rec_ptr)->rt_fields];
132    return( db_status = S_OKAY );
133 }
134
135
136
137 /* Check for valid (external) record number and return (internal) record
138    number and pointer.
139 */
140 int
141 nrec_check(nrec, rec, rec_ptr)
142 int nrec;
143 int *rec;
144 RECORD_ENTRY FAR * FAR *rec_ptr;
145 {
146    if (rec_okay(nrec - RECMARK, rec, (RECORD_ENTRY FAR * FAR *)rec_ptr))
147       db_status = S_OKAY;
148    else
149       dberr(S_INVREC);
150    return( db_status );
151 }
152
153
154 /* Internal record number check
155 */
156 static int rec_okay(nrec, rec, rec_ptr)
157 int nrec;
158 int *rec;
159 RECORD_ENTRY FAR * FAR *rec_ptr;
160 {
161    if ((nrec < 0) || (nrec >= TABLE_SIZE(Size_rt)))
162       return (FALSE);
163
164    *rec_ptr = &record_table[*rec = NUM2INT(nrec, rt_offset)];
165    return (TRUE);
166 }
167
168
169 /* Compare values of two db_VISTA data fields
170 */
171 int fldcmp(fld_ptr, f1, f2)
172 FIELD_ENTRY FAR *fld_ptr;
173 CONST char FAR *f1;   /* pointer to field 1 */
174 CONST char FAR *f2;   /* pointer to field 2 */
175 /*
176    returns < 0 if f1 < f2,
177            = 0 if f1 == f2,
178            > 0 if f1 > f2
179 */
180 {
181    int kt_lc;                   /* loop control */
182    int i, k, elt, result, len, cur_len, sub_len, entries;
183 #ifdef DS
184    int ui1, ui2;
185    long ul1, ul2;
186    short us1, us2;
187 #else
188    unsigned int ui1, ui2;
189    unsigned long ul1, ul2;
190    unsigned short us1, us2;
191 #endif
192    int i1, i2;
193    long l1, l2;
194    short s1, s2;
195 #ifndef  NO_FLOAT
196    float F1, F2;
197    double d1, d2;
198 #endif
199    FIELD_ENTRY FAR *fld_max;
200    FIELD_ENTRY FAR *sfld_ptr;
201    KEY_ENTRY FAR *key_ptr;
202    INT FAR *dim_ptr;
203
204    len = fld_ptr->fd_len;
205
206    /* compute number of array elements */
207    entries = 1;
208    for (i = 0, dim_ptr = fld_ptr->fd_dim;
209         (i < MAXDIMS) && *dim_ptr;
210         ++i, ++dim_ptr)
211       entries *= *dim_ptr;
212
213    switch ( fld_ptr->fd_type ) {
214       case CHARACTER:
215          if ( fld_ptr->fd_dim[1] )
216             return ( bytecmp(f1, f2, len) );
217          else if ( fld_ptr->fd_dim[0] )
218          {
219 #ifdef NO_COUNTRY
220             return ( strncmp(f1, f2, len) );
221 #else
222             if ( db_global.ctbl_activ ) return ( ctblcmp(f1, f2, len) );
223             else return ( strncmp(f1, f2, len) );
224 #endif
225          }
226          else
227             return ( (int)(*f1) - (int)(*f2) );
228       case REGINT:
229          for ( result = elt = 0; result == 0 && elt < entries; ++elt ) {
230             if ( fld_ptr->fd_flags & UNSIGNEDFLD ) {
231                bytecpy(&ui1, f1+(elt*sizeof(int)), sizeof(int));
232                bytecpy(&ui2, f2+(elt*sizeof(int)), sizeof(int));
233                if ( ui1 < ui2 ) result = -1;
234                else if ( ui1 > ui2 ) result =  1;
235             }
236             else {
237                bytecpy(&i1, f1+(elt*sizeof(int)), sizeof(int));
238                bytecpy(&i2, f2+(elt*sizeof(int)), sizeof(int));
239                if ( i1 < i2 ) result = -1;
240                else if ( i1 > i2 ) result =  1;
241             }
242          }
243          break;
244       case LONGINT:
245          for ( result = elt = 0; result == 0 && elt < entries; ++elt ) {
246             if ( fld_ptr->fd_flags & UNSIGNEDFLD ) {
247                bytecpy(&ul1, f1+(elt*sizeof(long)), sizeof(long));
248                bytecpy(&ul2, f2+(elt*sizeof(long)), sizeof(long));
249                if ( ul1 < ul2 ) result = -1;
250                else if ( ul1 > ul2 ) result =  1;
251             }
252             else {
253                bytecpy(&l1, f1+(elt*sizeof(long)), sizeof(long));
254                bytecpy(&l2, f2+(elt*sizeof(long)), sizeof(long));
255                if ( l1 < l2 ) result = -1;
256                else if ( l1 > l2 ) result =  1;
257             }
258          }
259          break;
260       case SHORTINT:
261          for ( result = elt = 0; result == 0 && elt < entries; ++elt ) {
262             if ( fld_ptr->fd_flags & UNSIGNEDFLD ) {
263                bytecpy(&us1, f1+(elt*sizeof(short)), sizeof(short));
264                bytecpy(&us2, f2+(elt*sizeof(short)), sizeof(short));
265                if ( us1 < us2 ) result = -1;
266                else if ( us1 > us2 ) result =  1;
267             }
268             else {
269                bytecpy(&s1, f1+(elt*sizeof(short)), sizeof(short));
270                bytecpy(&s2, f2+(elt*sizeof(short)), sizeof(short));
271                if ( s1 < s2 ) result = -1;
272                else if ( s1 > s2 ) result =  1;
273             }
274          }
275          break;
276 #ifndef  NO_FLOAT
277       case FLOAT:
278          for ( result = elt = 0; result == 0 && elt < entries; ++elt ) {
279             bytecpy(&F1, f1+(elt*sizeof(float)), sizeof(float));
280             bytecpy(&F2, f2+(elt*sizeof(float)), sizeof(float));
281             if ( F1 < F2 )  result = -1;
282             else if ( F1 > F2 )  result = 1;
283          }
284          break;
285       case DOUBLE:
286          for ( result = elt = 0; result == 0 && elt < entries; ++elt ) {
287             bytecpy(&d1, f1+(elt*sizeof(double)), sizeof(double));
288             bytecpy(&d2, f2+(elt*sizeof(double)), sizeof(double));
289             if ( d1 < d2 )  result = -1;
290             else if ( d1 > d2 )  result = 1;
291          }
292          break;
293 #endif
294       case DBADDR:
295          for ( result = elt = 0; result == 0 && elt < entries; ++elt ) {
296             result = ADDRcmp((DB_ADDR FAR *)(f1+(elt*sizeof(DB_ADDR))),
297                              (DB_ADDR FAR *)(f2+(elt*sizeof(DB_ADDR))));
298          }
299          break;
300       case GROUPED:
301          len /= entries; /* length of each entry */
302          fld_max = &field_table[size_fd];
303          for (i = 0, cur_len = 0; i < entries; ++i, cur_len += len) {
304             for (sfld_ptr = fld_ptr + 1;
305                  (sfld_ptr < fld_max) && (sfld_ptr->fd_flags & STRUCTFLD);
306                  ++sfld_ptr) {
307                sub_len = cur_len + sfld_ptr->fd_ptr - fld_ptr->fd_ptr;
308                if ((k = fldcmp(sfld_ptr, f1 + sub_len, f2 + sub_len)))
309                   return ( k );
310             }
311          }
312          return ( 0 );
313       case COMKEY:
314          for (kt_lc = size_kt - fld_ptr->fd_ptr,
315                                         key_ptr = &key_table[fld_ptr->fd_ptr];
316               (--kt_lc >= 0) && (&field_table[key_ptr->kt_key] == fld_ptr);
317               ++key_ptr) {
318             i = key_ptr->kt_ptr;
319             if (( k = fldcmp(&field_table[key_ptr->kt_field], f1 + i, f2 + i) ))
320                return ( k );
321          }
322          return ( 0 );
323    }
324    return( result );
325 }
326
327
328 /* compare the INT variables
329 */
330 int INTcmp( i1, i2 )
331 CONST char FAR *i1, FAR *i2;
332 {
333    INT I1, I2;
334
335    bytecpy( &I1, i1, sizeof(INT) );
336    bytecpy( &I2, i2, sizeof(INT) );
337    return( (int)( I1-I2 ) );
338 }
339
340
341 /* compare two DB_ADDR variables 
342 */
343 int ADDRcmp( d1, d2 )
344 CONST DB_ADDR FAR *d1, FAR *d2;
345 {
346    DB_ADDR a1, a2;
347    FILE_NO f1, f2;
348    F_ADDR r1, r2;
349
350    bytecpy(&a1, d1, DB_ADDR_SIZE);
351    bytecpy(&a2, d2, DB_ADDR_SIZE);
352
353    f1 = (FILE_NO)(FILEMASK & (a1 >> FILESHIFT));
354    f2 = (FILE_NO)(FILEMASK & (a2 >> FILESHIFT));
355    r1 = ADDRMASK & a1;
356    r2 = ADDRMASK & a2;
357    
358    if ( f1 == f2 ) {
359       if ( r1 < r2 ) return( -1 );
360       if ( r1 > r2 ) return( 1 );
361       return( 0 );
362    }
363    else 
364       return(f1 - f2);
365 }
366
367
368
369
370 /* check for empty DB_ADDR
371 */
372 int
373 null_dba( db_addr )
374 CONST char FAR *db_addr;
375 {
376    DB_ADDR dba;
377
378    bytecpy( &dba, db_addr, DB_ADDR_SIZE );
379    return( dba == NULL_DBA );
380 }
381
382
383 /* check for valid DB_ADDR
384 */
385 int
386 check_dba( dba )
387 DB_ADDR dba;
388 {
389    FILE_NO fno;
390    F_ADDR  rno, last;
391
392    fno = (FILE_NO)(FILEMASK & (dba >> FILESHIFT));
393    rno = ADDRMASK & dba;
394
395    /* Make sure page 0 has been read */
396    if ( (last = dio_pznext(NUM2INT(fno, ft_offset))) <= 0 )
397       return( db_status );
398
399    if (((fno < 0) || (fno >= TABLE_SIZE(Size_ft))) ||
400        ((rno <= 0L) || (rno >= last)))
401       dberr(S_INVADDR);
402    else
403       db_status = S_OKAY;
404
405    return( db_status );
406 }
407
408 #ifndef NO_COUNTRY
409 /* Compare two strings with sorting according to char-table
410 */
411 static int ctblcmp(s, t, n)
412 CONST unsigned char FAR *s;  /* String 1 */
413 CONST unsigned char FAR *t;  /* String 2 */
414 int    n;   /* Max. String length */
415 {
416    int x;
417    unsigned char   f1, f2, x1, x2;
418
419    /* Always return immediately if first difference found */
420    for (; (n && *s && *t); n--) {
421       if ( db_global.country_tbl.ptr[*s].sort_as1 )
422          f1 = db_global.country_tbl.ptr[*s].sort_as1;
423       else f1 = *s;
424       if ( db_global.country_tbl.ptr[*t].sort_as1 )
425          f2 = db_global.country_tbl.ptr[*t].sort_as1;
426       else f2 = *t;
427
428       if ((x = f1 - f2)) return(x);
429  
430       /* Check sort_as2-values if sort_as1-values are equal */
431       /*----------------------------------------------------*/
432       x1 = db_global.country_tbl.ptr[*s].sort_as2;
433       x2 = db_global.country_tbl.ptr[*t].sort_as2;
434       if ( x1 && x2 ) {  /* We have an entry for char. of both strings */
435          if (( x = x1 - x2 )) return(x);
436       }
437       else {
438          if ( x1 || x2 ) { /* Only sort_as2 value for one string */
439             if ( x1 ) {
440                *t++;    /* Compare with next character in string 2 */
441                if ( db_global.country_tbl.ptr[*t].sort_as1 )
442                   f2 = db_global.country_tbl.ptr[*t].sort_as1;
443                else f2 = *t;
444                if (( x = x1 - f2 )) return(x);
445             }
446             if ( x2 ) {
447                *s++;    /* Compare with next character in string 1 */
448                if ( db_global.country_tbl.ptr[*s].sort_as1 )
449                   f1 = db_global.country_tbl.ptr[*s].sort_as1;
450                else f1 = *s;
451                if (( x = f1 - x2 )) return(x);
452             }
453          }
454
455          /* if both are equal compare sub_sort values */
456          /*-------------------------------------------*/
457          if ((x = db_global.country_tbl.ptr[*s].sub_sort -
458                 db_global.country_tbl.ptr[*t].sub_sort))
459             return(x);  
460       }
461       *s++;
462       *t++;
463    }
464    if (n) {
465       if (*s) return(1);
466       if (*t) return(-1);
467    }
468    return(0);
469 }
470 #endif
471 /* vpp -nOS2 -dUNIX -nBSD -nVANILLA_BSD -nVMS -nMEMLOCK -nWINDOWS -nFAR_ALLOC -f/usr/users/master/config/nonwin libfcns.c */