cmd.c (4229B)
1 #include "graphics.h" 2 #include "surface_cache.h" 3 #include "util.h" 4 #include "cmd.h" 5 #include "memory.h" 6 7 int 8 ltk_parse_cmd( 9 ltk_window *window, ltk_cmd_token *tokens, size_t num_tokens, 10 ltk_cmdarg_parseinfo *parseinfo, size_t num_arg, ltk_error *err) { 11 const char *errstr = NULL; 12 if (num_tokens > num_arg || (num_tokens < num_arg && !parseinfo[num_tokens].optional)) { 13 err->type = ERR_INVALID_NUMBER_OF_ARGUMENTS; 14 err->arg = -1; 15 return 1; 16 } 17 size_t i = 0; 18 for (; i < num_tokens; i++) { 19 if (parseinfo[i].type != CMDARG_DATA && tokens[i].contains_nul) { 20 err->type = ERR_INVALID_ARGUMENT; 21 err->arg = i; 22 goto error; 23 } 24 switch (parseinfo[i].type) { 25 case CMDARG_INT: 26 parseinfo[i].val.i = ltk_strtonum(tokens[i].text, parseinfo[i].min, parseinfo[i].max, &errstr); 27 if (errstr) { 28 err->type = ERR_INVALID_ARGUMENT; 29 err->arg = i; 30 goto error; 31 } 32 parseinfo[i].initialized = 1; 33 break; 34 case CMDARG_STICKY: 35 parseinfo[i].val.sticky = LTK_STICKY_NONE; 36 for (const char *c = tokens[i].text; *c != '\0'; c++) { 37 switch (*c) { 38 case 't': 39 parseinfo[i].val.sticky |= LTK_STICKY_TOP; 40 break; 41 case 'b': 42 parseinfo[i].val.sticky |= LTK_STICKY_BOTTOM; 43 break; 44 case 'r': 45 parseinfo[i].val.sticky |= LTK_STICKY_RIGHT; 46 break; 47 case 'l': 48 parseinfo[i].val.sticky |= LTK_STICKY_LEFT; 49 break; 50 case 'w': 51 parseinfo[i].val.sticky |= LTK_STICKY_SHRINK_WIDTH; 52 break; 53 case 'h': 54 parseinfo[i].val.sticky |= LTK_STICKY_SHRINK_HEIGHT; 55 break; 56 case 'p': 57 parseinfo[i].val.sticky |= LTK_STICKY_PRESERVE_ASPECT_RATIO; 58 break; 59 default: 60 err->type = ERR_INVALID_ARGUMENT; 61 err->arg = i; 62 goto error; 63 } 64 } 65 parseinfo[i].initialized = 1; 66 break; 67 case CMDARG_WIDGET: 68 parseinfo[i].val.widget = ltk_get_widget(tokens[i].text, parseinfo[i].widget_type, err); 69 if (!parseinfo[i].val.widget) { 70 err->arg = i; 71 goto error; 72 } 73 parseinfo[i].initialized = 1; 74 break; 75 case CMDARG_STRING: 76 parseinfo[i].val.str = tokens[i].text; 77 parseinfo[i].initialized = 1; 78 break; 79 case CMDARG_DATA: 80 parseinfo[i].val.data = tokens[i].text; 81 parseinfo[i].initialized = 1; 82 parseinfo[i].len = tokens[i].len; 83 break; 84 case CMDARG_COLOR: 85 if (ltk_color_create(window->renderdata, tokens[i].text, &parseinfo[i].val.color)) { 86 /* FIXME: this could fail even if the argument is fine */ 87 err->type = ERR_INVALID_ARGUMENT; 88 err->arg = i; 89 goto error; 90 } 91 parseinfo[i].initialized = 1; 92 break; 93 case CMDARG_BOOL: 94 if (strcmp(tokens[i].text, "true") == 0) { 95 parseinfo[i].val.b = 1; 96 } else if (strcmp(tokens[i].text, "false") == 0) { 97 parseinfo[i].val.b = 0; 98 } else { 99 err->type = ERR_INVALID_ARGUMENT; 100 err->arg = i; 101 goto error; 102 } 103 parseinfo[i].initialized = 1; 104 break; 105 case CMDARG_ORIENTATION: 106 if (strcmp(tokens[i].text, "horizontal") == 0) { 107 parseinfo[i].val.orient = LTK_HORIZONTAL; 108 } else if (strcmp(tokens[i].text, "vertical") == 0) { 109 parseinfo[i].val.orient = LTK_VERTICAL; 110 } else { 111 err->type = ERR_INVALID_ARGUMENT; 112 err->arg = i; 113 goto error; 114 } 115 parseinfo[i].initialized = 1; 116 break; 117 case CMDARG_BORDERSIDES: 118 parseinfo[i].val.border = LTK_BORDER_NONE; 119 for (const char *c = tokens[i].text; *c != '\0'; c++) { 120 switch (*c) { 121 case 't': 122 parseinfo[i].val.border |= LTK_BORDER_TOP; 123 break; 124 case 'b': 125 parseinfo[i].val.border |= LTK_BORDER_BOTTOM; 126 break; 127 case 'l': 128 parseinfo[i].val.border |= LTK_BORDER_LEFT; 129 break; 130 case 'r': 131 parseinfo[i].val.border |= LTK_BORDER_RIGHT; 132 break; 133 default: 134 err->type = ERR_INVALID_ARGUMENT; 135 err->arg = i; 136 goto error; 137 } 138 } 139 parseinfo[i].initialized = 1; 140 break; 141 case CMDARG_IGNORE: 142 parseinfo[i].initialized = 1; 143 break; 144 default: 145 ltk_fatal("Invalid command argument type. This should not happen.\n"); 146 /* TODO: ltk_assert(0); */ 147 } 148 } 149 for (; i < num_arg; i++) { 150 parseinfo[i].initialized = 0; 151 } 152 return 0; 153 error: 154 for (; i-- > 0;) { 155 if (parseinfo[i].type == CMDARG_COLOR) { 156 ltk_color_destroy(window->renderdata, &parseinfo[i].val.color); 157 } 158 } 159 return 1; 160 }