Add GNU LGPL headers to all .c .C and .h files
[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 librararies 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 dbn_check(dbn)
75 int dbn;
76 {
77    if ( ! dbopen ) 
78       return( dberr(S_DBOPEN) );
79
80    if ( no_of_dbs > 1 && ! setdb_on ) {
81       if ( dbn < 0 || dbn >= no_of_dbs )
82          return( dberr(S_INVDB) );
83       db_table[curr_db].curr_dbt_rec = curr_rec;
84       curr_db_table = &db_table[curr_db = dbn];
85       curr_rn_table = &rn_table[curr_db];       /* point to new rn_table */
86       curr_rec = curr_db_table->curr_dbt_rec;
87    }
88    return( db_status = S_OKAY );
89 }
90 #endif
91
92
93 /* Check for valid (external) set number and return (internal) set number
94    and set_table pointer.
95 */
96 nset_check(nset, set, set_ptr )
97 register int nset;
98 int *set;
99 SET_ENTRY FAR * FAR *set_ptr;
100 {
101    nset -= SETMARK;
102    if ((nset < 0) || (nset >= TABLE_SIZE(Size_st)))
103       return( dberr(S_INVSET) );
104
105    *set_ptr = &set_table[*set = NUM2INT(nset, st_offset)];
106    return( db_status = S_OKAY );
107 }
108
109
110 /* Check for valid (external) field number and return (internal) record
111    and field numbers and pointers.
112 */
113 nfld_check(nfld, rec, fld, rec_ptr, fld_ptr )
114 long nfld;
115 int *rec;
116 int *fld;
117 RECORD_ENTRY FAR * FAR *rec_ptr;
118 FIELD_ENTRY FAR * FAR *fld_ptr;
119 {
120    int trec;
121    int tfld;
122
123    if (!rec_okay(trec = (int)(nfld/FLDMARK), rec, (RECORD_ENTRY FAR * FAR *)rec_ptr) ||
124        ((tfld = (int)(nfld - trec*FLDMARK)) < 0) ||
125        (tfld >= TABLE_SIZE(Size_fd)))
126       return( dberr(S_INVFLD) );
127
128    *fld_ptr = &field_table[*fld = tfld + (*rec_ptr)->rt_fields];
129    return( db_status = S_OKAY );
130 }
131
132
133
134 /* Check for valid (external) record number and return (internal) record
135    number and pointer.
136 */
137 nrec_check(nrec, rec, rec_ptr)
138 int nrec;
139 int *rec;
140 RECORD_ENTRY FAR * FAR *rec_ptr;
141 {
142    if (rec_okay(nrec - RECMARK, rec, (RECORD_ENTRY FAR * FAR *)rec_ptr))
143       db_status = S_OKAY;
144    else
145       dberr(S_INVREC);
146    return( db_status );
147 }
148
149
150 /* Internal record number check
151 */
152 static int rec_okay(nrec, rec, rec_ptr)
153 register int nrec;
154 int *rec;
155 RECORD_ENTRY FAR * FAR *rec_ptr;
156 {
157    if ((nrec < 0) || (nrec >= TABLE_SIZE(Size_rt)))
158       return (FALSE);
159
160    *rec_ptr = &record_table[*rec = NUM2INT(nrec, rt_offset)];
161    return (TRUE);
162 }
163
164
165 /* Compare values of two db_VISTA data fields
166 */
167 int fldcmp(fld_ptr, f1, f2)
168 FIELD_ENTRY FAR *fld_ptr;
169 CONST char FAR *f1;   /* pointer to field 1 */
170 CONST char FAR *f2;   /* pointer to field 2 */
171 /*
172    returns < 0 if f1 < f2,
173            = 0 if f1 == f2,
174            > 0 if f1 > f2
175 */
176 {
177    register int kt_lc;                  /* loop control */
178    int i, k, elt, result, len, cur_len, sub_len, entries;
179 #ifdef DS
180    int ui1, ui2;
181    long ul1, ul2;
182    short us1, us2;
183 #else
184    unsigned int ui1, ui2;
185    unsigned long ul1, ul2;
186    unsigned short us1, us2;
187 #endif
188    int i1, i2;
189    long l1, l2;
190    short s1, s2;
191 #ifndef  NO_FLOAT
192    float F1, F2;
193    double d1, d2;
194 #endif
195    FIELD_ENTRY FAR *fld_max;
196    FIELD_ENTRY FAR *sfld_ptr;
197    KEY_ENTRY FAR *key_ptr;
198    INT FAR *dim_ptr;
199
200    len = fld_ptr->fd_len;
201
202    /* compute number of array elements */
203    entries = 1;
204    for (i = 0, dim_ptr = fld_ptr->fd_dim;
205         (i < MAXDIMS) && *dim_ptr;
206         ++i, ++dim_ptr)
207       entries *= *dim_ptr;
208
209    switch ( fld_ptr->fd_type ) {
210       case CHARACTER:
211          if ( fld_ptr->fd_dim[1] )
212             return ( bytecmp(f1, f2, len) );
213          else if ( fld_ptr->fd_dim[0] )
214          {
215 #ifdef NO_COUNTRY
216             return ( strncmp(f1, f2, len) );
217 #else
218             if ( db_global.ctbl_activ ) return ( ctblcmp(f1, f2, len) );
219             else return ( strncmp(f1, f2, len) );
220 #endif
221          }
222          else
223             return ( (int)(*f1) - (int)(*f2) );
224       case REGINT:
225          for ( result = elt = 0; result == 0 && elt < entries; ++elt ) {
226             if ( fld_ptr->fd_flags & UNSIGNEDFLD ) {
227                bytecpy(&ui1, f1+(elt*sizeof(int)), sizeof(int));
228                bytecpy(&ui2, f2+(elt*sizeof(int)), sizeof(int));
229                if ( ui1 < ui2 ) result = -1;
230                else if ( ui1 > ui2 ) result =  1;
231             }
232             else {
233                bytecpy(&i1, f1+(elt*sizeof(int)), sizeof(int));
234                bytecpy(&i2, f2+(elt*sizeof(int)), sizeof(int));
235                if ( i1 < i2 ) result = -1;
236                else if ( i1 > i2 ) result =  1;
237             }
238          }
239          break;
240       case LONGINT:
241          for ( result = elt = 0; result == 0 && elt < entries; ++elt ) {
242             if ( fld_ptr->fd_flags & UNSIGNEDFLD ) {
243                bytecpy(&ul1, f1+(elt*sizeof(long)), sizeof(long));
244                bytecpy(&ul2, f2+(elt*sizeof(long)), sizeof(long));
245                if ( ul1 < ul2 ) result = -1;
246                else if ( ul1 > ul2 ) result =  1;
247             }
248             else {
249                bytecpy(&l1, f1+(elt*sizeof(long)), sizeof(long));
250                bytecpy(&l2, f2+(elt*sizeof(long)), sizeof(long));
251                if ( l1 < l2 ) result = -1;
252                else if ( l1 > l2 ) result =  1;
253             }
254          }
255          break;
256       case SHORTINT:
257          for ( result = elt = 0; result == 0 && elt < entries; ++elt ) {
258             if ( fld_ptr->fd_flags & UNSIGNEDFLD ) {
259                bytecpy(&us1, f1+(elt*sizeof(short)), sizeof(short));
260                bytecpy(&us2, f2+(elt*sizeof(short)), sizeof(short));
261                if ( us1 < us2 ) result = -1;
262                else if ( us1 > us2 ) result =  1;
263             }
264             else {
265                bytecpy(&s1, f1+(elt*sizeof(short)), sizeof(short));
266                bytecpy(&s2, f2+(elt*sizeof(short)), sizeof(short));
267                if ( s1 < s2 ) result = -1;
268                else if ( s1 > s2 ) result =  1;
269             }
270          }
271          break;
272 #ifndef  NO_FLOAT
273       case FLOAT:
274          for ( result = elt = 0; result == 0 && elt < entries; ++elt ) {
275             bytecpy(&F1, f1+(elt*sizeof(float)), sizeof(float));
276             bytecpy(&F2, f2+(elt*sizeof(float)), sizeof(float));
277             if ( F1 < F2 )  result = -1;
278             else if ( F1 > F2 )  result = 1;
279          }
280          break;
281       case DOUBLE:
282          for ( result = elt = 0; result == 0 && elt < entries; ++elt ) {
283             bytecpy(&d1, f1+(elt*sizeof(double)), sizeof(double));
284             bytecpy(&d2, f2+(elt*sizeof(double)), sizeof(double));
285             if ( d1 < d2 )  result = -1;
286             else if ( d1 > d2 )  result = 1;
287          }
288          break;
289 #endif
290       case DBADDR:
291          for ( result = elt = 0; result == 0 && elt < entries; ++elt ) {
292             result = ADDRcmp((DB_ADDR FAR *)(f1+(elt*sizeof(DB_ADDR))),
293                              (DB_ADDR FAR *)(f2+(elt*sizeof(DB_ADDR))));
294          }
295          break;
296       case GROUPED:
297          len /= entries; /* length of each entry */
298          fld_max = &field_table[size_fd];
299          for (i = 0, cur_len = 0; i < entries; ++i, cur_len += len) {
300             for (sfld_ptr = fld_ptr + 1;
301                  (sfld_ptr < fld_max) && (sfld_ptr->fd_flags & STRUCTFLD);
302                  ++sfld_ptr) {
303                sub_len = cur_len + sfld_ptr->fd_ptr - fld_ptr->fd_ptr;
304                if (k = fldcmp(sfld_ptr, f1 + sub_len, f2 + sub_len))
305                   return ( k );
306             }
307          }
308          return ( 0 );
309       case COMKEY:
310          for (kt_lc = size_kt - fld_ptr->fd_ptr,
311                                         key_ptr = &key_table[fld_ptr->fd_ptr];
312               (--kt_lc >= 0) && (&field_table[key_ptr->kt_key] == fld_ptr);
313               ++key_ptr) {
314             i = key_ptr->kt_ptr;
315             if ( k = fldcmp(&field_table[key_ptr->kt_field], f1 + i, f2 + i) )
316                return ( k );
317          }
318          return ( 0 );
319    }
320    return( result );
321 }
322
323
324 /* compare the INT variables
325 */
326 int INTcmp( i1, i2 )
327 CONST char FAR *i1, FAR *i2;
328 {
329    INT I1, I2;
330
331    bytecpy( &I1, i1, sizeof(INT) );
332    bytecpy( &I2, i2, sizeof(INT) );
333    return( (int)( I1-I2 ) );
334 }
335
336
337 /* compare two DB_ADDR variables 
338 */
339 int ADDRcmp( d1, d2 )
340 CONST DB_ADDR FAR *d1, FAR *d2;
341 {
342    DB_ADDR a1, a2;
343    FILE_NO f1, f2;
344    F_ADDR r1, r2;
345
346    bytecpy(&a1, d1, DB_ADDR_SIZE);
347    bytecpy(&a2, d2, DB_ADDR_SIZE);
348
349    f1 = (FILE_NO)(FILEMASK & (a1 >> FILESHIFT));
350    f2 = (FILE_NO)(FILEMASK & (a2 >> FILESHIFT));
351    r1 = ADDRMASK & a1;
352    r2 = ADDRMASK & a2;
353    
354    if ( f1 == f2 ) {
355       if ( r1 < r2 ) return( -1 );
356       if ( r1 > r2 ) return( 1 );
357       return( 0 );
358    }
359    else 
360       return(f1 - f2);
361 }
362
363
364
365
366 /* check for empty DB_ADDR
367 */
368 null_dba( db_addr )
369 CONST char FAR *db_addr;
370 {
371    DB_ADDR dba;
372
373    bytecpy( &dba, db_addr, DB_ADDR_SIZE );
374    return( dba == NULL_DBA );
375 }
376
377
378 /* check for valid DB_ADDR
379 */
380 check_dba( dba )
381 DB_ADDR dba;
382 {
383    FILE_NO fno;
384    F_ADDR  rno, last;
385
386    fno = (FILE_NO)(FILEMASK & (dba >> FILESHIFT));
387    rno = ADDRMASK & dba;
388
389    /* Make sure page 0 has been read */
390    if ( (last = dio_pznext(NUM2INT(fno, ft_offset))) <= 0 )
391       return( db_status );
392
393    if (((fno < 0) || (fno >= TABLE_SIZE(Size_ft))) ||
394        ((rno <= 0L) || (rno >= last)))
395       dberr(S_INVADDR);
396    else
397       db_status = S_OKAY;
398
399    return( db_status );
400 }
401
402 #ifndef NO_COUNTRY
403 /* Compare two strings with sorting according to char-table
404 */
405 static int ctblcmp(s, t, n)
406 CONST unsigned char FAR *s;  /* String 1 */
407 CONST unsigned char FAR *t;  /* String 2 */
408 int    n;   /* Max. String length */
409 {
410    int x;
411    unsigned char   f1, f2, x1, x2;
412
413    /* Always return immediately if first difference found */
414    for (; (n && *s && *t); n--) {
415       if ( db_global.country_tbl.ptr[*s].sort_as1 )
416          f1 = db_global.country_tbl.ptr[*s].sort_as1;
417       else f1 = *s;
418       if ( db_global.country_tbl.ptr[*t].sort_as1 )
419          f2 = db_global.country_tbl.ptr[*t].sort_as1;
420       else f2 = *t;
421
422       if (x = f1 - f2) return(x);
423  
424       /* Check sort_as2-values if sort_as1-values are equal */
425       /*----------------------------------------------------*/
426       x1 = db_global.country_tbl.ptr[*s].sort_as2;
427       x2 = db_global.country_tbl.ptr[*t].sort_as2;
428       if ( x1 && x2 ) {  /* We have an entry for char. of both strings */
429          if ( x = x1 - x2 ) return(x);
430       }
431       else {
432          if ( x1 || x2 ) { /* Only sort_as2 value for one string */
433             if ( x1 ) {
434                *t++;    /* Compare with next character in string 2 */
435                if ( db_global.country_tbl.ptr[*t].sort_as1 )
436                   f2 = db_global.country_tbl.ptr[*t].sort_as1;
437                else f2 = *t;
438                if ( x = x1 - f2 ) return(x);
439             }
440             if ( x2 ) {
441                *s++;    /* Compare with next character in string 1 */
442                if ( db_global.country_tbl.ptr[*s].sort_as1 )
443                   f1 = db_global.country_tbl.ptr[*s].sort_as1;
444                else f1 = *s;
445                if ( x = f1 - x2 ) return(x);
446             }
447          }
448
449          /* if both are equal compare sub_sort values */
450          /*-------------------------------------------*/
451          if (x = db_global.country_tbl.ptr[*s].sub_sort -
452                 db_global.country_tbl.ptr[*t].sub_sort)
453             return(x);  
454       }
455       *s++;
456       *t++;
457    }
458    if (n) {
459       if (*s) return(1);
460       if (*t) return(-1);
461    }
462    return(0);
463 }
464 #endif
465 /* vpp -nOS2 -dUNIX -nBSD -nVANILLA_BSD -nVMS -nMEMLOCK -nWINDOWS -nFAR_ALLOC -f/usr/users/master/config/nonwin libfcns.c */