URI: 
       tcmd.c - ltk - Socket-based GUI for X11 (WIP)
  HTML git clone git://lumidify.org/ltk.git (fast, but not encrypted)
  HTML git clone https://lumidify.org/git/ltk.git (encrypted, but very slow)
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tcmd.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 }