libfcns.c

来自「db.* (pronounced dee-be star) is an adva」· C语言 代码 · 共 640 行 · 第 1/2 页

C
640
字号
/*************************************************************************** *                                                                         * * db.*                                                                    * * open source database kernel                                             * *                                                                         * * Copyright (c) 2000 Centura Software Corporation. All rights reserved.   * *                                                                         * * Use of this software, whether in source code format, or in executable,  * * binary object code form, is governed by the CENTURA OPEN SOURCE LICENSE * * which is fully described in the LICENSE.TXT file, included within this  * * distribution of source code files.                                      *  *                                                                         * **************************************************************************/#include "db.star.h"/* Internal function prototypes */static int INTERNAL_FCN rec_okay(int, int *, RECORD_ENTRY **, DB_TASK *);/* ======================================================================    Check for valid (external) set number and return (internal) set number    and task->set_table pointer.*/int INTERNAL_FCN nset_check(register int nset, int *set, SET_ENTRY **set_ptr,                                     DB_TASK *task){    nset -= SETMARK;    if (nset < 0 || nset >= TABLE_SIZE(Size_st))        return (dberr(S_INVSET));    *set_ptr = &task->set_table[*set = NUM2INT(nset, st_offset)];    return (task->db_status);}/* ======================================================================    Check for valid (external) field number and return (internal) record    and field numbers and pointers.*/int INTERNAL_FCN  nfld_check(    register long  nfld,    int           *rec,    int           *fld,    RECORD_ENTRY **rec_ptr,    FIELD_ENTRY  **fld_ptr,    DB_TASK       *task){    int   trec;    int   tfld;    if (!rec_okay(trec = (int) (nfld / FLDMARK), rec, rec_ptr, task) ||        (tfld = (int) (nfld - trec * FLDMARK)) < 0 ||        tfld >= TABLE_SIZE(Size_fd) || (*rec_ptr)->rt_fdtot <= 0)        return (dberr(S_INVFLD));    *fld_ptr = &task->field_table[*fld = tfld + (*rec_ptr)->rt_fields];    return (task->db_status);}/* ======================================================================    Check for valid (external) record number and return (internal) record    number and pointer.*/int INTERNAL_FCN nrec_check(int nrec, int *rec, RECORD_ENTRY **rec_ptr,                            DB_TASK *task){    if (rec_okay(nrec - RECMARK, rec, rec_ptr, task))        return (task->db_status);    return (dberr(S_INVREC));}/* ======================================================================    Internal record number check*/static int INTERNAL_FCN rec_okay(register int nrec, int *rec,                                 RECORD_ENTRY **rec_ptr, DB_TASK *task){    if (nrec < 0 || nrec >= TABLE_SIZE(Size_rt))        return FALSE;    *rec_ptr = &task->record_table[*rec = NUM2INT(nrec, rt_offset)];    return TRUE;}/* ======================================================================    Compare values of two unsigned character arrays*/static int INTERNAL_FCN uchar_cmp(unsigned char *uc1, unsigned char *uc2,                                  int len, int string){    int result = 0;    while (!result && len--)    {        if (string && (*uc1 == 0 || *uc2 == 0))            return (int)*uc1 - (int)*uc2;        result = (int)*uc1++ - (int)*uc2++;    }    return result;}/* ======================================================================    Compare values of two unsigned long values*/static int INTERNAL_FCN ulong_cmp(unsigned long ul1, unsigned long ul2){    if (ul1 < ul2)        return -1;    if (ul1 > ul2)        return 1;    return 0;}/* ======================================================================    Compare values of two db.* data fields*/int EXTERNAL_FCN fldcmp(    FIELD_ENTRY  *fld_ptr,    const char   *f1,    const char   *f2,    DB_TASK      *task){    /*        returns < 0 if f1 < f2,                = 0 if f1 == f2,                > 0 if f1 > f2    */    int            kt_lc;    int            elt;    int            result;    int            len;    int            cur_len;    int            sub_len;    int            entries;    int            ufld;    short          key_num;    unsigned int   ui1, ui2;    unsigned long  ul1, ul2;    unsigned short us1, us2;    int            i1, i2;    long           l1, l2;    short          s1, s2;    float          F1, F2;    double         d1, d2;    FIELD_ENTRY   *fld_last;    FIELD_ENTRY   *sfld_ptr;    KEY_ENTRY     *key_ptr;    short         *dptr;    unsigned char *uc1;    unsigned char *uc2;    len = fld_ptr->fd_len;    result = 0;    /* compute number of array elements */    entries = 1;    for (elt = 0, dptr = fld_ptr->fd_dim; elt < MAXDIMS && *dptr; ++elt, ++dptr)        entries *= *dptr;    ufld = fld_ptr->fd_flags & UNSIGNEDFLD;    switch (fld_ptr->fd_type)    {        case CHARACTER:            uc1 = (unsigned char *) f1;            uc2 = (unsigned char *) f2;            if (fld_ptr->fd_dim[1])            {                /* multiply-dimentioned array */                if (ufld)                    return uchar_cmp(uc1, uc2, entries, 0);                                return memcmp(f1, f2, entries);            }            if (task->ctbl_activ)                return ctblcmp(uc1, uc2, len, task);            /* unsigned char string or single unsigned char */            if (ufld)                return uchar_cmp(uc1, uc2, entries, 1);            /* single-dimensioned array -- string */            if (fld_ptr->fd_dim[0])            {                if (task->dboptions & MBSSORT)                {                    if (task->dboptions & IGNORECASE)                        return vmbsnicmp(f1, f2, len);                    return vmbsncmp(f1, f2, len);                }                else                {                    if (task->dboptions & IGNORECASE)                        return strnicmp(f1, f2, len);                    return strncmp(f1, f2, len);                }            }            /* single char */            return (int) *f1 - (int) *f2;        case REGINT:            for (elt = 0; !result && elt < entries; ++elt)            {                if (ufld)                {                    memcpy(&ui1, f1 + elt * sizeof(int), sizeof(int));                    memcpy(&ui2, f2 + elt * sizeof(int), sizeof(int));                    result = ulong_cmp((unsigned long) ui1, (unsigned long) ui2);                }                else                {                    memcpy(&i1, f1 + elt * sizeof(int), sizeof(int));                    memcpy(&i2, f2 + elt * sizeof(int), sizeof(int));                    if (i1 < i2)                        result = -1;                    else if (i1 > i2)                        result = 1;                }            }            break;        case LONGINT:            for (elt = 0; !result && elt < entries; ++elt)            {                if (ufld)                {                    memcpy(&ul1, f1 + (elt * sizeof(long)), sizeof(long));                    memcpy(&ul2, f2 + (elt * sizeof(long)), sizeof(long));                    result = ulong_cmp(ul1, ul2);                }                else                {                    memcpy(&l1, f1 + (elt * sizeof(long)), sizeof(long));                    memcpy(&l2, f2 + (elt * sizeof(long)), sizeof(long));                    if (l1 < l2)                        result = -1;                    else if (l1 > l2)                        result = 1;                }            }            break;        case WIDECHAR:            ufld = 1;            /*                If it's not a one-dimensional array, just drop through                and treat it like an array of unsigned shorts (or a single                unsigned short value.            */            if (fld_ptr->fd_dim[0] > 0 && fld_ptr->fd_dim[1] == 0)            {                if (task->dboptions & IGNORECASE)                    return vwcsnicoll((const wchar_t *)f1, (const wchar_t *)f2, len / sizeof(wchar_t));                return vwcsncoll((const wchar_t *)f1, (const wchar_t *)f2, len / sizeof(wchar_t));            }        case SHORTINT:            for (elt = 0; !result && elt < entries; ++elt)            {                if (ufld)                {                    memcpy(&us1, f1 + (elt * sizeof(short)), sizeof(short));                    memcpy(&us2, f2 + (elt * sizeof(short)), sizeof(short));                    result = ulong_cmp((unsigned long)us1, (unsigned long) us2);                }                else                {                    memcpy(&s1, f1 + (elt * sizeof(short)), sizeof(short));                    memcpy(&s2, f2 + (elt * sizeof(short)), sizeof(short));                    if (s1 < s2)                        result = -1;                    else if (s1 > s2)                        result = 1;                }            }            break;        case FLOAT:            for (elt = 0; elt < entries; ++elt)            {                memcpy(&F1, f1 + (elt * sizeof(float)), sizeof(float));                memcpy(&F2, f2 + (elt * sizeof(float)), sizeof(float));                if (F1 < F2) {                    result = -1;                    break;                }                else if (F1 > F2)                {                    result = 1;                    break;                }            }            break;        case DOUBLE:            for (elt = 0; elt < entries; ++elt)            {                memcpy(&d1, f1 + (elt * sizeof(double)), sizeof(double));

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?