coverity modeling build automation tool – cmbat (one way to write multiple-choice menu via shell)

I have been responsible for Coverity tool integration/test/support in ALU LCP (Linux Control Platform) dept for nearly 2 years.  In this post, I would share a ksh tool/framework wrote on 2009 for Coverity modeling build automation. However, I would not involve too many things on Coverity itself (except the necessary background) but rather than some code examples to show one way to write multiple-choice menu via shell (如何用SHELL写多选菜单)- that’s is my point. Of course, if cmbat itself would give you a hint, thank God:)

Coverity: Coverity is a static code analysis tool developed by Coverity Inc. (It is said the biggest and strongest company on static code analysis. Another 2 famous ones you may heard of are Klocwork and Insure++)

Coverity modeling: Because of path limitation of analysis, some functions are unable to be analyzed. Coverity modeling is used to downsize these functions helping Coverity itself doing analysis on them. (There are also other usages on modeling, please refer to Coverity document. How to write Coverity modeling is not covered in this post the either way.)

cmbat: The basic idea is to construct modeling for some important functions (such as memory allocation/deallocation in our case). Then construct the corresponding modeling lib used by cmbat. The last thing is to write an automation tool (ksh in our case) according to your Coverity integration way. Again, please focus on the way to implement multiple-choice menu via shell.

/home/daveti/cmbat/libcov_mm: ll
total 10
drwxr-xr-x  4 daveti   daveti 5 Jan  8 03:07 ims
-rw-r--r--  1 daveti   daveti 246 Jan  8 03:07 ims.map
-rw-r--r--  1 daveti   daveti 1094 Jan  8 03:07 ims_rmm.map
drwxr-xr-x  4 daveti   daveti 5 Jan  8 03:07 msc
-rw-r--r--  1 daveti   daveti 335 Jan  8 03:07 msc.map
-rw-r--r--  1 daveti   daveti 1184 Jan  8 03:07 msc_rmm.map
drwxr-xr-x  4 daveti   daveti 5 Jan  8 03:07 rmm
-rw-r--r--  1 daveti   daveti 851 Jan  8 03:07 rmm.map
/home/daveti/cmbat/libcov_mm: cat ims.map
1:$IMSLIB/alloc/SIPia_Create_1xx_Response.c
2:$IMSLIB/alloc/SIPia_Create_Final_Response.c
3:$IMSLIB/alloc/SIPia_Build_Request.c
4:$IMSLIB/alloc/SIPia_clone.c
5:$IMSLIB/alloc/SIPia_new.c
6:$IMSLIB/dealloc/SIPia_delete.c
7:$IMSLIB/ims_all.c
8:Quit

#!/opt/ksh93e/bin/ksh

##########################################################
# Coverity Modeling Build Automation Tool (cmbat)
# April 22 - 30, 2009
# Version 0.1
# Last Modified: Jan 8, 2011
# Dave.Tian@alcatel-lucent.com
# For Detailed information please refer to
# http://daveti.blog.com                   
##########################################################

# Set Environment
#################
export MODELLIB=/home/daveti/cmbat/libcov_mm
export IMSLIB=$MODELLIB/ims
MENU_CHOICE=""# record the input number string
MENU_MAP=""# find the corresponding map file
MAX_NUM="8"# max number of options among all the available submenus
# in this case, we've only got one IMS submenu with max 8 options
IMS_NUM="8"# max number of options per submenu
IMS_ALL="7"# option number for all the functoins listed in this submenu
IMS_QUIT="8"# option number for quit in this submenu
# U could imagine there should be many more stuffs like this
# if we need to implement more submenu/modeling lib
X_NUM=""# X_XXX is used to match each submenu
X_ALL=""
X_QUIT=""
X_LIB1=""
X_LIB2=""
ALL_FILE1=""
ALL_FILE2=""
BJOBSID=""
BJOBSLINE=""
BJOBSSTAT=""

# Init the menu count for Multiple choices
##########################################
typeset -i count
count=1

while [ "$count" -le "$MAX_NUM" ]
do
 # Once such error happens below
 # ./cmbat[45]: menu_1=0:  not found
 # Please make sure you are using ksh93 not ksh87
 typeset -i menu_${count}
 menu_${count}=0
 count=$(($count+1))
done

# Define functions
##################
cleanup() {
 [[ -f $ROOT/cov.M.out ]] && rm $ROOT/cov.M.out > /dev/null 2>&1
 [[ -f $ROOT/cov.A.out ]] && rm $ROOT/cov.A.out > /dev/null 2>&1
 [[ -f $ROOT/cov.B.out ]] && rm $ROOT/cov.B.out > /dev/null 2>&1
 [[ -f $ROOT/cov.F.out ]] && rm $ROOT/cov.F.out > /dev/null 2>&1
 [[ -f $ROOT/lib.xmldb ]] && rm $ROOT/lib.xmldb > /dev/null 2>&1
 [[ -f $PWD/cov.M.out ]] && rm $PWD/cov.M.out > /dev/null 2>&1
 [[ -f $PWD/cov.T.out ]] && rm $PWD/cov.T.out > /dev/null 2>&1
 [[ -f $PWD/cov.J.out ]] && rm $PWD/cov.J.out > /dev/null 2>&1
 [[ -f $PWD/cov.A.out ]] && rm $PWD/cov.A.out > /dev/null 2>&1
 [[ -f $PWD/cov.B.out ]] && rm $PWD/cov.B.out > /dev/null 2>&1
 [[ -f $PWD/cov.F.out ]] && rm $PWD/cov.F.out > /dev/null 2>&1
 return
}

clean_tmp() {
 [[ -f $PWD/cov.T.out ]] && rm $PWD/cov.T.out > /dev/null 2>&1
 [[ -f $PWD/cov.J.out ]] && rm $PWD/cov.J.out > /dev/null 2>&1
 return
}

