bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#2947: 23.0.91; font-lock-mode will hang emacs on this file (both on


From: Bao Haojun
Subject: bug#2947: 23.0.91; font-lock-mode will hang emacs on this file (both on Windows/Linux)
Date: Fri, 10 Apr 2009 13:27:51 +0800
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.91 (windows-nt)

The file is attached, the offending character is the last `"' character on line 
117:

        {"get micco", MICCO_TEST, "B<B>B>", "0x1", "},

If I run M-x font-lock-mode, emacs will hang. I have also tested on Linux emacs.


In GNU Emacs 23.0.91.1 (i386-mingw-nt5.1.2600)
 of 2009-02-27 on SOFT-MJASON
Windowing system distributor `Microsoft Corp.', version 5.1.2600
configured using `configure --with-gcc (3.4)'

Important settings:
  value of $LC_ALL: nil
  value of $LC_COLLATE: nil
  value of $LC_CTYPE: nil
  value of $LC_MESSAGES: nil
  value of $LC_MONETARY: nil
  value of $LC_NUMERIC: nil
  value of $LC_TIME: nil
  value of $LANG: CHS
  value of $XMODIFIERS: nil
  locale-coding-system: cp936
  default-enable-multibyte-characters: t

Major mode: C++/l

Minor modes in effect:
  auto-image-file-mode: t
  shell-dirtrack-mode: t
  mouse-wheel-mode: t
  file-name-shadow-mode: t
  blink-cursor-mode: t
  global-auto-composition-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  line-number-mode: t
  transient-mark-mode: t
  abbrev-mode: t

Recent input:
<help-echo> C-x C-f s r c / c l i <M-backspace> e n 
g <M-backspace> a l c <return> j s <return> <return> 
c l i <return> M-x M-p C-k f o n t <tab> l o <tab> 
m o <tab> <return> C-e C-b C-b " C-x C-s M-x C-g M-x 
g l o b <tab> f o n <tab> <return> M-x r e p o r <tab> 
<return>

Recent messages:
Loading paren...done
Loading q:/.session...done
For information about GNU Emacs and the GNU system, type C-h C-a.
Searching for `cli'....
Loading vc-svn...done
Font-Lock mode disabled
Saving file q:/src/alchemy/JSC-fork-dll/AlchemyLib/cli.cpp...
Wrote q:/src/alchemy/JSC-fork-dll/AlchemyLib/cli.cpp
Quit
Global-Font-Lock mode disabled
#include "stdafx.h"
#include "alchemy_internal.h"

#include <afxtempl.h>
#include "cli.h"
#define ENABLE_BHJDEBUG
#include "bhjdebug.h" 

