fld_move.c

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

C
968
字号
/*************************************************************************** *                                                                         * * db.*                                                                    * * open source database, dbimp utility                                     * *                                                                         * * 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"#include "impdef.h"#include "impvar.h"static DB_ADDR read_dba(DB_TCHAR *);static int mv_struct(char *, int, int, DB_TCHAR *);static int mv_elem(char *, int, int, int, int *, DB_TCHAR *);static DB_TCHAR next_ch(DB_TCHAR *, int *, int *);static int asc_fld;                    /* Current ASCII field position *//**************************************************************************/int fld_move(struct fld *fptr, char *record){    register int fld, i;    DB_TCHAR *line = NULL;    int dims, size, nelem, base;    int idx, endidx;    DB_TASK *task = imp_g.dbtask;    /* for each field */    for ( ; fptr; fptr = fptr->fld_next)    {        /* see if the field is within the scope of loop stack */        for (i = 0; i < imp_g.loop_lvl; i++)        {            if (vtstrcmp(fptr->fld_file, imp_g.curloop[i]->u.sp_looptr->l_fname) == 0)            {                line = imp_g.curloop[i]->u.sp_looptr->l_line;                break;            }        }        /* field spec not within any active file */        if (i == imp_g.loop_lvl)        {            vftprintf(stderr, DB_TEXT("File %s is not open\n"), fptr->fld_file);            dbimp_abort(DB_TEXT("Execution terminated"));            return FAILURE;        }        asc_fld = fptr->fld_name;        fld = fptr->fld_ndx;        /* If this field is not a structure field */        if (task->field_table[fld].fd_type != GROUPED)        {            /* move a non-structured field */            if (mv_elem(record, fptr->fld_offset, fld, fptr->fld_dims,                    fptr->fld_dim, line) == FAILURE)                return FAILURE;            continue;        }        /* determine if there is an array of structures */        for (dims = 0; dims < MAXDIMS && task->field_table[fld].fd_dim[dims]; dims++)            ;        base = task->field_table[fld].fd_ptr -                task->record_table[task->field_table[fld].fd_rec].rt_data;        /* if this is an array of structures */        if (dims <= 0)        {            mv_struct(record, base, fld, line);            fptr = fptr->fld_next;            continue;        }        /* determine how many elements will be moved */        for (nelem = 1, i = 0; i < dims; i++)            nelem *= task->field_table[fld].fd_dim[i];        size = task->field_table[fld].fd_len / nelem;        /* if this is a partial definition, find the starting element */        vec_idx(dims, task->field_table[fld].fd_dim, fptr->fld_dim, &idx);        /* find the ending element */        if (fptr->fld_dims)        {            fptr->fld_dim[fptr->fld_dims - 1]++;            vec_idx(dims, task->field_table[fld].fd_dim, fptr->fld_dim, &endidx);            fptr->fld_dim[fptr->fld_dims - 1]--;        }        else            endidx = nelem;        if (dims > fptr->fld_dims)        {            /* now loop once for each element following */            for (i = idx; i < endidx; i++)                mv_struct(record, base + i * size, fld, line);        }        /* not partial definition */        else            mv_struct(record, base + idx * size, fld, line);    }    return OK;}/**************************************************************************//* move all elements of one structure */static int mv_struct(char *record, int offset, int ndx, DB_TCHAR *line){    int vec[MAXDIMS];    int i, diff, fld;    DB_TASK *task = imp_g.dbtask;    for (i = 0; i < MAXDIMS; i++)        vec[i] = 0;    /* for each subfield */    fld = ndx + 1;    while (task->field_table[fld].fd_flags & STRUCTFLD)    {        diff = task->field_table[fld].fd_ptr - task->field_table[ndx].fd_ptr;        if (mv_elem(record, offset + diff, fld, 0, vec, line) == FAILURE)            return FAILURE;        fld++;    }    return OK;}/**************************************************************************//* move all elements of a non-structured field */static int mv_elem(char *record, int offset, int ndx, int flddims,                   int *flddim, DB_TCHAR *line){    int i, dims, size, nelem, idx, endidx, fd_width;    DB_TASK *task = imp_g.dbtask;    /* determine if there is an array */    for (dims = 0; dims < MAXDIMS && task->field_table[ndx].fd_dim[dims]; dims++)        ;    /* if this field is an array */    if (dims <= 0)        return mv_fld(record, offset, ndx, line);    /* determine how many elements will be moved */    for (nelem = 1, i = 0; i < dims; i++)        nelem *= task->field_table[ndx].fd_dim[i];    size = task->field_table[ndx].fd_len / nelem;    /* if this is a partial definition, find the starting element */    vec_idx(dims, task->field_table[ndx].fd_dim, flddim, &idx);    /* find the ending element */    if (flddims)    {        flddim[flddims - 1]++;        vec_idx(dims, task->field_table[ndx].fd_dim, flddim, &endidx);        flddim[flddims - 1]--;    }    else        endidx = nelem;    /* character types are copied instead of converted */    if (  (task->field_table[ndx].fd_type == CHARACTER         || task->field_table[ndx].fd_type == WIDECHAR)        && dims != flddims)    {        fd_width = task->field_table[ndx].fd_dim[dims - 1];        /* if not partial definition of string */        if (flddims && dims == flddims + 1)        {            if (task->field_table[ndx].fd_type == CHARACTER)                return mv_char(record, offset + idx, fd_width, line);            return mv_wchar(record, offset + idx, fd_width, line);        }        if (fd_width > 1)        {            /* for each character string array element */            for (; idx < endidx; idx += fd_width)            {                if (task->field_table[ndx].fd_type == CHARACTER)                {                    if (mv_char(record, offset + idx, fd_width, line) == FAILURE)                        return FAILURE;                }                else                {                    if (mv_wchar(record, offset + idx, fd_width, line) == FAILURE)                        return FAILURE;                }            }            return OK;        }        /* binary copy */        fd_width = task->field_table[ndx].fd_dim[dims - 2];        for (; idx < endidx; idx += fd_width)        {            if (task->field_table[ndx].fd_type == CHARACTER)            {                if (mv_binary(record, offset + idx, fd_width, line) == FAILURE)                    return FAILURE;            }            else            {                if (mv_wbinary(record, offset + idx, fd_width, line) == FAILURE)                    return FAILURE;            }        }        return OK;    }    /* character data */    if (dims <= flddims)        return mv_fld(record, offset + idx * size, ndx, line);    /* now loop once for each element following */    for (i = idx; i < endidx; i++)    {        if (mv_fld(record, offset + i * size, ndx, line) == FAILURE)            return FAILURE;    }    return OK;}/**************************************************************************/int mv_char(char *record, int offset, int fd_width, DB_TCHAR *line){    DB_TCHAR *fld_cont;    int width;    fld_cont = find_fld(asc_fld, line, &width);    if (fld_cont == NULL)        return FAILURE;    if (fd_width <= width && fd_width > 1)    {        if (!imp_g.silent)        {            vftprintf(stderr,                DB_TEXT("**WARNING**  db.* field not wide enough for %d; truncated\n"),                asc_fld);        }        width = fd_width - 1;    }    /* copy into the record */    ttoa(fld_cont, record + offset, width);    asc_fld++;    return OK;}/**************************************************************************/int mv_wchar(char *record, int offset, int fd_width, DB_TCHAR *line){    DB_TCHAR *fld_cont;    int width;    fld_cont = find_fld(asc_fld, line, &width);    if (fld_cont == NULL)        return FAILURE;    if (fd_width <= width && fd_width > 1)    {        if (!imp_g.silent)        {            vftprintf(stderr,                DB_TEXT("**WARNING**  db.* field not wide enough for %d; truncated\n"),                asc_fld);        }        width = fd_width - 1;    }    /* copy into the record */    record += offset;    ttow(fld_cont, (wchar_t *) record, width);    asc_fld++;    return OK;}/**************************************************************************/int mv_binary(char *record, int offset, int fd_width, DB_TCHAR *line){    DB_TCHAR *fld_cont, bin[3];    int width, i;    int hex;    fld_cont = find_fld(asc_fld, line, &width);    if (fld_cont == NULL)        return FAILURE;    if (fd_width * 2 < width)    {        if (!imp_g.silent)        {            vftprintf(stderr,                DB_TEXT("**WARNING**  db.* field not wide enough for %d; truncated\n"),                asc_fld);        }        width = fd_width * 2;    }    /* copy into the record */    for (i = 0; i < width;)    {        bin[0] = fld_cont[i++];        bin[1] = fld_cont[i++];        bin[2] = '\0';        vstscanf(bin, DB_TEXT("%02x"), &hex);        record[offset + (i - 2) / 2] = (char) hex;    }    asc_fld++;    return OK;}/**************************************************************************/int mv_wbinary(char *record, int offset, int fd_width, DB_TCHAR *line){    DB_TCHAR *fld_cont, bin[5];    wchar_t *p;    int width, i, j;    int hex;    record += offset;    p = (wchar_t *) record;    fld_cont = find_fld(asc_fld, line, &width);    if (fld_cont == NULL)        return FAILURE;    if (fd_width * 4 < width)    {        if (!imp_g.silent)        {            vftprintf(stderr,                DB_TEXT("**WARNING**  db.* field not wide enough for %d; truncated\n"),                asc_fld);        }    }    /* copy into the record */    for (i = j = 0; j < fd_width; j++)    {        bin[0] = fld_cont[i++];        bin[1] = fld_cont[i++];        bin[2] = fld_cont[i++];        bin[3] = fld_cont[i++];        bin[4] = '\0';        vstscanf(bin, DB_TEXT("%04x"), &hex);        p[j] = (wchar_t) hex;    }    asc_fld++;    return OK;}/**************************************************************************/static char read_char(DB_TCHAR *fld){    int     num = 0;    int     i = 0;    int     escape = 0;#if defined(UNICODE)    wchar_t wnum[2];    char    cnum[2];#endif    if (fld[0] != DB_TEXT('\''))    {        vstscanf(fld, DB_TEXT("%d"), &num);        return (char) num;    }    while ((fld[++i] != DB_TEXT('\'')) || (escape == 1))    {        if (escape == 0)    /* No '\' yet. */        {            if (fld[i] == DB_TEXT('\\'))   /* We found a '\' character */                escape = 1;            else    /* Just a regular character */            {#if defined(UNICODE)                wnum[0] = fld[i];                wnum[1] = 0;                wtoa(wnum, cnum, sizeof(cnum));                num = cnum[0];#else                num = fld[i];#endif                escape = -1;            }        }        else if (escape == -1)        {            /* a valid character has been found, but no closing "'" */            vftprintf(stderr, DB_TEXT("**WARNING** invalid char %s\n"), fld);            return (char) num;        }        else if (fld[i] >= DB_TEXT('0') && fld[i] < DB_TEXT('8'))  /* octal */        {            do            {                if (i > 4)  /* too many digits */                {                    vftprintf(stderr,                        DB_TEXT("**WARNING** invalid octal value: %s\n"), fld);                    return (char) num;                }                num *= 8;                num += fld[i] - DB_TEXT('0');                if (fld[++i] == DB_TEXT('\''))                    escape = -1;            } while (fld[i] >= DB_TEXT('0') && fld[i] < DB_TEXT('8'));            if (fld[i] != DB_TEXT('\''))            {                vftprintf(stderr,                    DB_TEXT("**WARNING** invalid octal value: %s\n"), fld);                return (char) num;            }            i--;        }        else        {            escape = -1;            switch (fld[i])            {                case DB_TEXT('n'):   num = '\n';    break;                case DB_TEXT('r'):   num = '\r';    break;                case DB_TEXT('f'):   num = '\f';    break;                case DB_TEXT('t'):   num = '\t';    break;                case DB_TEXT('b'):   num = '\b';    break;                case DB_TEXT('v'):   num = '\v';    break;                default:#if defined(UNICODE)                    wnum[0] = fld[i];

⌨️ 快捷键说明

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