show_mainmenu() {
 echo "*************************************"
 echo "*           Main Menu   *"
 echo "*************************************"
 echo "          [1]  MSC"
 echo "          [2]  IMS"
 echo "          [3]  RMM"
 echo "          [4]  MSC+RMM"
 echo "          [5]  IMS+RMM"
 echo "          [6]  All"
 echo "          [7]  Quit"
 echo
 show_input_s
 return
}

show_submenu_ims() {
 echo
 echo "******************************************"
 echo "*              IMS Modeling *"
 echo "******************************************"
 echo "Allocation:"
 echo "------------------------------------------"
 echo "          [1]  SIPia_Create_1xx_Response"
 echo "          [2]  SIPia_Create_Final_Response"
 echo "          [3]  SIPia_Build_Request"
 echo "          [4]  SIPia_clone"
 echo "          [5]  SIPia_new"
 echo
 echo "De-allocation:"
 echo "------------------------------------------"
 echo "          [6]  SIPia_delete"
 echo
 echo "All/Quit:"
 echo "------------------------------------------"
 echo "          [7] All"
 echo "          [8] Quit"
 echo
 show_input_m
 MENU_MAP="ims.map"
 ALL_FILE1="ims_all.c"
 X_LIB1=$IMSLIB
 X_NUM=$IMS_NUM
 X_ALL=$IMS_ALL
 X_QUIT=$IMS_QUIT
 return
}

show_error() {
 echo "Invalid input."
 cleanup
 return
}

show_input_s() {
 print -n "Please enter your single choice: "
 read MENU_CHOICE
 return
}

show_input_m() {
 echo "Please use COMMA to seperate the multiple choices!"
 print -n "Please enter your multiple choices: "
 read MENU_CHOICE
 return
}

show_model() {
 echo "Coverity Modeling ......"
 return
}

show_build() {
 echo "Coverity Building ......"
 return
}

show_analysis() {
 echo "Coverity Analyzing ......"
 return
}

# This function is especially for ALU LCP Coverity Integration
check_jobs() {
 # get the job id from BJOBSLINE
 BJOBSID=$(echo $BJOBSLINE | cut -d" " -f2 | tr -d "<>")
 bjobs $BJOBSID > cov.J.out
 echo $BJOBSLINE

 # get the job stat from BJOBSLINE
 # Pay more attention about the multiple backspaces
 BJOBSSTAT=$(grep $BJOBSID cov.J.out | sed 's/  */ /g' | cut -d" " -f3)

 # handle the DONE stat and JOB-is-not-found
 until [ "$BJOBSSTAT" = "DONE" ]
 do
 echo "####################################################"
 sleep 10
 bjobs $BJOBSID > cov.J.out
 BJOBSSTAT=$(grep $BJOBSID cov.J.out | sed 's/  */ /g' | cut -d" " -f3)

 if [ "$BJOBSSTAT" = "EXIT" ]
 then
 break
 echo "Build job is terminated abnormally."
 echo "Please check the build environment."
 cleanup
 exit 1
 fi
 done
 return
}

proc_Multi_args() {
 if [ -n "$MENU_CHOICE" ]
 then
 # check for valid input
 for num in $(echo $MENU_CHOICE | tr "," "n")
 do
 if ([[ $num != [0-9] ]] && [[ $num != [1-9][0-9] ]]) || [ "$num" -gt "$X_NUM" ]
 then
 echo "Input should be a number and not greater than the QUIT item."
 show_error
 exit 1
 fi
 done

 # Count the number of choices
 for num in $(echo $MENU_CHOICE | tr "," "n")
 do
 ((menu_${num}+=1))
 done

 # check for duplicate
 typeset -i looper
 looper=1
 while [ "$looper" -le "$X_NUM" ]
 do
 if [ $((menu_${looper})) -gt 1 ]
 then
 echo "Input should not be duplicated."
 show_error
 exit 1
 fi
 ((looper+=1))
 done

# check the all choice
 looper=1
 if [ $((menu_${X_ALL})) -eq 1 ]
 then
 while [ "$looper" -le "$X_NUM" ]
 do
 if [ $((menu_${looper})) -eq 1 ] && [ "$looper" -ne "$X_ALL" ]
 then
 echo "Only choose ALL to model all the functions."
 show_error
 exit 1
 fi
 ((looper+=1))
 done
 fi

 # check the quit choice
 looper=1
 if [ $((menu_${X_QUIT})) -eq 1 ]
 then
 while [ "$looper" -le "$X_NUM" ]
 do
 if [ $((menu_${looper})) -eq 1 ] && [ "$looper" -ne "$X_QUIT" ]
 then
 echo "Only choose QUIT to quit the menu."
 show_error
 exit 1
 fi
 ((looper+=1))
 done
 fi

# map the choices into real path
 for num2 in $(echo $MENU_CHOICE | tr "," "n")
 do
 grep ^$num2: "$MODELLIB/$MENU_MAP" | tr -d "$num2:" | tr -s "n" " " >> cov.T.out
 done

 return

else
 show_error
 exit 1
fi
}