typedef enum
{
    FACTORY_ID     = 0x001,
    GPIO_TEST      = 0x003,
    REGISTER_TEST = 0x004,
    ADC_TEST = 0x005,
    REBOOT_TEST = 0x006,
    CAMERA_TEST = 0x007,
    BLUETOOTH_TEST = 0x008,
    TESTINFO       = 0x009,
    ATPARSER_TEST  = 0x00a,
    VIBRATOR_TEST = 0x00b,
    POWERREASON_TEST=0x00c,
    VOLTAGE_TEST = 0x00d,  /*get real voltage by ADC */
    TEMPRATURE_TEST = 0x00e, /*get real temprature by ADC */
    CHARGETYPE_TEST =0x00f,
    GSENSOR_TEST   = 0x010,
    MICCO_TEST     = 0x011,
    LCDBACK_TEST   = 0x012,
    KEYBACK_TEST   = 0x013,
    TOUCH_POINT =0x014,
    KEY_INPUT = 0x015,
    ONLY_Key = 0x031,
    LGSENSOR_TEST  = 0x01c,
    GSENSOR_INFO   = 0x01d,
        
        /* DDR test commands */
    Ddr_TEST = 0x01f,
    /* LCD test commands */
    LCD_TEST = 0x20,
    /* T-FLASH card detect*/
    CARD_TEST =0x021,  

        /* charge status */
    CHARGESTATUS_TEST = 0x022, 
    
        /* MAT FILE Read AND write */
        MAT_TEST = 0x023 ,
        
       /*audio hardware test */
    AUDIO_TEST = 0x024,
     
    
/* ADC calibration &NVM block operation related test commands*/
    CALI_TEMP = 0x016, /*only operation on filesystem file*/
    CALI_VOLT = 0x017, /*only operation on filesystem file*/
    NVM_TEST  = 0X018,
    VOLT_TEST = 0x019, /*read /write from filesystem to NVM block*/
    TEMP_TEST = 0x01a, /*read /write from filesystem to NVM block*/
    RF_TEST   = 0x01b,  /*read /write from filesystem to NVM block*/
    TESTINFO_TEST =0x025,/*read /write from filesystem to NVM block*/
    FACTORYID_TEST=0x026,/*read /write from filesystem to NVM block*/
    MATFLAG_TEST=0x027,/*read /write from filesystem to NVM block*/
    
    /*touch panel test */
   PANEL_TEST = 0x028,
  /*empty  test */
   EMPTY_TEST = 0x029,
   
  /* bluetooth test commands */
    BT_TEST   = 0x050,
    BTNVM_TEST= 0x051,
    BT_INQUIRE= 0x052,
    BT_TESTMODE =0x053,
    BT_KILL=0x054,//kill the "/system/bin/hciattach" process after enter into 
BT Test Mode /BTINQUIRE 
   /*camera test commands */
    CAMERA_PREVIEW = 0x060,
    LAUNCH_CAMERA = 0x61,
    I2C_TEST  = 0x01e,
    
     /*CMMB test commands */
    IF101_TEST= 0x070,    
    INNO_DEVICE= 0x071, /*enter or exit CMMB test mode*/
    Signallock_TEST = 0x72,
    Sensitive_TEST = 0x73,
    IF101_SPI_TEST = 0x74,
    IF101_SET_FREQ = 0x75,
    LAUNCH_TV = 0x76,
   /* GPS test commands */ 
    GPS_TEST = 0x80,
    GPS_LOCATION=0x81,
    GPS_MESSAGE=0x82,/*only get NEMA Message*/
    GPS_LOCA_MESSAGE=0x83,/*only get Location Message*/
    GPS_CHANGE_MODE=0x84,/*Change between hot mode and code mode*/
  
    /* SPARK */
        SPARK_KEY=0x90,/*TEST KEY INPUT*/
        /* Key Monitor */
        KEY_MONITOR=0x91,
        /* Sensor Monitor */
        SENSOR_MONITOR=0x92,
        /* Set/Get LPR SMS report flag */
        SMS_FLAG =0x93,
        /* Set/Get LPR livetime period  */
    LIVETIME_PERIOD = 0x94,
    /* Set/Get EFEM feature flag  */
    EFEM_FLAG =0x95,
        DIAG_LAUNCH=0x96,       
        GET_RDNVM =0x9a,
        DIAG_EXT_INTERFACE=0x9b,
        /*to set /get element config value */
        NVM_Element=0x9c,
        /*to set /get phase  data : */
        NVM_PHASE =0x9d,
        /*Common set/get Bit config element value*/
        NVM_BITCONFIG  =0x9e, 
        /* Version */
        VERSION     = 0x039,
    
    /* bp only handler */
    BP_ONLY    = 0xFFFF
} TC_AP_FSM_EVENT_OPCODE_T;

typedef unsigned char u8;
typedef unsigned short u16;
typedef struct{
        const char *cmdName;
        int opCode;
        const char *inputSpec; // datatype: BHIOoF, how: <>*! 
        const char *fixedInput;
        const char *description;
        
} testCmd_T;


