Conditional Branching

Several other commands provide additional capabilities for enhancing the script execution environment, although none of these additional commands interacts directly with the tfsscript() function as do exit , goto , gosub , and return . The one remaining command implementation that is worth detailing is the if command. The if command provides MicroMonitor with the conditional branching capabilities needed for any programming environment. The implementation of if uses the facilities Ive already introduced with gosub , goto , exit , and return.

Listing 8.6: Conditional Branch Support: The if Command.
image from book
 char *IfHelp[] = {     "Conditional branching",     "-[t:] [{arg1} {compar} {arg2}] {action} [else action]",     " Numeric/logic compare:",     "  gt lt le ge eq ne and or",     " String compare:",     "  seq sne",     " Other tests (-t args):",     "  gc, ngc, iscmp {filename}",     " Action:",     " goto tag  gosub tag  exit  return",     0, }; int If(int argc, char *argv[]) {     int opt, arg, true, if_else, offset;     void    (*iffunc)(), (*elsefunc)();     long    var1, var2;     char    *testtype, *arg1, *arg2, *iftag, *elsetag;     testtype = 0;     while((opt=getopt(argc,argv,"t:")) != -1) {         switch(opt) {         case 't':             testtype = optarg;             break;         default:             return(CMD_PARAM_ERROR);         }     }     elsetag = 0;     elsefunc = 0;     offset = true = if_else = 0; 
image from book
 

The goal of the if command is to make some type of test or comparison and, based on the result of that test, to take some kind of action. The comparison is generally based on comparing the content of a shell variable to some constant or to another shell variable. The variables can be string or numerically based. The -t option allows the user to check for the presence of a character on the console port or to determine if a file is compressed or not.

The basic syntax of the if command is

if {comparison between A & B is true}{perform actionX}

[else {perform actionY}]

or

if {-t testtype}{perform actionX}[else {perform actionY}]

where the test performed by testtype can be true or false.

The if command offers two potential outcomes , so there must be two different function pointers to load with the appropriate function that performs the requested action ( iffunc and elsefunc ). Referring to Listing 8.6, the command line is first tested for the t option. If present, then the appropriate flag is set.

Listing 8.7: Parsing Else Clauses.
image from book
 /* First see if there is an 'else' present... */     for (arg=optind;arg<argc;arg++) {         if (!strcmp(argv[arg],"else")) {             if_else = 1;             break;         }     }     if (if_else) {         elsetag = argv[argc-1];         if (!strcmp(argv[argc-1],"exit")) {             offset = 2;             elsefunc = exitscript;         }         else if (!strcmp(argv[argc-1],"return")) {             offset = 2;             elsefunc = gosubret;         }         else if (!strcmp(argv[argc-2],"goto")) {             offset = 3;             elsefunc = gototag;         }         else if (!strcmp(argv[argc-2],"gosub")) {             offset = 3;             elsefunc = gosubtag;         }         else             return(CMD_PARAM_ERROR);     }          iftag = argv[argc-offset-1];     if (!strcmp(argv[argc-offset-1],"exit"))         iffunc = exitscript;     else if (!strcmp(argv[argc-offset-1],"return"))         iffunc = gosubret;     else if (!strcmp(argv[argc-offset-2],"goto"))         iffunc = gototag;     else if (!strcmp(argv[argc-offset-2],"gosub"))         iffunc = gosubtag;     else         return(CMD_PARAM_ERROR); 
image from book
 

Further parsing (Listing 8.7) determines if the else keyword is present on the command line. If so, the branching code loads the elsefunc function pointer with the else action. This action can be a goto , gosub , exit , or return . Next, the following four-way branch loads the iffunc function pointer with a corresponding action.

Listing 8.8: Performing the Test or Comparison.
image from book
 if (testtype) {         if (!strcmp(testtype,"gc")) {             if (gotachar())                 true=1;         }         else if (!strcmp(testtype,"ngc")) {             if (!gotachar())                 true=1;         }         else if (!strcmp(testtype,"iscmp")) {             TFILE *tfp;             tfp = tfsstat(argv[optind]);             if (tfp) {                 if (TFS_ISCPRS(tfp))                     true=1;             }             else                 printf("'%s' not found\n",argv[optind]);         }         else             return(CMD_PARAM_ERROR);     }     else {         arg1 = argv[optind];         testtype = argv[optind+1];         arg2 = argv[optind+2];         var1 = strtoul(arg1,(char **)0,0);         var2 = strtoul(arg2,(char **)0,0);         if (!strcmp(testtype,"gt")) {             if (var1 > var2)                 true = 1;         }         else if (!strcmp(testtype,"lt")) {             if (var1 < var2)                 true = 1;         }         else if (!strcmp(testtype,"le")) {             if (var1 <= var2)                 true = 1;         }         else if (!strcmp(testtype,"ge")) {             if (var1 >= var2)                 true = 1;         }         else if (!strcmp(testtype,"eq")) {             if (var1 == var2)                 true = 1;         }         else if (!strcmp(testtype,"ne")) {             if (var1 != var2)                 true = 1;         }         else if (!strcmp(testtype,"and")) {             if (var1 & var2)                 true = 1;         }         else if (!strcmp(testtype,"or")) {             if (var1  var2)                 true = 1;         }         else if (!strcmp(testtype,"seq")) {             if (!strcmp(arg1,arg2))                 true = 1;         }         else if (!strcmp(testtype,"sne")) {             if (strcmp(arg1,arg2))                 true = 1;         }         else             return(CMD_PARAM_ERROR);     } 
image from book
 

Next, referring to Listing 8.8, the test or comparison is executed, and the true flag is set based on the result.

Listing 8.9: Execute the Appropriate Action.
image from book
 /* If the true flag is set, call the 'if' function.      * If the true flag is clear, and "else" was found on the command      * line, then call the 'else' function...      */     if (true)         iffunc(iftag);     else if (if_else)         elsefunc(elsetag);     return(CMD_SUCCESS); } 
image from book
 

Finally, based on the setting of the true flag and the content of the iffunc and elsefunc pointers, the conditional action is performed (Listing 8.9). All in all, you get an amazing amount of script functionality from a surprisingly small, simple piece of code. Refer to the CD for command functions for read , item , sleep , echo , and other script- related commands.



Embedded Systems Firmware Demystified
Embedded Systems Firmware Demystified (With CD-ROM)
ISBN: 1578200997
EAN: 2147483647
Year: 2002
Pages: 118
Authors: Ed Sutter

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net