# This function is ALU LCP Coverity Integration specific.
# Try to write your own Coverity modeling, build and analysis code here.
make_model() {
 if [ $((menu_${X_ALL})) -eq 1 ]
 then
 show_model
 if [ -z "$ALL_FILE2" ] && [ -z "$X_LIB2" ]
 then
 BJOBSLINE=$(bsub -q $BLD_Q "$MAKEMODEL --config $CONFIGFILE -of $ROOT/lib.xmldb $X_LIB1/$ALL_FILE1 > cov.M.out 2>&1")
 elif [ -n "$ALL_FILE2" ] && [ -n "$X_LIB2" ]
 then
 BJOBSLINE=$(bsub -q $BLD_Q "$MAKEMODEL --config $CONFIGFILE -of $ROOT/lib.xmldb $X_LIB1/$ALL_FILE1 $X_LIB2/$ALL_FILE2 > cov.M.out
2>&1")
 else
 show_error
 exit 1
 fi

elif [ $((menu_${X_QUIT})) -eq 1 ]
 then
 exit 0
 else
 show_model
 BJOBSLINE=$(bsub -q $BLD_Q "$MAKEMODEL --config $CONFIGFILE -of $ROOT/lib.xmldb $(cat cov.T.out) > cov.M.out 2>&1")
 fi
 check_jobs

 show_build
 BJOBSLINE=$(/home/coverity/tools/bsubcov -b)
 check_jobs

 show_analysis
 BJOBSLINE=$(bsub -q $BLD_Q "ksh /home/coverity/tools/subcmds/model.covscr.devA")
 check_jobs

 clean_tmp
 return
}

# Interactive mode
##################
show_mainmenu
if [ "$MENU_CHOICE" = "1" ]
then
 show_submenu_msc        # N/A
 proc_Multi_args
 make_model

elif [ "$MENU_CHOICE" = "2" ]
then
 show_submenu_ims
 proc_Multi_args
 make_model

elif [ "$MENU_CHOICE" = "3" ]
then
 show_submenu_rmm        # N/A
 proc_Multi_args
 make_model

elif [ "$MENU_CHOICE" = "4" ]
then
 show_submenu_msc_rmm    # N/A
 proc_Multi_args
 make_model

elif [ "$MENU_CHOICE" = "5" ]
then
 show_submenu_ims_rmm    # N/A
 proc_Multi_args
 make_model

elif [ "$MENU_CHOICE" = "6" ]
then
 # Do modeling, build, anaylsis based on all available function modelings
 # Again, this is ALU LCP Coverity Integration specific.
 show_model
 BJOBSLINE=$(bsub -q $BLD_Q "$MAKEMODEL --config $CONFIGFILE -of $ROOT/lib.xmldb $IMSLIB/ims_all.c $MSCLIB/msc_all.c $RMMLIB/rmm_all.c > cov.M.out
2>&1")
 check_jobs

 show_build
 BJOBSLINE=$(/home/coverity/tools/bsubcov -b)
 check_jobs

 show_analysis
 BJOBSLINE=$(bsub -q $BLD_Q "ksh /home/coverity/tools/subcmds/model.covscr.devA")
 check_jobs

 clean_tmp

elif [ "$MENU_CHOICE" = "7" ]
then
 exit 0

else
 show_error
 exit 1
fi
Posted in Dave's Tools | Tagged , , | Leave a comment

while my guitar madly weeps…

Well, this is my first post on my guitars:) I’ve got 2 elec-guitars right now – the black Jackson (Bought on 2002. PM44?I could not remember the model clearly) and the white Squier (Bought on 2009. CA Series special edition). Both the 2 guitars are very cheap but indeed have a good feeling for me no matter solo or rhythm. Below are some pics and one video during my playing in company. Enjoy:)

The left pic was took on 2010 Jan – Lucent QD R&D 2010 Evening Party – Jackson – Song: 爱了就爱了(陈琳)&外面的世界(齐秦); the right pic was took on 2010 Dec – Lucent QD R&D 5/10/15 Anniversary – Squier – Song: 不再犹豫(Beyond)&晴朗(老狼) – the same to the video below:) (Link to download the video if media player is not so kind enough: Squier_Dec_2010_Anniversary)


Posted in Music Prose | Tagged , , | 4 Comments

error C2026 – VC compiler limitation and countermeasure

De facto, I am not familiar with VC compiler and do not use it often either. However, it really gives me a little surprise when I have a try, like the limitation on number of ‘else if’ (I could not remember the error code there). Here is an error I recently encountered – C2026 and some good workarounds – wish it help:)

Detailed instruction on MSDN for this error on Visual Studio 2005: http://msdn.microsoft.com/en-us/library/dddywwsc%28v=vs.80%29.aspx

Issue code episode:

char sz[] =
"
imagine a really, really 
long string here
";

Workaround 1 from MSDN:

char sz[] =
"
imagine a really, really "
"long string here
";

Workaround 2 from sprintf/snprintf

char sz[ 50000];
char *ptr = sz;
ptr += sprintf( ptr, "%s", "imaged long string - Part 1");
ptr += sprintf( ptr, "%s", "imaged long string - Part 2");
...
Posted in Programming | Tagged , | Leave a comment

state machine programming – smp

This is a little C program used to show the framework of state machine programming (smp,状态机编程). Detailed state transition picture is as below. Try to build the source code below and enjoy:)

/*
* State Machine Program (SMP)
* This program is used to construct basic framework
* of state machine programming, which is very useful
* in telecom software. Imagine when a protocol stack,
* multi-threads and socket are involved here…
* Language: C/C++
* OS: Unix/Linux
* Originated: Dec 29, 2010
* dave.tian@alcatel-lucent.com
*/

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

#define MSG_BUF_SIZE_MAX        1000

/* Event definition used to tigger State transition */
typedef enum _QuestionEvent
{
QUESTION_NONE,
QUESTION_HI,
QUESTION_WHO_ARE_YOU,
QUESTION_BYE,
QUESTION_NOT_SUPPORTED,
QUESTION_MAX
} QuestionEvent;

/* State definition */
typedef enum _ProgramMoodState
{
PROGRAM_MOOD_STATE_NONE,
PROGRAM_MOOD_STATE_GOOD,
PROGRAM_MOOD_STATE_HIGH,
PROGRAM_MOOD_STATE_ANY,
PROGRAM_MOOD_STATE_MAX
} ProgramMoodState;

