Ken Yourek / ucmd

Dependents:   nucleo_ucmd_helloworld

Committer:
kyourek
Date:
Mon Oct 12 21:09:07 2015 +0000
Revision:
0:9e2fc73e5a12
Initial commit of the ucmd library for mbed.; https://github.com/kyourek/ucmd

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kyourek 0:9e2fc73e5a12 1 #include <string.h>
kyourek 0:9e2fc73e5a12 2 #include "ucmd_internal.h"
kyourek 0:9e2fc73e5a12 3
kyourek 0:9e2fc73e5a12 4 static ucBool is_char_white_space(char c) {
kyourek 0:9e2fc73e5a12 5 /* The native isspace function in ctype.h was giving some weird behavior in the uVision simulator. */
kyourek 0:9e2fc73e5a12 6 return (((c >= 0x09) && (c <= 0x0D)) || (c == 0x020)) ? ucBool_TRUE : ucBool_FALSE;
kyourek 0:9e2fc73e5a12 7 }
kyourek 0:9e2fc73e5a12 8
kyourek 0:9e2fc73e5a12 9 static char is_char_a_quote(char c) {
kyourek 0:9e2fc73e5a12 10 if (c == '"') return '"';
kyourek 0:9e2fc73e5a12 11 if (c == '\'') return '\'';
kyourek 0:9e2fc73e5a12 12 return 0;
kyourek 0:9e2fc73e5a12 13 }
kyourek 0:9e2fc73e5a12 14
kyourek 0:9e2fc73e5a12 15 static void remove_cmd_char(char *cmd, int index) {
kyourek 0:9e2fc73e5a12 16 if (NULL == cmd) return;
kyourek 0:9e2fc73e5a12 17 while (cmd[index] != uc_cmd_terminator) {
kyourek 0:9e2fc73e5a12 18 cmd[index] = cmd[index + 1];
kyourek 0:9e2fc73e5a12 19 index++;
kyourek 0:9e2fc73e5a12 20 }
kyourek 0:9e2fc73e5a12 21 }
kyourek 0:9e2fc73e5a12 22
kyourek 0:9e2fc73e5a12 23 static ucCmdTok *parse(ucCmdParser *p, char *cmd) {
kyourek 0:9e2fc73e5a12 24 int i, j, len;
kyourek 0:9e2fc73e5a12 25 char quote, current_quote;
kyourek 0:9e2fc73e5a12 26
kyourek 0:9e2fc73e5a12 27 if (NULL == cmd) return NULL;
kyourek 0:9e2fc73e5a12 28
kyourek 0:9e2fc73e5a12 29 /* get the length of the whole command */
kyourek 0:9e2fc73e5a12 30 len = strlen(cmd);
kyourek 0:9e2fc73e5a12 31
kyourek 0:9e2fc73e5a12 32 /* replace any command-terminating characters in the string with a space */
kyourek 0:9e2fc73e5a12 33 for (i = 0; i < len; i++) {
kyourek 0:9e2fc73e5a12 34 if (cmd[i] == uc_cmd_terminator) {
kyourek 0:9e2fc73e5a12 35 cmd[i] = ' ';
kyourek 0:9e2fc73e5a12 36 }
kyourek 0:9e2fc73e5a12 37 }
kyourek 0:9e2fc73e5a12 38
kyourek 0:9e2fc73e5a12 39 /* append a command terminator */
kyourek 0:9e2fc73e5a12 40 cmd[len + 1] = uc_cmd_terminator;
kyourek 0:9e2fc73e5a12 41
kyourek 0:9e2fc73e5a12 42 /* loop through each character in the command */
kyourek 0:9e2fc73e5a12 43 i = 0;
kyourek 0:9e2fc73e5a12 44 current_quote = 0;
kyourek 0:9e2fc73e5a12 45 while (cmd[i] != uc_cmd_terminator) {
kyourek 0:9e2fc73e5a12 46
kyourek 0:9e2fc73e5a12 47 /* check if this command character is a quote */
kyourek 0:9e2fc73e5a12 48 quote = is_char_a_quote(cmd[i]);
kyourek 0:9e2fc73e5a12 49 if (quote) {
kyourek 0:9e2fc73e5a12 50
kyourek 0:9e2fc73e5a12 51 /* check if this is our current quote */
kyourek 0:9e2fc73e5a12 52 if (quote == current_quote) {
kyourek 0:9e2fc73e5a12 53
kyourek 0:9e2fc73e5a12 54 /* remove the quote only if this is
kyourek 0:9e2fc73e5a12 55 not an empty quote */
kyourek 0:9e2fc73e5a12 56 if ((0 < i) && (current_quote != cmd[i - 1])) {
kyourek 0:9e2fc73e5a12 57 cmd[i] = ' ';
kyourek 0:9e2fc73e5a12 58 }
kyourek 0:9e2fc73e5a12 59
kyourek 0:9e2fc73e5a12 60 /* the quoted item is finished */
kyourek 0:9e2fc73e5a12 61 current_quote = 0;
kyourek 0:9e2fc73e5a12 62 }
kyourek 0:9e2fc73e5a12 63 else {
kyourek 0:9e2fc73e5a12 64
kyourek 0:9e2fc73e5a12 65 /* check if we're NOT in a quote */
kyourek 0:9e2fc73e5a12 66 if (!current_quote) {
kyourek 0:9e2fc73e5a12 67
kyourek 0:9e2fc73e5a12 68 /* we've started a quote */
kyourek 0:9e2fc73e5a12 69 current_quote = quote;
kyourek 0:9e2fc73e5a12 70
kyourek 0:9e2fc73e5a12 71 /* remove the quote character
kyourek 0:9e2fc73e5a12 72 only if this is not an empty
kyourek 0:9e2fc73e5a12 73 quote */
kyourek 0:9e2fc73e5a12 74 if (current_quote != cmd[i + 1]) {
kyourek 0:9e2fc73e5a12 75 remove_cmd_char(cmd, i);
kyourek 0:9e2fc73e5a12 76 }
kyourek 0:9e2fc73e5a12 77 }
kyourek 0:9e2fc73e5a12 78 }
kyourek 0:9e2fc73e5a12 79 }
kyourek 0:9e2fc73e5a12 80
kyourek 0:9e2fc73e5a12 81 /* check if we're not in a quoted string */
kyourek 0:9e2fc73e5a12 82 if (!current_quote) {
kyourek 0:9e2fc73e5a12 83
kyourek 0:9e2fc73e5a12 84 /* check if we're in a token separator */
kyourek 0:9e2fc73e5a12 85 if (is_char_white_space(cmd[i])) {
kyourek 0:9e2fc73e5a12 86
kyourek 0:9e2fc73e5a12 87 /* separate this token */
kyourek 0:9e2fc73e5a12 88 cmd[i] = ucTok_separator;
kyourek 0:9e2fc73e5a12 89
kyourek 0:9e2fc73e5a12 90 /* remove any remaining white space */
kyourek 0:9e2fc73e5a12 91 j = i + 1;
kyourek 0:9e2fc73e5a12 92 while (is_char_white_space(cmd[j])) {
kyourek 0:9e2fc73e5a12 93 remove_cmd_char(cmd, j);
kyourek 0:9e2fc73e5a12 94 }
kyourek 0:9e2fc73e5a12 95 }
kyourek 0:9e2fc73e5a12 96 }
kyourek 0:9e2fc73e5a12 97
kyourek 0:9e2fc73e5a12 98 /* go to the next character */
kyourek 0:9e2fc73e5a12 99 i++;
kyourek 0:9e2fc73e5a12 100 }
kyourek 0:9e2fc73e5a12 101
kyourek 0:9e2fc73e5a12 102 /* we're done parsing */
kyourek 0:9e2fc73e5a12 103 return (ucCmdTok*)cmd;
kyourek 0:9e2fc73e5a12 104 }
kyourek 0:9e2fc73e5a12 105
kyourek 0:9e2fc73e5a12 106 ucCmdTok *ucCmdParser_parse(ucCmdParser *p, char *cmd) {
kyourek 0:9e2fc73e5a12 107 if (NULL == p) return NULL;
kyourek 0:9e2fc73e5a12 108 if (NULL == p->parse) return NULL;
kyourek 0:9e2fc73e5a12 109 return p->parse(p, cmd);
kyourek 0:9e2fc73e5a12 110 }
kyourek 0:9e2fc73e5a12 111
kyourek 0:9e2fc73e5a12 112 ucCmdParser *ucCmdParser_get_instance(void) {
kyourek 0:9e2fc73e5a12 113 static ucCmdParser instance;
kyourek 0:9e2fc73e5a12 114 static ucCmdParser *p = NULL;
kyourek 0:9e2fc73e5a12 115 if (NULL == p) {
kyourek 0:9e2fc73e5a12 116 p = &instance;
kyourek 0:9e2fc73e5a12 117 p->parse = parse;
kyourek 0:9e2fc73e5a12 118 }
kyourek 0:9e2fc73e5a12 119 return p;
kyourek 0:9e2fc73e5a12 120 }
kyourek 0:9e2fc73e5a12 121