source: cmd.c @ 52f3507

barnowl_perlaimdebianowlrelease-1.10release-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 52f3507 was f1e629d, checked in by Erik Nygren <nygren@mit.edu>, 21 years ago
New API for perl message formatting functions. Legacy variables are still supported for owl::format_msg and owl::receive_msg, but these functions are now also passed an owl::Message object which contains methods for accessing the contents of the message. See perlwrap.pm (and docs TBD) for the available methods. *** WARNING: The exact API for owl::Message has *** not yet stabilized. Added "style" command for creating new styles. Usage: style <name> perl <function_name> Added support for "show styles". Changed global style table from list to dictionary. Changed AIM password prompt from "Password:" to "AIM Password:". Messages are reformatted after a window resize to allow styles to take into account the width of the window. When perl throws an error, the message is put in the msgwin if possible. Added perl functions for: owl::getcurmsg() -- returns an owl::Message object for the active message in the current view. owl::getnumcols() -- returns the column width of the window owl::zephyr_getrealm() -- returns the zephyr realm owl::zephyr_getsender() -- returns the zephyr sender Made owl::COMMAND("foo"); be syntactic sugar for owl::command("COMMAND foo"); *** Is this a good or bad idea? *** This feature may be taken out before release. Added perlwrap.pm to contain perl code to be compiled into the binary. This is transformed into perlwrap.c by encapsulate.pl. Renamed readconfig.c to perlconfig.c and changed variables accordingly. Minor bugfixes in cmd.c and commands.c
  • Property mode set to 100644