/* Function definition for State transition */
typedef void (*ProgramActionFunction) (void);

/* State Machine transition element definition */
typedef struct _ProgramStateMachineTransition
{
ProgramMoodState currentState;
QuestionEvent eventReceived;
ProgramActionFunction actionFunction;
ProgramMoodState newState;
} ProgramStateMachineTransition;

/* State Machine entry definition used during transition */
typedef struct _ProgramStateMachineEntry
{
ProgramActionFunction actionFunction;
ProgramMoodState newState;
} ProgramStateMachineEntry;

/* Action function declaration for different state transition
* ‘static’ is used here to guarantee that the function could
* only be used within this source file */
static void processOthers( void);
static void processWhoAreYouBeforeHi( void);
static void processByeBeforeHi( void);
static void processHiAfterHi( void);
static void processByeAfterHi( void);
static void processHiAfterWhoAreYou( void);
static void processWhoAreYouAfterWhoAreYou( void);
static void processHi( void);
static void processWhoAreYou( void);
static void processBye( void);

/* State Machine transition table definition
* ‘static’ is used here to guarantee that only
* functions in this source file could access this table */
static ProgramStateMachineTransition programSMTtable[] =
{

/* This is the core part of State Machine Programming */
/* Unexpected state transition handling below */
{PROGRAM_MOOD_STATE_ANY, QUESTION_NOT_SUPPORTED, processOthers, PROGRAM_MOOD_STATE_NONE},
{PROGRAM_MOOD_STATE_NONE, QUESTION_WHO_ARE_YOU, processWhoAreYouBeforeHi, PROGRAM_MOOD_STATE_NONE},
{PROGRAM_MOOD_STATE_NONE, QUESTION_BYE, processByeBeforeHi, PROGRAM_MOOD_STATE_NONE},
{PROGRAM_MOOD_STATE_GOOD, QUESTION_HI, processHiAfterHi, PROGRAM_MOOD_STATE_GOOD},
{PROGRAM_MOOD_STATE_GOOD, QUESTION_BYE, processByeAfterHi, PROGRAM_MOOD_STATE_NONE},
{PROGRAM_MOOD_STATE_HIGH, QUESTION_HI, processHiAfterWhoAreYou, PROGRAM_MOOD_STATE_HIGH},
{PROGRAM_MOOD_STATE_HIGH, QUESTION_WHO_ARE_YOU, processWhoAreYouAfterWhoAreYou, PROGRAM_MOOD_STATE_HIGH},

/* Expected state transition handling below */
{PROGRAM_MOOD_STATE_NONE, QUESTION_HI, processHi, PROGRAM_MOOD_STATE_GOOD},
{PROGRAM_MOOD_STATE_GOOD, QUESTION_WHO_ARE_YOU, processWhoAreYou, PROGRAM_MOOD_STATE_HIGH},
{PROGRAM_MOOD_STATE_HIGH, QUESTION_BYE, processBye, PROGRAM_MOOD_STATE_NONE}
};

/* Max number of entries definition used to State Machine initialization
* for SMP, this value is used to determine how many entries init’ed from
* programSMTtable[] to programSMTentry[][]. This value should not bigger
* than the max size of array programSMTtable. Once programSMTtable[] is
* added new state transitions, this value needs to be updated */
#define STATE_MACHINE_ENTRY_MAX         10

/* State Machine transition entry definition
* used to provide usable entry to State Machine
* transition table – init’ed by transition table */
static ProgramStateMachineEntry programSMTentry[ PROGRAM_MOOD_STATE_MAX][ QUESTION_MAX];

int main ( void)
{

/* Globle variable standing for this program’s mood */
ProgramMoodState myMood = PROGRAM_MOOD_STATE_NONE;

/* Globel variable standing for event got from user */
QuestionEvent myEvent = QUESTION_NONE;

char msgBuf[ MSG_BUF_SIZE_MAX];
char *stringPtr;
int i;

printf(“nState Machine Program (SMP)n”);
printf(“Developed by Stupid Maniac Programmer (SMP) davetin”);
printf(“dave.tian@alcatel-lucent.comn”);
printf(“Type ‘help’ for detailed usagen”);

/* Init State Machine (entry) */
initSMT();

while ( 1)
{
myEvent = QUESTION_NONE;
printf(“n>> “);

/*
* scanf() is unable to support empty input – stupid
* gets() is able to cause buffer overflow – dangerous
* fgets() is including the newline right before ” – no comment
*/

/* Note: newline is read into buffer 2! */
fgets( msgBuf, MSG_BUF_SIZE_MAX, stdin);

/* Change the newline to null */
msgBuf[ strlen( msgBuf) – 1] = ”;

stringPtr = msgBuf;
for ( i = 0; i < strlen( msgBuf); i++)
{
if ( isspace( msgBuf[ i]))
{

/* Bypass the whitespaces forwarded */
stringPtr++;
}
else
{
break;
}
}

if ( stringPtr == msgBuf + strlen( msgBuf))
{

/* No valid input in this time */
continue;
}

if ( strcasecmp( stringPtr, “hi”) == 0)
{
myEvent = QUESTION_HI;
}
else if ( strcasecmp( stringPtr, “whoru”) == 0)
{
myEvent = QUESTION_WHO_ARE_YOU;
}
else if ( strcasecmp( stringPtr, “bye”) == 0)
{
myEvent = QUESTION_BYE;
}
else if ( strcasecmp( stringPtr, “help”) == 0)
{
showHelp();
continue;
}
else if (strcasecmp( stringPtr, “exit”) == 0)
{

/* Exit SMP */
return 0;
}
else
{
myEvent = QUESTION_NOT_SUPPORTED;
}

/* Start State Machine Transition */
startSMT( &myMood, myEvent);
}

return 0;
}

