Thursday, May 22, 2008

gnu make on win32 shell

1. The version of gnu make that works on win32 is 3.80, while both 3.78 and 3.81 would not work.

2. win32 shell script. The following is a sample which uses cvs to check out foo source code


@echo off

set PRJ_DIR=%PRJ_ROOT%\foo-%PRJ_TSTAMP%
set PRJ_NAME=foo
if "%1"=="-D" goto check_out_tstamp;

echo "check out HEAD of %PRJ_NAME%"
cvs co -d %PRJ_DIR% -P %PRJ_NAME%

goto end;

: check_out_tstamp
echo "check out with time stamp"
cvs co -D %PRJ_TIME% "-d" %PRJ_DIR% -P %PRJ_NAME%

:end

Thursday, May 15, 2008

vim - some tips on use cscope and ctags

1. cscope does not work very well on c++, it is hard to search class members. (so don't expect cscope can do everything)

2. don't use "cscope -b -q" to build the database

3. with ctrl-\ and f, open header file in a c/C++ source code


nmap < C-\>f :cs find f < C-R>=expand("< cword>") . ".h" < CR>< CR>


4. add database with specification on ignore charactor case.

cs add cscope.out . -C


5. Here is my build bat file for win32

rm cscope.* tags
set project=c:\work\foo
find %project% -name "*.cpp" -o -name "*.[ch]" > cscope.files
cscope -b
ctags --extra=+q -L cscope.files

Monday, May 12, 2008

utils - ti memory data conversion

The ccs IDE provides a function to save memory data to a file, here is a saved file:

1651 1 10032238 0 300
0x00000000
0x00000000
0x00000000
0x00000000
....


It is a text file, with the first line, contains the memory address, the data length etc. From the next line, comes the data. Since the output is still the text file, I need to convert it to actual binary data. So I develop a little application to do the conversion. Not good on awk, or with sed, I use c programming language directly. C is such powerful.


#include < stdio.h>
#include < string.h>

#define LINE_MAX 256
char my_asc2hex(char a, char b)
{
char o;
if (a >= '0' && a <='9') a = a - '0';
if (a >= 'a' && a <='f') a = a - 'a' + 10;
if (a >= 'A' && a <='F') a = a - 'A' + 10;
if (b >= '0' && b <='9') b = b - '0';
if (b >= 'a' && b <='f') b = b - 'a' + 10;
if (b >= 'A' && b <='F') b = b - 'A' + 10;
o = a + b * 16;
return (o);
}
int main(int argc, char* argv[])
{
char line_buf[LINE_MAX];
char* lp;
FILE* fp, *fp_out;
char aa,bb,cc,dd;

if (argc < 3){
printf("%s ti_input_file output_file", argv[0]);
return 1;
}

fp = fopen(argv[1], "r");
if (fp == NULL) return 1;
fp_out = fopen(argv[2], "w+b");
if (fp_out == NULL) {
fclose(fp);
return 1;
}

for(;;) {
lp = fgets(line_buf, LINE_MAX, fp);
if (lp == NULL) goto main_exit;
if (*lp++ == '0' && *lp++ == 'x' && strlen(lp) >= 8) {
aa = my_asc2hex(*lp++, *lp++);
bb = my_asc2hex(*lp++, *lp++);
cc = my_asc2hex(*lp++, *lp++);
dd = my_asc2hex(*lp++, *lp++);

fwrite(&dd, 1, sizeof(char), fp_out);
fwrite(&cc, 1, sizeof(char), fp_out);
fwrite(&bb, 1, sizeof(char), fp_out);
fwrite(&aa, 1, sizeof(char), fp_out);
}
}

main_exit:
fclose(fp);
fclose(fp_out);
return 0;
}


I just need to pay attention to the byte order, for example, if it is "0x00004F99" from the input, the output will be "99 4F 00 00". BUT the confusing part is here:

if (*lp++ == '0' && *lp++ == 'x'...)
....
my_asc2hex(*lp++, *lp++);

In "if" condition, the evaluating is one by one, the first item "evaluate" first, then is the next, while in function, the "evaluation" of parameters is, the last item first (put on the stack first), and moves on previous items. so that is why the first parameter to my_asc2hex is the latter one. kind of confusing using pointer!