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 + -
显示快捷键?