/* State Machine (entry) initialization function definition */
void initSMT( void)
{
QuestionEvent e;
ProgramMoodState s, sNew;
ProgramActionFunction af;
int i;

for ( i = 0; i < STATE_MACHINE_ENTRY_MAX; i++)
{
s = programSMTtable[ i].currentState;
e = programSMTtable[ i].eventReceived;
af = programSMTtable[ i].actionFunction;
sNew = programSMTtable[ i].newState;

programSMTentry[ s][ e].actionFunction = af;
programSMTentry[ s][ e].newState = sNew;
}
}

/* State Machine transition function definition */
void startSMT( ProgramMoodState *myMood, QuestionEvent event)
{
ProgramMoodState mState;
ProgramStateMachineEntry *smEntry;

if ( event == QUESTION_NOT_SUPPORTED)
{

/* Update the local mood state to wildcard */
mState = PROGRAM_MOOD_STATE_ANY;
}
else
{

/* Set the local mood state to globle mood */
mState = *myMood;
}

/* Do the mapping via programSMTtable */
smEntry = &programSMTentry[ mState][ event];

/* Note: no pointer checking here – memory fault may happen if
* un-covered state transition in state machine transition table
* is triggered here – be ware of this! */

/* Call for action function */
smEntry->actionFunction();

/* Update the globle mood with new state */
*myMood = smEntry->newState;
}

/* Detailed action function definitions */
void processWhoAreYouBeforeHi( void)
{
printf(“Hey, Man, u never say hi to me before asking who i am…n”);
}

void processByeBeforeHi( void)
{
printf(“Hey, Man, u never say hi before saying bye to me…ok, bye…n”);
}

void processHiAfterHi( void)
{
printf(“Hey, Man, I am sure this is not the first time u saying hi to me…r u a hi machine?n”);
}

void processByeAfterHi( void)
{
printf(“Bye, Man!n”);
}

void processHiAfterWhoAreYou( void)
{
printf(“Hey, Man, u are saying hi to me againe…ok, hi…n”);
}

void processWhoAreYouAfterWhoAreYou( void)
{
printf(“Hey, Man, u did ask me this question before right? I am SMP, us 2?n”);
}

void processOthers( void)
{
printf(“Hey, Man, couldn’t you please make me feel a little better?n”);
}

void processHi( void)
{
printf(“Hi, Man, you are so nice!n”);
}

void processWhoAreYou( void)
{
printf(“As you might have already known, I am a stupid State Machine Program coded by a nuts job…n”);
}

void processBye( void)
{
printf(“Bye, Man, wish you a good day!n”);
}

/* Stupid Boring help function definition */
void showHelp( void)
{
char dispBuf[ MSG_BUF_SIZE_MAX];
snprintf( dispBuf, MSG_BUF_SIZE_MAX, “%s”,
“SMP supports following questions/commands belown”
“hi – say hello to SMPn”
“whoru – ask SMP ‘who are you’n”
“bye – say byebye to SMPn”
“help – show this help menun”
“exit – exit SMPn”
“Note: any other words to SMP would make her feel unhappy!n” );

printf(“%s”, dispBuf);
}

Posted in Dave's Tools, Programming | Tagged , , | Leave a comment

Essential Essence of Agile/Scrum

近期参加了公司组织的风险管理培训,结合Agile/Scrum,总结了一下自己对Why Agile/Scrum的理解,以下仅为个人见解,如有雷同,只能说英雄所见略同:)

Essential Essence of Agile by Dave Tian

1.    挖掘客户的need而不是want - 通过与PO的及时、按时沟通,以最低风险达到客户最大满意度和最大收益

2.    软件开发从功能层面转向业务层面 - 通过捆绑PO、dev、tester,使团队整体感知客户的业务,高屋建瓴领,而不是仅仅专注于feature层面

3.    应对客户需求的多变 - 通过PO和短期迭代,随时交付可用产品(demo),客户可随时根据自身情况作出需求调整

4.    应对现代软件管理的滞后与盲目预测 - 混沌告诉我们超过24小时的天气预报是扯淡,那么在软件项目开始前就做出的任何预测也将在短期内失效,通过Scrum每天的例会和短期迭代,把大计划分化成阶段计划,并可以根据backlog里feature的prio随时更新计划

5.    应对软件开发人员水平的参差不齐 - 通过Scrum的例会,随时总结个人项目中的问题并分享与团队,以期团队整体在项目中最大化技术提升和团队战斗力而不是重在个人

6.    应对软件测试的资源浪费和事倍功半 - 忘了谁说的这句话(大概意思),软件测试不是用来发现bug的。个人非常同意,dev应当是自己code的最好tester,于是在agile中,dev应当充分利用新的UT技术或者其他自动化测试技术来完成对自己code的测试;而tester将从功能测试的层面转向业务层面,而业务层面的测试又要求新技术TDD、BDD、ATDD的应用(如果以现在FT、ST、NLT的架构来看,那么dev将负责FT和ST,tester会直接专注于NLT-业务层面)

Posted in Programming | Tagged , | Leave a comment

clear screen for text – 3 ways in C

I have been wondering the implementation of top’s (I mean ‘top’ command) displaying for long – like a text ‘GUI’ on the screen with numbers changing all the time. Though still I have not got time to go thru the source of ‘top’, I find some other ways to do that. Now imagine if you could clear screen after the each displaying and output the results right to the same beginning position of the screen, you have got a ‘top’-like displaying indeed.(用curses库实现文字清屏-’top’命令的显示风格)

1.  Shell command ‘clear’

This is the easiest way to do.  With another C lib function ‘system‘, you can implement the displaying like below:

// Clear the terminal output
system(“clear”);
// Then printf stuff……

