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 }