File size: 7.7 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <unistd.h>
5#include "owl.h"
6
7static const char fileIdent[] = "$Id$";
8
9extern owl_cmd commands_to_init[];
10
11/**************************************************************************/
12/***************************** COMMAND DICT *******************************/
13/**************************************************************************/
14
15int owl_cmddict_setup(owl_cmddict *cd) {
16  if (0 != owl_cmddict_init(cd)) return(-1);
17  if (0 != owl_cmddict_add_from_list(cd, commands_to_init)) return(-1);
18  return(0);
19}
20
21int owl_cmddict_init(owl_cmddict *cd) {
22  if (owl_dict_create(cd)) return(-1);
23  return(0);
24}
25
26/* for bulk initialization at startup */
27int owl_cmddict_add_from_list(owl_cmddict *cd, owl_cmd *cmds) {
28  owl_cmd *cur, *cmd;
29  for (cur = cmds; cur->name != NULL; cur++) { 
30    cmd = owl_malloc(sizeof(owl_cmd));
31    owl_cmd_create_from_template(cmd, cur);
32    owl_dict_insert_element(cd, cmd->name, (void*)cmd, NULL);
33  }
34  return 0;
35}
36
37/* free the list with owl_cmddict_namelist_free */
38void owl_cmddict_get_names(owl_cmddict *d, owl_list *l) {
39  owl_dict_get_keys(d, l);
40}
41
42owl_cmd *owl_cmddict_find(owl_cmddict *d, char *name) {
43  return (owl_cmd*)owl_dict_find_element(d, name);
44}
45
46void owl_cmddict_namelist_free(owl_list *l) {
47  owl_list_free_all(l, owl_free);
48}
49
50/* creates a new command alias */
51int owl_cmddict_add_alias(owl_cmddict *cd, char *alias_from, char *alias_to) {
52  owl_cmd *cmd;
53  cmd = owl_malloc(sizeof(owl_cmd));
54  owl_cmd_create_alias(cmd, alias_from, alias_to);
55  owl_dict_insert_element(cd, cmd->name, (void*)cmd, (void(*)(void*))owl_cmd_free);   
56  return(0);
57}
58
59char *owl_cmddict_execute(owl_cmddict *cd, owl_context *ctx, char *cmdbuff) {
60  char **argv;
61  int argc;
62  char *tmpbuff;
63  char *retval = NULL;
64  owl_cmd *cmd;
65
66  tmpbuff=strdup(cmdbuff);
67  argv=owl_parseline(tmpbuff, &argc);
68  if (argc < 0) {
69    owl_free(tmpbuff);
70    sepbar(NULL);
71    owl_function_makemsg("Unbalanced quotes");
72    return NULL;
73  } 
74 
75  if (argc < 1) return(NULL);
76
77  if (!strcmp(argv[0], "")) {
78  } else if (NULL != (cmd = (owl_cmd*)owl_dict_find_element(cd, argv[0]))) {
79    retval = owl_cmd_execute(cmd, cd, ctx, argc, argv, cmdbuff);
80  } else {
81    owl_function_makemsg("Unknown command '%s'.", cmdbuff);
82  }
83  owl_parsefree(argv, argc);
84  owl_free(tmpbuff);
85  sepbar(NULL);
86  return retval;
87}
88
89/*********************************************************************/
90/***************************** COMMAND *******************************/
91/*********************************************************************/
92
93/* sets up a new command based on a template, copying strings */
94int owl_cmd_create_from_template(owl_cmd *cmd, owl_cmd *templ) {
95  *cmd = *templ;
96  if (!templ->name) return(-1);
97  cmd->name = owl_strdup(templ->name);
98  if (templ->summary)     cmd->summary     = owl_strdup(templ->summary);
99  if (templ->usage)       cmd->usage       = owl_strdup(templ->usage);
100  if (templ->description) cmd->description = owl_strdup(templ->description);
101  if (templ->cmd_aliased_to) cmd->cmd_aliased_to = owl_strdup(templ->cmd_aliased_to);
102  return(0);
103}
104
105int owl_cmd_create_alias(owl_cmd *cmd, char *name, char *aliased_to) {
106  memset(cmd, 0, sizeof(owl_cmd));
107  cmd->name = owl_strdup(name);
108  cmd->cmd_aliased_to = owl_strdup(aliased_to);
109  cmd->summary = owl_malloc(strlen(aliased_to)+strlen(OWL_CMD_ALIAS_SUMMARY_PREFIX)+2);
110  strcpy(cmd->summary, OWL_CMD_ALIAS_SUMMARY_PREFIX);
111  strcat(cmd->summary, aliased_to);
112  return(0);
113}
114
115void owl_cmd_free(owl_cmd *cmd) {
116  if (cmd->name) owl_free(cmd->name);
117  if (cmd->summary) owl_free(cmd->summary);
118  if (cmd->usage) owl_free(cmd->usage);
119  if (cmd->description) owl_free(cmd->description);
120}
121
122int owl_cmd_is_context_valid(owl_cmd *cmd, owl_context *ctx) { 
123  if (owl_context_matches(ctx, cmd->validctx)) return 1;
124  else return 0;
125}
126
127char *owl_cmd_execute(owl_cmd *cmd, owl_cmddict *cd, owl_context *ctx, int argc, char **argv, char *cmdbuff) {
128  static int alias_recurse_depth = 0;
129  int ival=0;
130  char *cmdbuffargs, *newcmd, *rv=NULL;
131
132  if (argc < 1) return(NULL);
133
134  /* Recurse if this is an alias */
135  if (cmd->cmd_aliased_to) {
136    if (alias_recurse_depth++ > 50) {
137      owl_function_makemsg("Alias loop detected for '%s'.", cmdbuff);
138    } else {
139      cmdbuffargs = skiptokens(cmdbuff, 1);
140      newcmd = owl_malloc(strlen(cmd->cmd_aliased_to)+strlen(cmdbuffargs)+2);
141      strcpy(newcmd, cmd->cmd_aliased_to);
142      strcat(newcmd, " ");
143      strcat(newcmd, cmdbuffargs);
144      rv = owl_function_command(newcmd);
145      owl_free(newcmd);
146    } 
147    alias_recurse_depth--;
148    return rv;
149  }
150
151  /* Do validation and conversions */
152  if (cmd->cmd_ctxargs_fn || cmd->cmd_ctxv_fn || cmd->cmd_ctxi_fn) {
153    if (!owl_cmd_is_context_valid(cmd, ctx)) {
154      owl_function_makemsg("Invalid context for command '%s'.", cmdbuff);
155      return NULL;
156    }
157  }
158
159  if ((argc != 1) && (cmd->cmd_v_fn || cmd->cmd_ctxv_fn)) {
160    owl_function_makemsg("Wrong number of arguments for %s command.", argv[0]);
161    return NULL;
162  }
163
164  if (cmd->cmd_i_fn || cmd->cmd_ctxi_fn) {
165      char *ep = "x";
166      if (argc != 2) {
167        owl_function_makemsg("Wrong number of arguments for %s command.", argv[0]);
168        return NULL;
169      }
170      ival = strtol(argv[1], &ep, 10);
171      if (*ep || ep==argv[1]) {
172        owl_function_makemsg("Invalid argument '%s' for %s command.", argv[1], argv[0]);
173        return(NULL);
174      }
175  }
176
177  if (cmd->cmd_args_fn) {
178    return cmd->cmd_args_fn(argc, argv, cmdbuff);
179  } else if (cmd->cmd_v_fn) {   
180    cmd->cmd_v_fn();
181  } else if (cmd->cmd_i_fn) {
182    cmd->cmd_i_fn(ival);
183  } else if (cmd->cmd_ctxargs_fn) {
184    return cmd->cmd_ctxargs_fn(owl_context_get_data(ctx), argc, argv, cmdbuff);
185  } else if (cmd->cmd_ctxv_fn) {   
186    cmd->cmd_ctxv_fn(owl_context_get_data(ctx));
187  } else if (cmd->cmd_ctxi_fn) {
188    cmd->cmd_ctxi_fn(owl_context_get_data(ctx), ival);
189  }
190
191  return NULL;
192}
193
194/* returns a reference */
195char *owl_cmd_get_summary(owl_cmd *cmd) {
196  return cmd->summary;
197}
198
199/* returns a summary line describing this keymap.  the caller must free. */
200char *owl_cmd_describe(owl_cmd *cmd) {
201  char *s;
202  int slen;
203  if (!cmd || !cmd->name || !cmd->summary) return NULL;
204  slen = strlen(cmd->name)+strlen(cmd->summary)+30;
205  s = owl_malloc(slen);
206  snprintf(s, slen-1, "%-25s - %s", cmd->name, cmd->summary);
207  return s;
208}
209
210
211
212void owl_cmd_get_help(owl_cmddict *d, char *name, owl_fmtext *fm) {
213  char *indent, *s;
214  owl_cmd *cmd;
215
216  if (!name || (cmd = owl_dict_find_element(d, name)) == NULL) {
217    owl_fmtext_append_bold(fm, "OWL HELP\n\n");
218    owl_fmtext_append_normal(fm, "No such command...\n");
219    return;
220  }
221
222  owl_fmtext_append_bold(fm, "OWL HELP\n\n");
223  owl_fmtext_append_bold(fm, "NAME\n\n");
224  owl_fmtext_append_normal(fm, OWL_TABSTR);
225  owl_fmtext_append_normal(fm, cmd->name);
226
227  if (cmd->summary && *cmd->summary) {
228    owl_fmtext_append_normal(fm, " - ");
229    owl_fmtext_append_normal(fm, cmd->summary);
230  }
231  owl_fmtext_append_normal(fm, "\n");
232
233  if (cmd->usage && *cmd->usage) {
234    s = cmd->usage;
235    indent = owl_malloc(strlen(s)+(owl_text_num_lines(s)+3)*OWL_TAB+1);
236    owl_text_indent(indent, s, OWL_TAB);
237    owl_fmtext_append_bold(fm, "\nSYNOPSIS\n");
238    owl_fmtext_append_normal(fm, indent);
239    owl_fmtext_append_normal(fm, "\n");
240    owl_free(indent);
241  } else {
242    owl_fmtext_append_bold(fm, "\nSYNOPSIS\n");
243    owl_fmtext_append_normal(fm, OWL_TABSTR);
244    owl_fmtext_append_normal(fm, cmd->name);
245    owl_fmtext_append_normal(fm, "\n");
246  }
247
248  if (cmd->description && *cmd->description) {
249    s = cmd->description;
250    indent = owl_malloc(strlen(s)+(owl_text_num_lines(s)+3)*OWL_TAB+1);
251    owl_text_indent(indent, s, OWL_TAB);
252    owl_fmtext_append_bold(fm, "\nDESCRIPTION\n");
253    owl_fmtext_append_normal(fm, indent);
254    owl_fmtext_append_normal(fm, "\n");
255    owl_free(indent);
256  }
257
258  owl_fmtext_append_normal(fm, "\n\n"); 
259}
Note: See TracBrowser for help on using the repository browser.