//< means from the fixedInput, 
//> means from user provided input, 
//! means arbitrary value is acceptable, so we just use 0, 
//* means fill with a string
static testCmd_T cmdMap[] = {
        {"version", VERSION, "B<", "0x12", "Read software version of the 
phone"},
        {"get factory_id", FACTORY_ID, "B<", "0x11", "Read FactoryId of the 
phone"},
        {"set factory_id", FACTORY_ID, "B<B*", "0x00", "Update FactoryId of the 
phone" },
        {"atCommand", ATPARSER_TEST, "B*", "", "Test an AT command" },
        {"get gpio", GPIO_TEST, "B<H>B!", "0x1", "Get GPIO, the u16 argument is 
the GPIO number"},

        {"set gpio", GPIO_TEST, "B<H>B>", "0x2", 
         "Set GPIO, the u16 is GPIO number, the u8 is GPIO setting\n"
         "the meaning of bit 7-0:\n"
         "    level : 1,     //0:low,1:High\n"
         "    in_out: 1,    //0:input, 1:output\n"
         "    pullup: 1,    //0:no pullup,1:pullup\n"
         "    pulldown:  1,    //0:no pulldown,1:pulldown\n"
         "    tri_state: 1,    //0:anit_tristate,1:tristate\n"
         "    reserved:  3;\n"
        },
        {"get register", REGISTER_TEST, "B<I>I!", "0x1", "Read register value, 
u32 is register number. Use with caution!"},
        {"set register", REGISTER_TEST, "B<I>I>", "0x2", "Write register, first 
u32 is register number, second is value"},
        {"get adc", ADC_TEST, "B>H!", "", "Read A/D converter value, u8 is AD 
number" },

        {"reboot poweroff", REBOOT_TEST, "B<", "0x0", "reboot to poweroff 
mode"},
        {"reboot factory", REBOOT_TEST, "B<", "0x1" "reboot to factory mode 
(minimal applications will start, so boot/test is faster)"},
        {"reboot normal", REBOOT_TEST, "B<", "0x2", "reboot, the `Normal' 
reboot"},
        {"reboot flash", REBOOT_TEST, "B<", "0x3", "reboot to flash mode"},

        //{"camera test", //???
        {"launch camera", LAUNCH_CAMERA, "", "", "lauch camera"},
        //{"bluetooth test", //???
        //{"get info", TESTINFO, "B<", "0x11"}, //???
        //{"set info", TESTINFO, "B<B*", "0x0"}, //???
        {"get gsensor", GSENSOR_TEST, "B<B>B!", "0x1", "get gravity sensor 
value, u8 is the gsensor number"},
        {"set gsensor", GSENSOR_TEST, "B<B>B>", "0x2", "set gsensor value, 
first u8 is the gsensor number, second is value"},
        {"get micco", MICCO_TEST, "B<B>B>", "0x1", "},
        {"set micco", MICCO_TEST, "B<B>B>", "0x2"},
        {"vibrator on", VIBRATOR_TEST, "B<", "0x1"},
        {"vibrator off", VIBRATOR_TEST, "B<", "0x2"},
        //{"at test" //bhj: don't know what this means
        {"get power reason", POWERREASON_TEST, "", ""},
        {"get chargetype", CHARGETYPE_TEST, "B<", "0x1"},
        {"set chargetype", CHARGETYPE_TEST, "B<B>", "0x2"},
        {"get manual voltage", VOLTAGE_TEST, "B<", "0x0"},
        {"get auto voltage", VOLTAGE_TEST, "B<", "0x4"},
        {"get manual temperature", TEMPRATURE_TEST, "B<", "0x1"},//0x0? 
        {"get auto temperature", TEMPRATURE_TEST, "B<", "0x5"},
        {"get lcdbl", LCDBACK_TEST, "B<B>", "0x1"},
        {"set lcdbl", LCDBACK_TEST, "B<B>", "0x2"},
        {"get keybl", KEYBACK_TEST, "B<B>", "0x1"},
        {"set keybl", KEYBACK_TEST, "B<B>", "0x2"},
        {"test touch", TOUCH_POINT, "", ""},
        {"test keyinput",ONLY_Key,"",""},
        {"get lprflag", SMS_FLAG, "B<", "0x1"},
        {"set lprflag", SMS_FLAG, "B<B>", "0x2"},
        {"get lprtime", LIVETIME_PERIOD, "B<", "0x1"},
        {"set lprtime", LIVETIME_PERIOD, "B<B>", "0x2"},
        {"get efemflag", EFEM_FLAG, "B<", "0x1"},
        {"set efemflag", EFEM_FLAG, "B<B>", "0x2"},
        {"get cali temperature",CALI_TEMP,"B<","0x1"},//add by Jason from here
        {"get cali voltage",CALI_VOLT,"B<","0x1"},
        {"set cali voltage",CALI_VOLT,"B<B*","0x2"},
        {"store volt",VOLT_TEST,"B<","0x1"},
        {"load volt",VOLT_TEST,"B<","0x2"},
        {"store temp",TEMP_TEST,"B<","0x1"},
        {"load temp",TEMP_TEST,"B<","0x2"},
        {"store RF",RF_TEST,"B<","0x1"},
        {"load RF",RF_TEST,"B<","0x2"},
        {"store testinfo",TESTINFO_TEST,"B<","0x1"},
        {"load testinfo",TESTINFO_TEST,"B<","0x2"},
        {"store factoryid",FACTORYID_TEST,"B<","0x1"},
        {"load factoryid",FACTORYID_TEST,"B<","0x2"},
        {"store MATflag",MATFLAG_TEST,"B<","0x1"},
        {"load MATflag",MATFLAG_TEST,"B<","0x2"},
        {"camera preview on",CAMERA_PREVIEW,"B<","0x1"},
        {"camera preview off",CAMERA_PREVIEW,"B<","0x2"},
        {"get sensor",LGSENSOR_TEST,"B<","0x1"},
        {"i2c test",I2C_TEST,"",""},
        {"if101 test",IF101_TEST,"",""},
        {"read bt",BT_TEST,"B<","0x1"},
        {"write bt",BT_TEST,"B<B*","0x2"},
        {"store btnvm",BTNVM_TEST,"B<B*","0x1"},
        {"load btnvm",BTNVM_TEST,"B<","0x2"},
        {"bt inquire",BT_INQUIRE,"",""},
        {"bt testmode",BT_TESTMODE,"",""},
        {"bt kill",BT_KILL,"",""},//ljs:not find the definition
        {"launch tv",LAUNCH_TV,"",""},
        {"ddr test",Ddr_TEST,"",""},
        {"gps test",GPS_TEST,"B>",""},
        {"lcd test",LCD_TEST,"B>",""},
        {"card detect",CARD_TEST,"B>",""},
        {"charge status",CHARGESTATUS_TEST,"B>",""},
        {"audio test",AUDIO_TEST,"B>",""},
        //data: 0x01: AUDIO_SD_PLAY
        //              0x02: AUDIO_MICRO_TEST
    //      0x03: AUDIO_EAR_TEST
        {"save rd",GET_RDNVM,"B<B>","0x1"},
        {"get diag_en",DIAG_LAUNCH,"B<","0x1"},
        {"set diag_en",DIAG_LAUNCH,"B<B>","0x2"},
        {"get diag_intf",DIAG_EXT_INTERFACE,"B<","0x1"},
        {"set diag_intf",DIAG_EXT_INTERFACE,"B<B>","0x2"},
        {"get element",NVM_Element,"I>B<","0x1"},
        {"set element",NVM_Element,"I>B<o","0x2"},
        {"get phase",NVM_PHASE,"I>B<","0x1"},
        {"set phase",NVM_PHASE,"I>B<o>","0x2"},
        {"get ap_panic_report",NVM_BITCONFIG,"I>B<","0x1"},
        {"set ap_panic_report",NVM_BITCONFIG,"I>B<B>","0x2"},
        {"opcode", -1, "o>", ""},
        {"reliable data", 0x97, "F>", ""},
        {NULL, 0, NULL, NULL},
};


static BOOL notOptionalCode(char c)
{
        return (c!='*' && c!='?');
}

static BOOL isOptionalCode(char c)
{
        return !notOptionalCode(c);
}

static BOOL isSingleOptional(char c)
{
        return c=='?';
}

static BOOL isMultiOptional(char c)
{
        return c=='*';
}

static unsigned long getLong(CString& strInput)
{
        const char *s = strInput.GetBufferSetLength(strInput.GetLength());
        char *firstInvalid = NULL;
        
        long dataH = strtol(s, &firstInvalid, 0);
        strInput.ReleaseBuffer();
        strInput.Delete(0, firstInvalid-s);
        strInput.TrimLeft();
        return (unsigned long) dataH;

}

static int getLongCheck(CString& strInput, unsigned long& outLong) 
{
        outLong = 0;
        
        strInput.TrimLeft();
        strInput.TrimRight();

        if (strInput.IsEmpty()) {
                return -1;
        }

        int len = strInput.GetLength();
        outLong = (unsigned long)getLong(strInput);
        if (len == strInput.GetLength()) {
                return -1;
        }
        return 0;
}

static int getB(CString& strInput, CU8Array& dataArr)
{
        unsigned long outLong = 0;
        if (getLongCheck(strInput, outLong) < 0) {
                return -1;
        }
        unsigned char data = (unsigned char)outLong;
        dataArr.Add(data);
        return 0;
}
//'H' stands for a short
static int getH(CString& strInput, CU8Array& dataArr)
{
        unsigned long outLong = 0;
        if (getLongCheck(strInput, outLong) < 0) {
                return -1;
        }

        unsigned short data = (unsigned short) outLong;
        //big endian or little endian?
        dataArr.Add(data&0xff);
        dataArr.Add(data>>8);
        return 0;
}

static int getI(CString& strInput, CU8Array& dataArr)
{

        unsigned long outLong = 0;
        if (getLongCheck(strInput, outLong) < 0) {
                return -1;
        }

        unsigned int data = (unsigned int)outLong;
        dataArr.Add(data&0xff);                 //????int??????????
        dataArr.Add((data>>8) & 0xff);  //????int????????????   
        dataArr.Add((data>>16) & 0xff); //????int????????????
        dataArr.Add((data>>24) &0xff);  //????int????????????

        return 0;
}

static int getF(CString& strInput, CU8Array& dataArr)
{
        strInput.TrimLeft();
        strInput.TrimRight();

        FILE* fp = fopen(strInput, "rb");
        if (fp == NULL) {
                urgTrace("Error: %s open failed", (const char *)strInput);
                return -1;
        }

        fseek(fp, 0, SEEK_END);
        

        DWORD dwLength = ftell(fp);
        rewind(fp);
        char *buff = (char *)calloc(dwLength, 1);
        DWORD numRead = 0;
        
        for (;;) {
                numRead += fread(buff+numRead, 1, dwLength, fp);
                if (numRead == dwLength)
                        break;
        }
        
        ASSERT(numRead == dwLength);
        for (DWORD i=0; i<dwLength; i++) {
                dataArr.Add(buff[i]);
        }
        free(buff);
        fclose(fp);
        return 0;
}

#define AppendFormat(s, fmt) do {               \
                CString tmp_asfd;               \
                tmp_asfd.Format fmt;            \
                s+=tmp_asfd;                    \
        } while (0)

static CString getFormat(const char *dC /* i.e., inputSpec, such as "BB*" */)
{
        CString format;
        for (int i=0; dC[i]; i++) {
                if (dC[i]=='B' && notOptionalCode(dC[i+1])) {
                                continue;
                } else if (dC[i]=='B' && isMultiOptional(dC[i+1])) {
                        i++;
                        format += "[string] ";
                } else if (dC[i]=='H' && isSingleOptional(dC[i+1])) {
                        i++;
                        format += "[uint16] ";
                } else if (dC[i]=='I' && isSingleOptional(dC[i+1])) {
                        i++;
                        format += "[uint32] ";
                } else if (dC[i]=='B' && isSingleOptional(dC[i+1])) {
                        i++;
                        format += "[uint8] ";
                } else if (dC[i]=='O' && notOptionalCode(dC[i+1])) {
                        format += "[uint32 (as opcode)] [uint8]... ";
                } else if (dC[i]=='F' && notOptionalCode(dC[i+1])) {
                        format += "[filename] ";
                } else if (dC[i]=='o' && notOptionalCode(dC[i+1])) {
                        format += "[uint8]... ";
                }
        }

        if (format.IsEmpty()) {
                format += "no args";
        }
        format += "\r\n";
        return format;
}

static void commands()
{
        CString 
helpStr("\r\nCommands:\r\n--------------------------------\r\n\r\n");
        for (int i=0; cmdMap[i].cmdName!=NULL; i++) {
                CString cmdName(cmdMap[i].cmdName);
                AppendFormat(helpStr, ("%-25s : "
                                       "opcode 0x%04x : "
                                       "%s", cmdName, 
                                       (unsigned short)cmdMap[i].opCode, 
                                       getFormat(cmdMap[i].inputSpec)));
        }
        urgTrace("%s", helpStr);
        
}

static void help()
{
        CString helpStr("\r\nHelp:\r\n--------------------------------\r\n\r\n"
                        "You can type the following to get more 
infomation:,\r\n"
                        "\r\n"
                        "        help: dislay this help\r\n"
                        "        todo: display to-do in this tool\r\n"
                        "        bugs: display bugs/defects known\r\n"
                        "    commands: display a list of available commands\r\n"
                        "\r\n"
                        "When you type `commands`, the commands are displayed 
as `Command : Args`,\r\n"
                        "Leading and trailing spaces in a command is 
ignored,\r\n"
                        "  for e.g., `set keybl 255` is equal to `   set keybl  
  255   `\r\n"
                        "but, space in a command is not,\r\n"
                        "  for e.g., `get keybl` is ok, but `get  keybl` is not 
a valid command\r\n"
                        "for those command that want one or more u8/u16/u32 
argument, \r\n"
                        "if none or less that required argument is supplied, a 
default 0 is used\r\n"
                        "  for e.g., `set register 0x33 0x44` takes 2 args\r\n"
                        "  0x33 is register number, 0x44 is the value, \r\n"
                        "  i.e., register 0x33 will be set to 68 (decimal value 
of 0x44) \r\n"
                        "  But, if you run `set register`, then register 0 will 
be set to 0\r\n"
                        "And, you can use 0xf/017/15 to mean the same INT, 
15.");
                        

        urgTrace("%s", helpStr);
}

static void todo()
{
        CString todoStr("\r\nTodo:\r\n--------------------------------\r\n\r\n"
                        "    1. make the interface more user-friendly\r\n"
                        "       for e.g., get gpio should show if the i/o is 
pu/pd, etc.\r\n"
                        "    2. implement a better help system\r\n"
                        "    3. provide a means to clear or save the log to a 
file\r\n"
                        "    4. provide a means to save the commands executed 
to a file\r\n"
                        "    5. implement execution of commands from the saved 
commands file\r\n"
                        "    6. fix bugs");
        urgTrace("%s", todoStr);
}

static void bugs()
{
        CString bugsStr("\r\nBugs:\r\n--------------------------------\r\n\r\n"
                        "    1. connection is broken after you disconnect the 
usb cable\r\n"
                        "       and must restart the application to 
reconnect\r\n"
                        "    2. you must connect the usb cable before you start 
the application\r\n"
                        "    3. many other bugs, some are even undiscovered 
yet\r\n"
                        "       Please help report bugs/suggestions to 
haojun.bao@borqs.com");
        urgTrace("%s", bugsStr);
}


static void printResult(CU8Array& result)
{
        CString recvTrace("\"");
        if (result.GetSize()==0) {
                return;
        }

        for (int k=0; k<result.GetSize(); k++) {
                if (isprint(result[k])) {
                        recvTrace += result[k];
                } else {
                        CString tmp;
                        tmp.Format("\\x%02x", result[k]);
                        recvTrace += tmp;
                }
        }
        recvTrace+='"';

        urgTrace("%s", recvTrace);

        recvTrace = "   in hex: ";
        for (k=0; k<result.GetSize(); k++) {
                CString tmp;
                tmp.Format("0x%02x ", result[k]);
                recvTrace += tmp;
        }
        dbgTrace("%s", recvTrace);
                                                                   
        return;
}

static BOOL isFromUser(char where)
{
        return where == '>';
}

static BOOL isFromFixed(char where)
{
        return where == '<';
}

static BOOL isArbitrary(char where)
{
        return where == '!';
}

static BOOL isMultiple(char where)
{
        return where == '*';
}

static int getArg(CU8Array& dataArr, CString& strUserInput, CString& 
strFixedInput, char dataType, char where)
{
        if (dataType == 'B') {
                if (isFromUser(where)) {
                        return getB(strUserInput, dataArr);
                } else if (isFromFixed(where)) {
                        return getB(strFixedInput, dataArr);
                } else if (isArbitrary(where)) {
                        return getB(CString("0"), dataArr);
                } else if (isMultiple(where)) { //the rest of the user-input is 
consumed

                        for (int k=0; k<strUserInput.GetLength(); k++) {
                                dataArr.Add(strUserInput[k]);
                        }
                        strUserInput = ""; //empty user-input
                        return 0;
                }
        } else if (dataType == 'H') {
                if (isFromUser(where)) {
                        return getH(strUserInput, dataArr);
                } else if (isFromFixed(where)) {
                        return getH(strFixedInput, dataArr);
                } else if (isArbitrary(where)) {
                        return getH(CString("0"), dataArr);
                } else {
                        urgTrace("Error: alchemy bug detected, code is %c %c", 
dataType, where);
                        return -1;
                }
        } else if (dataType == 'I') {
                if (isFromUser(where)) {
                        return getI(strUserInput, dataArr);
                } else if (isFromFixed(where)) {
                        return getI(strFixedInput, dataArr);
                } else if (isArbitrary(where)) {
                        return getI(CString("0"), dataArr);
                } else {
                        urgTrace("Error: alchemy bug detected, code is %c %c", 
dataType, where);
                        return -1;
                }
        } else if (dataType == 'o') {
                strUserInput.TrimLeft();
                CString savedCommand = strUserInput;
                                        
                for (int k=0;;k++) { //infinite loop, k is only for debugging
                        if (strUserInput.IsEmpty()) {
                                break;
                        }
                        getB(strUserInput, dataArr);
                        if (strUserInput == savedCommand) {
                                urgTrace("invalid arguments, `%s'", 
savedCommand);
                                return -1;
                        }
                        strUserInput.TrimLeft();
                        savedCommand = strUserInput;
                }
                
                return 0;
        } else if (dataType == 'F') {
                if (!isFromUser(where)) {
                        urgTrace("Error: alchemy bug detected, code is %c %c", 
dataType, where);
                }                               
                return getF(strUserInput, dataArr);
        } else {
                urgTrace("Error: alchemy bug detected, code is %c %c", 
dataType, where);
                return -1;
        }

        return 0;
}

int cliCarryOut(const char *sCommand)
{
        return cliCarryOut(CString(sCommand));
}

int cliCarryOut(const CString& sCommand)
{
        CU8Array result;
        return cliCarryOut(sCommand, result);
}

//resolve the command send by IDC_EXEC_COMMAND
int cliCarryOut(const CString& sCommandConst, CU8Array& result)
{
        if (alchemyInited == FALSE) {
                urgTrace("Must call InitAlchemyLib first!\n");
                return -1;
        }

        //we need to change the input string, so make a copy to remove the 
`const'
        CString sCommand = sCommandConst;
        sCommand.TrimLeft();
        sCommand.TrimRight();
        
        for (int i=0; cmdMap[i].cmdName; i++) {
                if (sCommand.Find(cmdMap[i].cmdName) == 0) {
                        const char *inputSpec = cmdMap[i].inputSpec;
                        const char *fixedInput = cmdMap[i].fixedInput;
                        int opcode = cmdMap[i].opCode;  // this will change if 
cmd is "opcode"
                        
                        //so that only args to the cmd is in sCommand
                        sCommand.Delete(0, strlen(cmdMap[i].cmdName));
                        sCommand.TrimLeft();
                        
                        CString strUserInput = sCommand;
                        CString strFixedInput = fixedInput? fixedInput : "";
                        
                        CU8Array dataArr; //empty at first

                        //handle opcode first:
                        if (opcode < 0) {
                                opcode = getLong(strUserInput);
                        }
                        
                        for (int j=0; inputSpec[j]; j=j+2) {
                                int n = getArg(dataArr, strUserInput, 
strFixedInput, inputSpec[j], inputSpec[j+1]);

                                if (n < 0) {
                                        urgTrace("Error: don't know how to 
parse the input string:\n    %s", (const char*)sCommandConst);
                                }
                        } 

                        if (strUserInput.GetLength()) {
                                urgTrace("Error: argument parse failed, `%s' is 
remaining in the command string", strUserInput);
                                return -1;
                        }

                        BYTE recv[1024] = {0};
                        int nRecv = 0;

                        CString sendTrace("send: \"opCode ");
                        CString tmp;
                        tmp.Format("0x%08x,data: ", opcode);
                        sendTrace+=tmp;
                        for (int k=0; k<min(10,dataArr.GetSize()); k++) {
                                CString tmp;
                                tmp.Format("0x%02x ", dataArr[k]);
                                sendTrace+=tmp;
                        }
                        if (dataArr.GetSize()>10) {
                                sendTrace+="...";
                        }
                        dbgTrace("%s", sendTrace);

                        int ret = getConnection()->UC_Do3rdCommand(opcode,
                                                                   dataArr,
                                                                   result,
                                                                   
cmdMap[i].cmdName);
                        printResult(result);
                        if (ret < 0) {
                                infoTrace("`%s`: failed!", cmdMap[i].cmdName);
                                return -1;
                        } else {
                                infoTrace("`%s`: success!", cmdMap[i].cmdName);
                                return 0;
                        }
                }
        }
        if (sCommand.Find("help") == 0) {
                help();
        } else if (sCommand.Find("todo") == 0) {
                todo();
        } else if (sCommand.Find("bugs") == 0) {
                bugs();
        } else if (sCommand.Find("commands") == 0) {
                commands();
        } else {
                urgTrace("%s", sCommand+=": unknown command");
        } 
        return 0;
}

reply via email to

[Prev in Thread] Current Thread [Next in Thread]