GNU bug report logs - #2947
23.0.91; font-lock-mode will hang emacs on this file (both on Windows/Linux)

Previous Next

Packages: cc-mode, emacs;

Reported by: Bao Haojun <haojun.bao <at> borqs.com>

Date: Fri, 10 Apr 2009 05:35:03 UTC

Severity: normal

Fixed in version 23.3

Done: Glenn Morris <rgm <at> gnu.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 2947 in the body.
You can then email your comments to 2947 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-submit-list <at> lists.donarmstrong.com, Emacs Bugs <bug-gnu-emacs <at> gnu.org>:
bug#2947; Package emacs. (Fri, 10 Apr 2009 05:35:03 GMT) Full text and rfc822 format available.

Acknowledgement sent to Bao Haojun <haojun.bao <at> borqs.com>:
New bug report received and forwarded. Copy sent to Emacs Bugs <bug-gnu-emacs <at> gnu.org>. (Fri, 10 Apr 2009 05:35:04 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> emacsbugs.donarmstrong.com (full text, mbox):

From: Bao Haojun <haojun.bao <at> borqs.com>
To: emacs-pretest-bug <at> gnu.org
Subject: 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
[Message part 1 (text/plain, inline)]
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
[Message part 2 (text/plain, inline)]
#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 <at> 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;
}

Information forwarded to bug-submit-list <at> lists.donarmstrong.com, Emacs Bugs <bug-gnu-emacs <at> gnu.org>:
bug#2947; Package emacs. (Fri, 10 Apr 2009 17:55:05 GMT) Full text and rfc822 format available.

Acknowledgement sent to Stefan Monnier <monnier <at> iro.umontreal.ca>:
Extra info received and forwarded to list. Copy sent to Emacs Bugs <bug-gnu-emacs <at> gnu.org>. (Fri, 10 Apr 2009 17:55:05 GMT) Full text and rfc822 format available.

Message #10 received at 2947 <at> emacsbugs.donarmstrong.com (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Bao Haojun <haojun.bao <at> borqs.com>
Cc: 2947 <at> debbugs.gnu.org, Alan Mackenzie <acm <at> muc.de>
Subject: Re: bug#2947: 23.0.91; font-lock-mode will hang emacs on this file (both on Windows/Linux)
Date: Fri, 10 Apr 2009 13:50:19 -0400
reassign 2947 emacs,cc-mode
thanks

> 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.
  ^^^^^
[ Emacs does not run on a bare Linux kernel.  Please call the system
  GNU/Linux. ]

IIUC the file is opened in c++-mode, right?  If so, it looks like
a pathological regexp (or something similar) in cc-mode.  Alan, can you
take a look at it?


        Stefan


> 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 <at> 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;
> }




bug reassigned from package `emacs' to `emacs,cc-mode'. Request was from Stefan Monnier <monnier <at> iro.umontreal.ca> to control <at> emacsbugs.donarmstrong.com. (Fri, 10 Apr 2009 17:55:07 GMT) Full text and rfc822 format available.

Reply sent to Glenn Morris <rgm <at> gnu.org>:
You have taken responsibility. (Mon, 03 Oct 2011 20:20:02 GMT) Full text and rfc822 format available.

Notification sent to Bao Haojun <haojun.bao <at> borqs.com>:
bug acknowledged by developer. (Mon, 03 Oct 2011 20:20:02 GMT) Full text and rfc822 format available.

Message #17 received at 2947-done <at> debbugs.gnu.org (full text, mbox):

From: Glenn Morris <rgm <at> gnu.org>
To: 2947-done <at> debbugs.gnu.org
Subject: Re: bug#2947: 23.0.91;
	font-lock-mode will hang emacs on this file (both on Windows/Linux)
Date: Mon, 03 Oct 2011 16:18:27 -0400
Version: 23.3

I can reproduce the problem, by opening the file in c++-mode and then
doing `M-x isearch-forward get m'. (I think the original report meant
line 171 rather than line 117).

However, it seems to be fixed in Emacs 23.3 and up.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Tue, 01 Nov 2011 11:24:02 GMT) Full text and rfc822 format available.

This bug report was last modified 13 years and 295 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.