URI: 
       tcmd.h - 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.h (4170B)
       ---
            1 #ifndef LTK_CMD_H
            2 #define LTK_CMD_H
            3 
            4 #include "ltk.h"
            5 
            6 typedef enum {
            7         CMDARG_IGNORE,
            8         CMDARG_STRING, /* nul-terminated string */
            9         CMDARG_DATA,   /* also char*, but may contain nul */
           10         CMDARG_COLOR,
           11         CMDARG_INT,
           12         CMDARG_BOOL,
           13         CMDARG_BORDERSIDES,
           14         CMDARG_STICKY,
           15         CMDARG_WIDGET,
           16         CMDARG_ORIENTATION
           17 } ltk_cmdarg_datatype;
           18 
           19 /* color needs to be destroyed by cmd handling function if it is not needed anymore */
           20 /* str must *not* be freed because it is a pointer to the original argument
           21    -> it must be copied if it needs to be kept around */
           22 typedef struct {
           23         ltk_cmdarg_datatype type;
           24         /* Note: Bool and int are both integers, but they are
           25            separate just to make it a bit clearer (same goes for str/data) */
           26         union {
           27                 char *str;
           28                 char *data;
           29                 ltk_color color;
           30                 int i;
           31                 int b;
           32                 ltk_border_sides border;
           33                 ltk_sticky_mask sticky;
           34                 ltk_orientation orient;
           35                 ltk_widget *widget;
           36         } val;
           37         size_t len; /* only for data */
           38         int min, max; /* only for integers */ /* FIXME: which integer type is sensible here? */
           39         ltk_widget_type widget_type; /* only for widgets */
           40         int optional;
           41         int initialized;
           42 } ltk_cmdarg_parseinfo;
           43 
           44 /* Returns 1 on error, 0 on success */
           45 /* All optional arguments must be in one block at the end */
           46 int ltk_parse_cmd(
           47     ltk_window *window, ltk_cmd_token *tokens, size_t num_tokens,
           48     ltk_cmdarg_parseinfo *parseinfo, size_t num_arg, ltk_error *err
           49 );
           50 
           51 #define GEN_CMD_HELPERS_PROTO(func_name)                                                                        \
           52 int func_name(ltk_window *window, ltk_cmd_token *tokens, size_t num_tokens, ltk_error *err);
           53 
           54 
           55 #define GEN_CMD_HELPERS(func_name, widget_type, widget_typename, array_name, entry_type)                        \
           56 /* FIXME: maybe just get rid of this and rely on array already being sorted? */                                        \
           57 static int array_name##_sorted = 0;                                                                                \
           58                                                                                                                 \
           59 static int                                                                                                        \
           60 array_name##_search_helper(const void *keyv, const void *entryv) {                                                \
           61         const char *key = (const char *)keyv;                                                                        \
           62         entry_type *entry = (entry_type *)entryv;                                                                \
           63         return strcmp(key, entry->name);                                                                        \
           64 }                                                                                                                \
           65                                                                                                                 \
           66 static int                                                                                                        \
           67 array_name##_sort_helper(const void *entry1v, const void *entry2v) {                                                \
           68         entry_type *entry1 = (entry_type *)entry1v;                                                                \
           69         entry_type *entry2 = (entry_type *)entry2v;                                                                \
           70         return strcmp(entry1->name, entry2->name);                                                                \
           71 }                                                                                                                \
           72                                                                                                                 \
           73 int                                                                                                                \
           74 func_name(                                                                                                        \
           75     ltk_window *window,                                                                                                \
           76     ltk_cmd_token *tokens,                                                                                        \
           77     size_t num_tokens,                                                                                                \
           78     ltk_error *err) {                                                                                                \
           79         if (num_tokens < 3) {                                                                                        \
           80                 err->type = ERR_INVALID_NUMBER_OF_ARGUMENTS;                                                        \
           81                 err->arg = -1;                                                                                        \
           82                 return 1;                                                                                        \
           83         }                                                                                                        \
           84         /* just in case */                                                                                        \
           85         if (!array_name##_sorted) {                                                                                \
           86                 qsort(                                                                                                \
           87                     array_name, LENGTH(array_name),                                                                \
           88                     sizeof(array_name[0]), &array_name##_sort_helper);                                                \
           89                 array_name##_sorted = 1;                                                                        \
           90         }                                                                                                        \
           91         if (tokens[1].contains_nul) {                                                                                \
           92                 err->type = ERR_INVALID_ARGUMENT;                                                                \
           93                 err->arg = 1;                                                                                        \
           94                 return 1;                                                                                        \
           95         } else if (tokens[2].contains_nul) {                                                                        \
           96                 err->type = ERR_INVALID_ARGUMENT;                                                                \
           97                 err->arg = 2;                                                                                        \
           98                 return 1;                                                                                        \
           99         }                                                                                                        \
          100         entry_type *e = bsearch(                                                                                \
          101             tokens[2].text, array_name, LENGTH(array_name),                                                        \
          102             sizeof(array_name[0]), &array_name##_search_helper                                                        \
          103         );                                                                                                        \
          104         if (!e) {                                                                                                \
          105                 err->type = ERR_INVALID_COMMAND;                                                                \
          106                 err->arg = -1;                                                                                        \
          107                 return 1;                                                                                        \
          108         }                                                                                                        \
          109         if (e->needs_all) {                                                                                        \
          110                 return e->func(window, NULL, tokens, num_tokens, err);                                                \
          111         } else {                                                                                                \
          112                 widget_typename *widget = (widget_typename *)ltk_get_widget(tokens[1].text, widget_type, err);        \
          113                 if (!widget) {                                                                                        \
          114                         err->arg = 1;                                                                                \
          115                         return 1;                                                                                \
          116                 }                                                                                                \
          117                 int ret = e->func(window, widget, tokens + 3, num_tokens - 3, err);                                \
          118                 if (ret && err->arg >= 0)                                                                        \
          119                         err->arg += 3;                                                                                \
          120                 return ret;                                                                                        \
          121         }                                                                                                        \
          122         return 0; /* Well, I guess this is impossible anyways... */                                                \
          123 }
          124 
          125 #endif /* LTK_CMD_H */