However, you will find this is not real ‘top’-like displaying – ‘clear’ indeed always makes the output right from (0, 0) (the top left corner of the screen). But you still can find the previous output by scrolling back the window and all the output is re-displayed again as we are using ‘printf’ – that is why there should be a flash on screen during each displaying. We will rise the bar – is there a way to fix the things unchanged on screen but redisplay the things changed?

2. Lib curses/ncurses

‘curses’ lib was originated by Bill Joy and Ken Arnold. ‘ncurses’ lib is an enhancement version of ‘curses’ by GNU. All we need to do is: 1. #include <curses.h> (We do not include <ncurses.h> as we may need to support both Solaris and Linux). 2. cc -o a.out src.c -lcurses. Now we could code in this way:

initscr(); //start curses mode
for ( i = 0; i < 100; i++)
{
sleep(1);
clear(); //This is clear from curses lib
printw(“davetin”); // curses’ printf stuff
printw(“——-n”);
printw(“i = %dn”, i);
refresh(); // display on the screen
}
endwin(); // quit curses mode

When running this episode of code, you will find – 1. no previous output even scrolling back the window; just one output on the screen; 2. except the changing ‘i’, others are remain static! That is cool as we could write the same thing like ‘top’ displayed. The hidden thing behind is concept of ‘virtual’ window. When we call ‘initscr’, we make a new ‘virtual’ window called ‘stdscr’. All the things we try to display via ‘printw’ will NOT be written to standard output unless ‘refresh’ is called.  More of that, ‘refresh’ would make sure only the changed things be refreshed on the screen. Now what? Color – no problem; Highlight – no problem……

3. cleardevice/clrscr

The 2 functions needs ‘#include <conio.h>‘, which is NOT a standard C header file. However, it is usually included by TurboC and Windows.  ‘cleardevice’ is used to clear graphic screen, which ‘clrscr’ is used to clear text screen.

Posted in Programming | Tagged , | 7 Comments

agile tour 2010 – Qingdao

Some personal feeling after agile tour 2010 – Qingdao, China.

