Ken Yourek / ucmd

Dependents:   nucleo_ucmd_helloworld

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ucCmdParser.c Source File

ucCmdParser.c

00001 #include <string.h>
00002 #include "ucmd_internal.h"
00003 
00004 static ucBool is_char_white_space(char c) {
00005     /* The native isspace function in ctype.h was giving some weird behavior in the uVision simulator. */
00006     return (((c >= 0x09) && (c <= 0x0D)) || (c == 0x020)) ? ucBool_TRUE : ucBool_FALSE;
00007 }
00008 
00009 static char is_char_a_quote(char c) {
00010     if (c == '"') return '"';
00011     if (c == '\'') return '\'';
00012     return 0;
00013 }
00014 
00015 static void remove_cmd_char(char *cmd, int index) {
00016     if (NULL == cmd) return;
00017     while (cmd[index] != uc_cmd_terminator) {
00018         cmd[index] = cmd[index + 1];
00019         index++;
00020     }
00021 }
00022 
00023 static ucCmdTok *parse(ucCmdParser *p, char *cmd) {
00024     int i, j, len;
00025     char quote, current_quote;
00026 
00027     if (NULL == cmd) return NULL;
00028 
00029     /* get the length of the whole command */
00030     len = strlen(cmd);
00031 
00032     /* replace any command-terminating characters in the string with a space */
00033     for (i = 0; i < len; i++) {
00034         if (cmd[i] == uc_cmd_terminator) {
00035             cmd[i] = ' ';
00036         }
00037     }
00038 
00039     /* append a command terminator */
00040     cmd[len + 1] = uc_cmd_terminator;
00041 
00042     /* loop through each character in the command */
00043     i = 0;
00044     current_quote = 0;
00045     while (cmd[i] != uc_cmd_terminator) {
00046 
00047         /* check if this command character is a quote */
00048         quote = is_char_a_quote(cmd[i]);
00049         if (quote) {
00050 
00051             /* check if this is our current quote */
00052             if (quote == current_quote) {
00053 
00054                 /* remove the quote only if this is
00055                    not an empty quote */
00056                 if ((0 < i) && (current_quote != cmd[i - 1])) {
00057                     cmd[i] = ' ';
00058                 }
00059 
00060                 /* the quoted item is finished */
00061                 current_quote = 0;
00062             }
00063             else {
00064 
00065                 /* check if we're NOT in a quote */
00066                 if (!current_quote) {
00067 
00068                     /* we've started a quote */
00069                     current_quote = quote;
00070 
00071                     /* remove the quote character 
00072                        only if this is not an empty
00073                        quote */
00074                     if (current_quote != cmd[i + 1]) {
00075                         remove_cmd_char(cmd, i);
00076                     }
00077                 }
00078             }
00079         }
00080 
00081         /* check if we're not in a quoted string */
00082         if (!current_quote) {
00083 
00084             /* check if we're in a token separator */
00085             if (is_char_white_space(cmd[i])) {
00086 
00087                 /* separate this token */
00088                 cmd[i] = ucTok_separator;
00089 
00090                 /* remove any remaining white space */
00091                 j = i + 1;
00092                 while (is_char_white_space(cmd[j])) {
00093                     remove_cmd_char(cmd, j);
00094                 }
00095             }
00096         }
00097 
00098         /* go to the next character */
00099         i++;
00100     }
00101 
00102     /* we're done parsing */
00103     return (ucCmdTok*)cmd;
00104 }
00105 
00106 ucCmdTok *ucCmdParser_parse(ucCmdParser *p, char *cmd) {
00107     if (NULL == p) return NULL;
00108     if (NULL == p->parse) return NULL;
00109     return p->parse(p, cmd);
00110 }
00111 
00112 ucCmdParser *ucCmdParser_get_instance(void) {
00113     static ucCmdParser instance;
00114     static ucCmdParser *p = NULL;
00115     if (NULL == p) {
00116         p = &instance;
00117         p->parse = parse;
00118     }
00119     return p;
00120 }
00121