root/src/noit_console_state.c

Revision abfe5861994b2f5d62f789bf196ef636b0ef04fe, 4.8 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 6 years ago)

make the delegate state a first-class citizen and preserve closure for future use. show checks? seriously?

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  */
5
6 #include "noit_defines.h"
7
8 #include "eventer/eventer.h"
9 #include "utils/noit_log.h"
10 #include "utils/noit_hash.h"
11 #include "noit_listener.h"
12 #include "noit_console.h"
13 #include "noit_tokenizer.h"
14
15 cmd_info_t console_command_exit = {
16   "exit", noit_console_state_pop, NULL, NULL
17 };
18
19 static char *
20 noit_console_state_prompt(EditLine *el) {
21   static char *tl = "noit# ";
22   return tl;
23 }
24
25 int
26 noit_console_state_delegate(noit_console_closure_t ncct,
27                             int argc, char **argv,
28                             noit_console_state_t *dstate,
29                             void *closure) {
30   noit_console_state_stack_t tmps = { 0 };
31
32   if(argc == 0) {
33     nc_printf(ncct, "arguments expected\n");
34     /* XXX: noit_console_render_help(dstate); */
35     return -1;
36   }
37   if(!dstate) {
38     nc_printf(ncct, "internal error: no delegate state\n");
39     return -1;
40   }
41   tmps.state = dstate;
42   return _noit_console_state_do(ncct, &tmps, argc, argv);
43 }
44
45 int
46 _noit_console_state_do(noit_console_closure_t ncct,
47                        noit_console_state_stack_t *stack,
48                        int argc, char **argv) {
49   cmd_info_t *cmd;
50
51   if(!argc) {
52     nc_printf(ncct, "arguments expected\n");
53     return -1;
54   }
55   if(!noit_hash_retrieve(&stack->state->cmds,
56                          argv[0], strlen(argv[0]), (void **)&cmd)) {
57     nc_printf(ncct, "No such command: '%s'\n", argv[0]);
58     return -1;
59   }
60   return cmd->func(ncct, argc-1, argv+1, cmd->dstate, cmd->closure);
61 }
62 int
63 noit_console_state_do(noit_console_closure_t ncct, int argc, char **argv) {
64   return _noit_console_state_do(ncct, ncct->state_stack, argc, argv);
65 }
66
67 int cmd_info_comparek(void *akv, void *bv) {
68   char *ak = (char *)akv;
69   cmd_info_t *b = (cmd_info_t *)bv;
70   return strcasecmp(ak, b->name);
71 }
72 int cmd_info_compare(void *av, void *bv) {
73   cmd_info_t *a = (cmd_info_t *)av;
74   cmd_info_t *b = (cmd_info_t *)bv;
75   return strcasecmp(a->name, b->name);
76 }
77
78 int
79 noit_console_state_add_cmd(noit_console_state_t *state,
80                            cmd_info_t *cmd) {
81   return noit_hash_store(&state->cmds, cmd->name, strlen(cmd->name), cmd);
82 }
83
84 cmd_info_t *
85 noit_console_state_get_cmd(noit_console_state_t *state,
86                            const char *name) {
87   cmd_info_t *cmd = NULL;
88   if(noit_hash_retrieve(&state->cmds, name, strlen(name), (void **)&cmd))
89     return cmd;
90   return NULL;
91 }
92
93 noit_console_state_t *
94 noit_console_state_build(console_prompt_func_t promptf, cmd_info_t **clist,
95                          state_free_func_t sfreef) {
96   noit_console_state_t *state;
97   state = calloc(1, sizeof(*state));
98   state->console_prompt_function = promptf;
99   while(*clist) {
100     noit_hash_store(&state->cmds,
101                     (*clist)->name, strlen((*clist)->name),
102                     *clist);
103     clist++;
104   }
105   state->statefree = sfreef;
106   return state;
107 }
108
109 cmd_info_t *NCSCMD(const char *name, console_cmd_func_t func,
110                    noit_console_state_t *dstate, void *closure) {
111   cmd_info_t *cmd;
112   cmd = calloc(1, sizeof(*cmd));
113   cmd->name = strdup(name);
114   cmd->func = func;
115   cmd->dstate = dstate;
116   cmd->closure = closure;
117   return cmd;
118 }
119
120 noit_console_state_t *
121 noit_console_state_initial() {
122   static noit_console_state_t *_top_level_state = NULL;
123   if(!_top_level_state) {
124     static noit_console_state_t *show_state;
125     _top_level_state = calloc(1, sizeof(*_top_level_state));
126     noit_console_state_add_cmd(_top_level_state, &console_command_exit);
127     show_state = calloc(1, sizeof(*show_state));
128     noit_console_state_add_cmd(_top_level_state,
129       NCSCMD("show", noit_console_state_delegate, show_state, NULL));
130   }
131   return _top_level_state;
132 }
133
134 void
135 noit_console_state_push_state(noit_console_closure_t ncct,
136                               noit_console_state_t *state) {
137   noit_console_state_stack_t *stack;
138   stack = calloc(1, sizeof(*stack));
139   stack->last = ncct->state_stack;
140   stack->state = state;
141   ncct->state_stack = stack;
142 }
143
144 int
145 noit_console_state_pop(noit_console_closure_t ncct, int argc, char **argv,
146                        noit_console_state_t *dstate, void *unused) {
147   noit_console_state_stack_t *current;
148
149   if(argc) {
150     nc_printf(ncct, "no arguments allowed to this command.\n");
151     return -1;
152   }
153   if(!ncct->state_stack || !ncct->state_stack->last) {
154     ncct->wants_shutdown = 1;
155     return 0;
156   }
157
158   current = ncct->state_stack;
159   ncct->state_stack = current->last;
160   current->last = NULL;
161   if(current->state->statefree) current->state->statefree(current->state);
162   free(current);
163   noit_console_state_init(ncct);
164   return 0;
165 }
166
167 int
168 noit_console_state_init(noit_console_closure_t ncct) {
169   if(ncct->el) {
170     console_prompt_func_t f;
171     f = ncct->state_stack->state->console_prompt_function;
172     el_set(ncct->el, EL_PROMPT, f ? f : noit_console_state_prompt);
173   }
174   return 0;
175 }
Note: See TracBrowser for help on using the browser.