今天有幸参加了agile tour 2010青岛站的会议(http://agiletourchina.agilewizard.org/qingdao/),很棒,无论是speaker的演讲主题还是下午的分会场,都能看出组委会的用心。如果明年有机会,我想我还会来参见的。我是一个agile或scrum的门外汉,更没有几十年的coding经验,以下只是个人对agile的一些思考或看法:

1. agile作为一种方法论,无疑是软件工程的一种回归,回归到人而不是软件开发过程本身。套用nokia的一句广告词:科技以人为本。个人非常同意这一点,软件的附加值应该在dev上体现,而不是靠市场来体现,虽然QQ已经用行动说明其实人并不重要,重要的是走别人的路,让别人无路可走……(这又是另一个话题。)

2. agile作为一种生活哲学,无疑是人生理性规划的一种回归,回归到原始单纯的驱动。我至今都记得大学时我们理学院院长曾经真诚的说的一句话:当你不知道干什么的时候,就学习。(也至今记得当时自己讽刺嘲笑的表情……) 即便是到现在,或者是由于处女座的因素,总是在试图完美的design自己的人生,等待完美的机遇,后果是突然发现自己快30了,依然一事无成。或许这是agile给我的最大提醒,套用Bill Li先生会上引用功夫熊猫里乌龟大师的一句话:Yesterday is history; tomorrow is mystery; today is a gift.

3. agile做为一种新的软件工程方法,对整个软件行业的影响将是异常深远。我能体味agile发起者的野心,一种试图在资本盈利和软件工程之间建立完美连接。至少听起来是这样,充分信任scrum team并赋予自管理的权利和免收外部干涉的环境,同时又能保证最低的风险的最高的盈利。我的问题很简单,如何改造现有的大型企业的管理架构模式(例如,经理可能比dev还要多)使之适应agile?或者换一个角度来说,agile对大企业来说更合适于小部门团体的改造或者小公司的改造。我始终觉得在有一种新的管理模式与agile能配合之前,对于大型企业,agile的问题太多,不实用 (当然这是管理者的问题,我只是一名普通民工)。

4. agile作为一种新的研发团队模式,无疑更是影响可怕,Eric在会中说到,至今没有agile tester宣言。a. tester还有必要吗?毫无疑问,tester永远都是需要的,只不过其智能与技术讲与目前完全脱离,有一点我赞同:testing不是来发现bug的(虽然作为一个dev我做不到这一点)。在agile下,bug的testing的实现者无疑最好是dev,只要有足够的时间buffer,我相信dev本人才能写出最好的针对其code的测试case,UTcode,tool,anyway。而此时的tester则更需要向业务层面进行转移,随之的新技术TDD,ATTD,BDD。b. 研发经理变成了PO(scrum)或者变成◎#¥%……※×,anyway。c. scrum master应该是独立于任何研发项目并专注于agile实践的指导者(从这里你能看出scrumAlliance的野心,有点大学四六级证的意思,另一个方面,创造了一个新的职业,开拓了职业转型与从业方向)。

5. 结尾,再次感谢agile tour举办方的努力,谢谢。作为一名普通dev,agile其实与我无关,因为这更应该是管理层面的问题,而不是实现层面。你依然还要看一堆书,不断的学习新的语言与技术,其实一切都没有变,因为最终创造世界的是我们而不是agile。

Posted in Programming | Tagged , | Leave a comment

why try to change me now

For the one who loves me and the one who I loved before…

I’m sentimental
So I walk in the rain
I’ve got some habits
Even I can’t explain
Go to the corner
I end up in Spain
Why try to change me now

————————-Fiona Apple – Why try to change me now

Posted in Music Prose | Leave a comment

VirtualBox vs. VMwarePlayer

If you are using Windows XP and want to use certain virtual machine, no doubt, VirtualBox/VMwarePlayer should be your first 2 options. De facto, VirtualBox was my 1st choice as I once ran it on my Window XP with SP2 and as we all know that VMware Player is nothing else but a player – playing the image created by VMware Workstation…Now thing’s changed after i moved to Windows XP SP3 and on VMware Player:

1.  VBoxTestOGL.exe Error when starting VirtualBox 3.2.10

This is the main reason why i do NOT recommend VirtualBox. It is an already known error from VirtualBox forum and still no fix for it till i write this blog. Of course, we could ignore this and indeed VirtualBox will get started after few seconds. However, I never get my RH5.0 Enterprise Linux run – right struck in the hardware init. I am NOT sure if it is related with this error. However, it really makes me think about another virtual machine – as you know, VMware Player.

2. VMware Player is NOT just a player right now

Thanks to VMware Inc., now we could create virtual machines in VMware Player and though it is NOT open srouce, it is FREE – Forget VMware Workstation right now. You get VMware Player for FREE! Now, i installed Solaris 10 b50 on it and it works well without any error. Please kindly note that you may need to download the OS tools to support corresponding OS – Linux, Solaris, FreeBSD, Windows…I would recommed downloading them all before you install any guest OS.

Conclusion: It would be nice for VirtualBox running on Solaris. However, this is not the same case on my Windows XP with SP3 – VMware Player wins this round.

Posted in OS | Tagged , | Leave a comment

quick guide for new language support in netbeans

Original web: http://netbeans.dzone.com/tips/quickstart-guide-language-supp  在netbeans下写新的语言支持插件

This tutorial can be of interest for all those who want to create a module that adds support for a new language inside NetBeans IDE.
Original article: http://hiperia3d.blogspot.com/2008/04/netbeans-tutorial.html [1] (the original article has coloring that makes reading easier. If you have some dificulty reading it here, you can go there).  

The process of creating the first of the modules that compose my X3DV Module Suite [2] was similar to the one described here.  

We will learn how to make a module that has these features:  

  • Syntax highlighting that is specific for the language we will define.
  • Brace completion and auto-indentation.
  • Icons for the new files of that language.
  • To be able to create new files written in our new language.
  • Template for the new files written in that language.

Just download the last version of NetBeans IDE (download NetBeans IDE 6.1 Beta [3]). Then, follow all the steps described here. This tutorial is valid for the 6.1 version of NetBeans IDE, which has many improvements that make module building easier.  

This tutorial takes a fictional language called Foo Language as a sample. I suggest to follow the tutorial as it is, and later, adapt it to your needs. This is not a highly technical tutorial, but a quickstart guide that can be very easy for newcomers.

First Steps With Your Module

Create a new NetBeans project:  

[4]
Choose NetBeans Modules in Categories and Module in Projects:  

[5]
Fill in your project Name, locate the directory where its project folder will be placed, and mark it as a Standalone Module.  

[6]
Fill the info for your module. You just have to fill the two first text boxes: change the Code Name Base to what is appropriate for your module and choose a Display Name.  

[7]
The project will be created. Now we will add the basic: support files for the new file type.  

[8]  

New File Type Support

Over the project name, right click and select New/File Type:  

[9]
In the dialog that appears, you must enter some data so the NetbBeans IDE recognizes the new file type.
In MIME Type you must enter text/x- usually followed by the main extension of the file type.
Why does it say text/x-? As you may note, what you enter is not the true MIME type. For the IDE, all the extensions we create are text files.  

In Extension(s) you must enter them separated with spaces. In our example, there’s only one extensions for Foo Files: .foo  

[10]
In Class Name Prefix, you enter the name of the file type, so all classes generated by the IDE for this module will start with it.  

In Icon, you must locate in your hard drive a gif icon of 16×16 pixels. In our example, it’s this:  

[11]
Although
in some tutorials they say that jpg and png images can also be used, I
found that sometimes they’re not displayed. So I recommend using gif
images, as they are less error-prone.
The IDE will copy your icon to the project directory.  

[12]
At
this point, a bunch of files will be created by NetBeans IDE and opened
in the code editor. Close them all, you don’t need to edit them.  

Now
our module is ready to recognize and create the new file types. But we
want the new files to have a default content. So we will edit the
generated template. Locate the file named:  


Edit it and write the content that you want to be the default when you create a new file.  

[13]
Locate the XML Layer in the module. The XML Layer file is the soul of our module. It controls most of the things that a module can do.  

[14]
Locate these lines:  

[15]The
next step is to create a description of the new supported file type
that will be displayed when you want to create it, in the New File
Wizard. This description will be stored in a file called
“Description.html” (strange… uh?).  

Add this line after the one highlighted in blue, modifying it to your project url:  

<attr name=”templateWizardURL” urlvalue=”nbresloc:/org/yourorghere/
foolanguagesupport/Description.html”/>
This line we added describes where the Description of the new file is. Right click over your project and select New/Other. Select Other/HTML file.  

[16]
Name the file “Description”, and leave the rest as it is.  

[17]
Replace all the contents of the generated file with this:  

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
<html>
<head>
<title></title>
</head>
<body>
Creates a foo file that is useful for nothing at all.
</body>
</html>  

This is what we will see as a result of these steps once the module is finished and we want to create a Foo file.  

[18]

Create the Language Support

Now that we have the new files recognized, we will add syntax coloring and other features to our language module.
To
be able to support language features, we must do the following: right
click over your project and choose “Properties”. The properties of your
module will be displayed. Click over libraries (on the left) and then
the “Add…” button.  

[19]
In the list, search for the entry called “Generic Languages Framework”, and add it.  

[20]
Now, right click over your project and select New/Other.  

In Categories, select “Module Development”, and on the right, select “Language Support”.  

[21]
Then enter the MIME Type and Extensions as we did in the first section of our tutorial.  

[22]
You
will see that the XML Layer has changed and now has more things added.
Between them, there’s a new file that describes our language. That file
is called “language.nbs”.  

As the XML Layer has been modified,
the icon of our files may have disappeared, so we need to add something
to the XML Layer file to recover it.  

Close all the opened files. Locate the file called XML Layer, and open it. Locate the line highlighted in blue in this image, that says  

<file name=”language.nbs” url=”language.nbs”>
[23]
And replace that entire line with:  

<file name=”language.nbs” url=”language.nbs”>
<attr name =”icon” stringvalue=
“org/yourorghere/foolanguagesupport/foo_gif.gif”/>
</file>

Editing The Language File

The
default language.nbs file is filled with contents that may be a good
start point for a scripting language. For declarative languages like
VRML or X3D, or markup languages like HTML or similar, these contents
are not useful.  

In our example of the Foo Language, we will use
a very simple language definition. This way you will understand the
basics of defining languages.  

So delete all the contents of the file language.nbs, and replace them with this:  

# To change this template, choose Tools | Templates
# and open the template in the editor.

# definition of tokens
TOKEN:header:( "# foo language v1.0"
)

TOKEN:line_comment: ( "#"[^ "n" "r"]* |
"//"[^ "n" "r"]* )

TOKEN:keyword:(
"foo_function" |
"foo_command"
)

TOKEN:field:(
"foo_value"
)

# all that follows is useful for mostly all languages
TOKEN:identifier: ( ["a"-"z" "A"-"Z"]
["a"-"z" "A"-"Z" "0"-"9" "_"]* )
TOKEN:number: (["0"-"9"]*)
TOKEN:operator: (
":" | "*" | "?" | "+" | "-" | "[" | "]" |
"<" | ">" |
"^" | "|" | "{" | "}" | "(" | ")" |
"," | "=" | ";" |
"." | "$"
)
TOKEN:string:(
"""
(
[^ """ "\" "r" "n"] |
("\" ["r" "n" "t" "\" "'" """]) |
("\" "u" ["0"-"9" "a"-"f" "A"-"F"]
["0"-"9" "a"-"f" "A"-"F"]
["0"-"9" "a"-"f" "A"-"F"]
["0"-"9" "a"-"f" "A"-"F"])
)*
"""
)

TOKEN:string:(
"'"
(
[^ "'" "\" "r" "n"] |
("\" ["r" "n" "t" "\" "'" """]) |
("\" "u" ["0"-"9" "a"-"f" "A"-"F"]
["0"-"9" "a"-"f" "A"-"F"]
["0"-"9" "a"-"f" "A"-"F"]
["0"-"9" "a"-"f" "A"-"F"])
)*
"'"
)

