dbe_edx.c

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

C
809
字号
/*************************************************************************** *                                                                         * * db.*                                                                    * * open source database, dbedit 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.                                      *  *                                                                         * **************************************************************************//*-----------------------------------------------------------------------    dbe_edx.c - DBEDIT, edit hex command    This file contains all functions for the edit hex command.    Contents of the current file are read as needed into pages of    the cache. All changes made during edit hex mode form one    transaction, which is ended when the user ends hex edit mode,    or aborted and restarted if the user issues the cancel command.    The normal command line parser is not used in hex mode, because    commands & arguments are not necessarily separated by spaces.-----------------------------------------------------------------------*/#include "db.star.h"#include "dbe_type.h"#include "dbe_str.h"#include "dbe_err.h"#include "dbe_ext.h"/* ********************** EXTERNAL FUNCTIONS ************************* *//* ********************** LOCAL VARIABLES **************************** */static DBE_PAGE curr_page;static F_ADDR curr_pos;static int dbe_xtrans;/* Values for dbe_xtrans - a transaction is started on entry into   hex edit mode, and if changes are made to any cache pages during   hex editing then the transaction is ended with d_trend when the   user quits hex edit mode. If no pages are modified then the   transaction is aborted with d_trabort.*/#define DBE_XNOTRANS  0#define DBE_XACTIVE   1#define DBE_XMODIFIED 2int edit_hex(DB_TASK *task){    DB_TCHAR line[LINELEN], buffer[16], *p, *errstr;    char     cstring[LINELEN];    int      error, exit_code, kwd, len;    long     ln;    exit_code = 0;    dbe_xtrans = DBE_XNOTRANS;    dbe_select(1);    edx_start(task);    /* Loop until end command is typed in */    while (exit_code == 0)    {        errstr = NULL;        vstprintf(line,            decimal ? DB_TEXT("%06ld:") : DB_TEXT("%05lx:"), curr_pos);        vtstrcat(line, dbe_getstr(M_HEX));        if ((error = dbe_getline(line, line, sizeof(line) / sizeof(DB_TCHAR))) >= 0)        {            p = getxcomm(line, buffer, sizeof(buffer) / sizeof(DB_TCHAR));            if (p == line)                continue;            if ((kwd = getkwd(buffer, 1)) >= 0)            {                switch (kwd)                {                    case X_CHARF:           /* Move N characters forward */                    case X_CHARB:           /* Move N characters backwards */                    case X_LINEF:           /* Move N lines forward */                    case X_LINEB:           /* Move N lines backwards */                    case X_PRINT:           /* Print N lines */                        if (!(*p))                        {                            ln = 1;                        }                        else if ((ln = getnum(p)) <= 0)                        {                            error = BAD_NUM;                            errstr = p;                            break;                        }                        if (kwd == X_LINEF || kwd == X_LINEB)                            ln *= HEX_BYTES;                        if (kwd == X_CHARB || kwd == X_LINEB)                            ln = -ln;                        error = (kwd == X_PRINT) ?                            edx_print(ln, task) : edx_goto(ln, 1, task);                        break;                    case X_GOTO:            /* Jump to position N in file */                        if (!(*p))                        {                            error = UNX_END;                        }                        else if ((ln = getnum(p)) < 0)                        {                            error = BAD_NUM;                            errstr = p;                        }                        else                        {                            error = edx_goto(ln, 0, task);                        }                        break;                    case X_SRCHF:           /* Search forwards for string */                    case X_SRCHB:           /* Search backwards for string */                    case X_WRITE:           /* Write string */                        if (!(*p))                        {                            error = UNX_END;                        }                        else if (gettext(p, cstring, sizeof(cstring), &len) == p)                        {                            error = BAD_STR;                            errstr = p;                        }                        else                        {                            error = (kwd == X_WRITE) ?                                edx_write(cstring, len, task) :                                edx_search(cstring, len, kwd == X_SRCHF ? 1 : -1, task);                        }                        break;                    case X_CANCEL:          /* Cancel edits */                        edx_start(task);                        break;                    case X_END:             /* Go back to dbedit mode */                        error = edx_end(task);                        exit_code = 1;                        break;                    case X_QMARK:           /* Help */                    case X_HELP:                        help(1, task);                        break;                }            }            else            {                error = BAD_COM;            }        }        if (error)            dbe_err(error, errstr);    }    dbe_select(0);    return(0);}/* Get command from command line - tokens not necessarily separated by spaces*/DB_TCHAR *getxcomm(DB_TCHAR *tstring, DB_TCHAR *token, int maxlen){    register int   i;    DB_TCHAR      *p, *q;    p = tstring;    q = token;    i = 0;    while (*p && *p <= DB_TEXT(' '))        p++;    if (vistalpha(*p))    {        while (vistalpha(*p) && i < maxlen - 1)        {            *q++ = *p++;            i++;        }    }    else    {        while (*p && *p > DB_TEXT(' ') && !vistalpha(*p) && !vistdigit(*p)            && *p != DB_TEXT('"') && i < maxlen - 1)        {            *q++ = *p++;            i++;        }    }    *q = 0;    return (p);}/* Get string from command line - may be ascii string in quotes, Unicode   widechar string in quotes preceded by 'L', or series of hex bytes   separated by spaces. Returns length in bytes, even if string is widechar   string.*/DB_TCHAR *gettext(DB_TCHAR *in, char *out, int size, int *len){    int       i, hexval;    DB_TCHAR *start, *p;    int       wide = 0;    wchar_t  *wout;    wchar_t   wstr[2];    char      cstr[2];    while (*in && *in <= DB_TEXT(' '))        in++;    start = in;    if (*in == DB_TEXT('L'))    {        wide = 1;        in++;    }    if (*in == DB_TEXT('"'))    {                                   /* Ascii string */        in++;        for (i = 0; (*in != DB_TEXT('"')) && (i < size - 1); in++)        {            if (!(*in))                return (start);            if (*in == DB_TEXT('\\'))            {                if (wide)                {                    /* wchar_t result required in output string */                    wout = (wchar_t *) out;                    switch (*(++in))                    {                        case DB_TEXT('n'): *wout = L'\n'; break;                        case DB_TEXT('r'): *wout = L'\r'; break;                        case DB_TEXT('t'): *wout = L'\t'; break;                        case DB_TEXT('b'): *wout = L'\b'; break;                        case DB_TEXT('0'):                            if ((in[1] < DB_TEXT('0')) || (in[1] > DB_TEXT('7'))                             || (in[2] < DB_TEXT('0')) || (in[2] > DB_TEXT('7')))                            {                                *wout = 0;                                break;                            }                        default:        /* Octal number */                            if ( (in[0] >= DB_TEXT('0')) && (in[0] <= DB_TEXT('3'))                              && (in[1] >= DB_TEXT('0')) && (in[1] <= DB_TEXT('7'))                              && (in[2] >= DB_TEXT('0')) && (in[2] <= DB_TEXT('7')) )                            {                                *wout = (wchar_t) (((in[0] - DB_TEXT('0')) << 6)                                                      & ((in[1] - DB_TEXT('0')) << 3)                                                      & (in[2] - DB_TEXT('0')));                                in += 2;                            }                            else                            {#if defined(UNICODE)                                *wout = *in;#else                                cstr[0] = *in;                                cstr[1] = '\0';                                atow(cstr, wstr, sizeof(wstr)/sizeof(wchar_t));                                *wout = wstr[0];#endif                            }                            break;                    }                }                else                {                    switch (*(++in))                    {                        case DB_TEXT('n'): *out = '\n'; break;                        case DB_TEXT('r'): *out = '\r'; break;                        case DB_TEXT('t'): *out = '\t'; break;                        case DB_TEXT('b'): *out = '\b'; break;                        case DB_TEXT('0'):                            if ((in[1] < DB_TEXT('0')) || (in[1] > DB_TEXT('7'))                             || (in[2] < DB_TEXT('0')) || (in[2] > DB_TEXT('7')))                            {                                *out = 0;                                break;                            }                        default:        /* Octal number */                            if ( (in[0] >= DB_TEXT('0')) && (in[0] <= DB_TEXT('3'))                              && (in[1] >= DB_TEXT('0')) && (in[1] <= DB_TEXT('7'))                              && (in[2] >= DB_TEXT('0')) && (in[2] <= DB_TEXT('7')) )                            {                                *out = (char) (((in[0] - DB_TEXT('0')) << 6)                                             & ((in[1] - DB_TEXT('0')) << 3)                                             & (in[2] - DB_TEXT('0')));                                in += 2;                            }                            else                            {#if defined(UNICODE)                                wstr[0] = *in;                                wstr[1] = 0;                                wtoa(wstr, cstr, sizeof(cstr));                                *out = cstr[0];#else                                *out = *in;#endif                            }                            break;                    }                }            }            else if (wide)            {                wout = (wchar_t *) out;#if defined(UNICODE)                *wout = *in;            }            else            {                wstr[0] = *in;                wstr[1] = 0;                wtoa(wstr, cstr, sizeof(cstr));                *out = cstr[0];#else                cstr[0] = *in;                cstr[1] = '\0';                atow(cstr, wstr, sizeof(wstr) / sizeof(wchar_t));                *wout = wstr[0];            }            else            {                *out = *in;#endif            }            if (wide)            {                out += sizeof(wchar_t);                i += sizeof(wchar_t);            }            else            {                out++;                i++;            }        }        in++;    }    else    {        for (i = 0, p = in; i < size - 1; i++)        {                                /* Hex string */            while ((*p) && (*p == DB_TEXT(' ')))                p++;            if (! (*p))                break;            if ((*p >= DB_TEXT('0')) && (*p <= DB_TEXT('9')))                hexval = *p - DB_TEXT('0');            else if ((*p >= DB_TEXT('a')) && (*p <= DB_TEXT('f')))                hexval = *p - DB_TEXT('a') + 10;            else if ((*p >= DB_TEXT('A')) && (*p <= DB_TEXT('F')))                hexval = *p - DB_TEXT('A') + 10;            else                break;            hexval <<= 4;            p++;            if (! (*p))                break;            if ((*p >= DB_TEXT('0')) && (*p <= DB_TEXT('9')))                hexval += *p - DB_TEXT('0');            else if ((*p >= DB_TEXT('a')) && (*p <= DB_TEXT('f')))                hexval += *p - DB_TEXT('a') + 10;            else if ((*p >= DB_TEXT('A')) && (*p <= DB_TEXT('F')))                hexval += *p - DB_TEXT('A') + 10;            else                break;            *out++ = (char) (hexval & 0xFF);            in = ++p;        }    }    *out = 0;    *len = i;    return (i >= size - 1 ? start : in);}/* Start hex edit - set current position to current record or, if none,   start of current file*/int edx_start(DB_TASK *task){    if (dbe_xtrans != DBE_XNOTRANS)    {        d_trabort(task);        dbe_xtrans = DBE_XNOTRANS;    }    if (d_trbegin(DB_TEXT("edithex"), task) != S_OKAY)

⌨️ 快捷键说明

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