TOKEN:whitespace:( [" " "t" "n" "r"]+ )

# colors
COLOR:header:{
foreground_color:"orange";
background_color:"black";
font_type:"bold";
}

COLOR:line_comment:{
foreground_color:"#969696";
}

COLOR:keyword:{
foreground_color:"red";
font_type:"bold";
}

COLOR:field:{
foreground_color:"#25A613";
font_type:"bold";
}

# parser should ignore whitespaces
SKIP:whitespace

# brace completion
COMPLETE "{:}"
COMPLETE "(:)"
COMPLETE "":""
COMPLETE "':'"

# brace matching
BRACE "{:}"
BRACE "(:)"

# indentation support
INDENT "{:}"
INDENT "(:)"

Now, create a Foo file, using a plain text editor, and save it with the extension .foo  

These will be its contents:  

# foo language v1.0

# comment
// another comment

foo_function {

foo_command ( foo_value 1 0 1 );

}

Now let’s see the language.nbs file and understand the basic parts.  

TOKEN:header:( “# foo language v1.0”
)  

TOKEN:keyword:(
“foo_function” |
“foo_command”
)  

The Tokens are
the words that are part of your language, and you want them colored.
They define types of words that have something in common in your
language. You group them into a category, that is a token.
The words are between double quotes, and separated by a | sign.  

COLOR:header:{
foreground_color:”orange”;
background_color:”black”;
font_type:”bold”;
}  

COLOR:line_comment:{
foreground_color:”#969696″;
}  

This
defines the colors used for each token. You can specify more properties
for colors, but these are the basic ones. All these properties are very
easy to understand by their own names, as you see. The colors can be
specified by their names (although it recognizes only a few) or by its
number.  

# brace completion
COMPLETE "{:}"

What
these lines do is that when you type a { sign, the editor automatically
will type } after your caret, speeding your work and making it less
error-prone.  

# brace matching
BRACE "{:}"

# indentation support
INDENT "{:}"

This
sentences make that when you place the caret over a brace, the matching
brace will be highlighted, and that lines after those signs will be
indented.

Final Note

Now you know all that is needed to create the basic support for a new file type and language syntax highlighting.
You can add anything you like to your module, that you think is important for you and that could make your work easier.There’s
much more than can be done with NetBeans IDE. I invite just to test it,
join its huge community of users, and experience it by yourself.-Jordi R. Cardona-
X3D/VRML Worldbuilder
Java Programmer
X3DV Module Suite Developer.
Hiperia3D News [24]  

© 2008 by Jordi R. Cardona. The images and text of this post were added
by the author to dzone. The author has granted dzone.com with
exclusivity to use these images and text for the only purpose to spread
this article. If you want to promote this tutorial, you can link to the original one at: http://hiperia3d.blogspot.com/2008/04/netbeans-tutorial.html [1]   Source URL: http://netbeans.dzone.com/tips/quickstart-guide-language-supp

Posted in IDE_Make | Tagged , , | 3 Comments