Re: [PATCH] emacs: wash: make word-wrap bound message width
[notmuch-archives.git] / 50 / 5a99e47877f45a290407985ec34196a4c5b41b
1 Return-Path: <bremner@unb.ca>\r
2 X-Original-To: notmuch@notmuchmail.org\r
3 Delivered-To: notmuch@notmuchmail.org\r
4 Received: from localhost (localhost [127.0.0.1])\r
5         by olra.theworths.org (Postfix) with ESMTP id B4EFC429E31\r
6         for <notmuch@notmuchmail.org>; Thu,  1 Dec 2011 22:42:14 -0800 (PST)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: -2.3\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=-2.3 tagged_above=-999 required=5\r
12         tests=[RCVD_IN_DNSWL_MED=-2.3] autolearn=disabled\r
13 Received: from olra.theworths.org ([127.0.0.1])\r
14         by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
15         with ESMTP id xO-yl8ov3Bok for <notmuch@notmuchmail.org>;\r
16         Thu,  1 Dec 2011 22:42:14 -0800 (PST)\r
17 Received: from tempo.its.unb.ca (tempo.its.unb.ca [131.202.1.21])\r
18         (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))\r
19         (No client certificate requested)\r
20         by olra.theworths.org (Postfix) with ESMTPS id 5A7CF429E38\r
21         for <notmuch@notmuchmail.org>; Thu,  1 Dec 2011 22:42:13 -0800 (PST)\r
22 Received: from rocinante.cs.unb.ca (m3.kereda.com [207.194.238.3] (may be\r
23         forged)) (authenticated bits=0)\r
24         by tempo.its.unb.ca (8.13.8/8.13.8) with ESMTP id pB26g5lX010488\r
25         (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO);\r
26         Fri, 2 Dec 2011 02:42:07 -0400\r
27 Received: from bremner by rocinante.cs.unb.ca with local (Exim 4.76)\r
28         (envelope-from <bremner@tesseract.cs.unb.ca>)\r
29         id 1RWMou-00038i-Ob; Thu, 01 Dec 2011 22:42:04 -0800\r
30 From: David Bremner <david@tethera.net>\r
31 To: notmuch@notmuchmail.org\r
32 Subject: [RFC Patch v2 1/3] notmuch-opts.[ch]: new argument parsing framework\r
33         for notmuch.\r
34 Date: Thu,  1 Dec 2011 22:41:52 -0800\r
35 Message-Id: <1322808114-11854-1-git-send-email-david@tethera.net>\r
36 X-Mailer: git-send-email 1.7.5.4\r
37 In-Reply-To: <1322702130-26068-3-git-send-email-bremner@debian.org>\r
38 References: <1322702130-26068-3-git-send-email-bremner@debian.org>\r
39 Cc: David Bremner <bremner@debian.org>\r
40 X-BeenThere: notmuch@notmuchmail.org\r
41 X-Mailman-Version: 2.1.13\r
42 Precedence: list\r
43 List-Id: "Use and development of the notmuch mail system."\r
44         <notmuch.notmuchmail.org>\r
45 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
46         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
47 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
48 List-Post: <mailto:notmuch@notmuchmail.org>\r
49 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
50 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
51         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
52 X-List-Received-Date: Fri, 02 Dec 2011 06:42:14 -0000\r
53 \r
54 From: David Bremner <bremner@debian.org>\r
55 \r
56 As we noticed when Jani kindly converted things to getopt_long, much\r
57 of the work in argument parsing in notmuch is due to the the key-value\r
58 style arguments like --format=(raw|json|text).\r
59 \r
60 In this version I implement Austin Clements' suggestion of basing the\r
61 main API on taking pointers to output variables.\r
62 ---\r
63  Makefile.local |    1 +\r
64  notmuch-opts.c |  120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r
65  notmuch-opts.h |   50 +++++++++++++++++++++++\r
66  3 files changed, 171 insertions(+), 0 deletions(-)\r
67  create mode 100644 notmuch-opts.c\r
68  create mode 100644 notmuch-opts.h\r
69 \r
70 diff --git a/Makefile.local b/Makefile.local\r
71 index c94402b..6606be8 100644\r
72 --- a/Makefile.local\r
73 +++ b/Makefile.local\r
74 @@ -303,6 +303,7 @@ notmuch_client_srcs =               \\r
75         notmuch-count.c         \\r
76         notmuch-dump.c          \\r
77         notmuch-new.c           \\r
78 +       notmuch-opts.c          \\r
79         notmuch-reply.c         \\r
80         notmuch-restore.c       \\r
81         notmuch-search.c        \\r
82 diff --git a/notmuch-opts.c b/notmuch-opts.c\r
83 new file mode 100644\r
84 index 0000000..a8c5223\r
85 --- /dev/null\r
86 +++ b/notmuch-opts.c\r
87 @@ -0,0 +1,120 @@\r
88 +#include <assert.h>\r
89 +#include <string.h>\r
90 +#include <stdio.h>\r
91 +#include "error_util.h"\r
92 +#include "notmuch-opts.h"\r
93 +\r
94 +/*\r
95 +  Search the list of keywords for a given argument, assigning the\r
96 +  output variable to the corresponding value.  Return FALSE if nothing\r
97 +  matches.\r
98 +*/\r
99 +\r
100 +static notmuch_bool_t\r
101 +_process_keyword_arg (const notmuch_opt_desc_t *arg_desc, const char *arg_str) {\r
102 +\r
103 +    if (arg_str[0] != ':' && arg_str[0] != '=') {\r
104 +       return FALSE;\r
105 +    }\r
106 +\r
107 +    /* skip delimiter */\r
108 +    arg_str++;\r
109 +\r
110 +    notmuch_keyword_t *keywords = arg_desc->keywords;\r
111 +\r
112 +    while (keywords->name) {\r
113 +       if (strcmp (arg_str, keywords->name) == 0) {\r
114 +           if (arg_desc->output_var) {\r
115 +               *((int *)arg_desc->output_var) = keywords->value;\r
116 +           }\r
117 +           return TRUE;\r
118 +       }\r
119 +       keywords++;\r
120 +    }\r
121 +    return FALSE;\r
122 +}\r
123 +\r
124 +/*\r
125 +   Search for the {pos_arg_index}th position argument, return FALSE if\r
126 +   that does not exist.\r
127 +*/\r
128 +\r
129 +notmuch_bool_t\r
130 +parse_position_arg (const char *arg_str, int pos_arg_index, const notmuch_opt_desc_t *arg_desc) {\r
131 +\r
132 +    int pos_arg_counter = 0;\r
133 +    while (arg_desc->name){\r
134 +       if (arg_desc->opt_type == NOTMUCH_OPT_POSITION) {\r
135 +           if (pos_arg_counter == pos_arg_index) {\r
136 +               if (arg_desc->output_var) {\r
137 +                   *((const char **)arg_desc->output_var) = arg_str;\r
138 +               }\r
139 +               return TRUE;\r
140 +           }\r
141 +           pos_arg_counter++;\r
142 +       }\r
143 +       arg_desc++;\r
144 +    }\r
145 +    return FALSE;\r
146 +}\r
147 +\r
148 +notmuch_opt_result_t\r
149 +parse_option (const char *arg,\r
150 +             const notmuch_opt_desc_t *options){\r
151 +\r
152 +    assert(arg);\r
153 +    assert(options);\r
154 +\r
155 +    arg += 2;\r
156 +\r
157 +    const notmuch_opt_desc_t *try = options;\r
158 +    while (try->name) {\r
159 +       if (strncmp (arg, try->name, strlen(try->name)) == 0) {\r
160 +\r
161 +           switch (try->opt_type) {\r
162 +           case NOTMUCH_OPT_KEYWORD:\r
163 +               return  _process_keyword_arg (try, arg+strlen(try->name));\r
164 +               break;\r
165 +           case NOTMUCH_OPT_BOOLEAN:\r
166 +               return TRUE;\r
167 +               break;\r
168 +           case NOTMUCH_OPT_POSITION:\r
169 +           case NOTMUCH_OPT_NULL:\r
170 +           default:\r
171 +               INTERNAL_ERROR ("unknown or unhandled option type %d", try->opt_type);\r
172 +               /*UNREACHED*/\r
173 +           }\r
174 +       }\r
175 +       try++;\r
176 +    }\r
177 +    return FALSE;\r
178 +}\r
179 +\r
180 +int\r
181 +notmuch_parse_args (int argc, char **argv, const notmuch_opt_desc_t *options, int opt_index){\r
182 +\r
183 +    int pos_arg_index = 0;\r
184 +    notmuch_bool_t more_args = TRUE;\r
185 +\r
186 +    while (more_args && opt_index < argc) {\r
187 +       if (strncmp (argv[opt_index],"--",2) != 0) {\r
188 +\r
189 +           more_args = parse_position_arg (argv[opt_index], pos_arg_index, options);\r
190 +\r
191 +           if (more_args) {\r
192 +               pos_arg_index++;\r
193 +               opt_index++;\r
194 +           }\r
195 +\r
196 +       } else {\r
197 +\r
198 +           if (strlen (argv[opt_index]) == 2)\r
199 +               return opt_index+1;\r
200 +\r
201 +           more_args = parse_option (argv[opt_index], options);\r
202 +           opt_index++;\r
203 +       }\r
204 +    }\r
205 +\r
206 +    return opt_index;\r
207 +}\r
208 diff --git a/notmuch-opts.h b/notmuch-opts.h\r
209 new file mode 100644\r
210 index 0000000..75d65cb\r
211 --- /dev/null\r
212 +++ b/notmuch-opts.h\r
213 @@ -0,0 +1,50 @@\r
214 +#ifndef NOTMUCH_OPTS_H\r
215 +#define NOTMUCH_OPTS_H\r
216 +\r
217 +#include "notmuch.h"\r
218 +\r
219 +enum notmuch_opt_type {\r
220 +    NOTMUCH_OPT_NULL = 0,\r
221 +    NOTMUCH_OPT_BOOLEAN,\r
222 +    NOTMUCH_OPT_KEYWORD,\r
223 +    NOTMUCH_OPT_POSITION\r
224 +};\r
225 +\r
226 +typedef enum notmuch_opt_result {\r
227 +    NOTMUCH_OPT_ERROR = -2,\r
228 +    NOTMUCH_OPT_GOT_POS = -1,\r
229 +    NOTMUCH_OPT_STOP = 0,\r
230 +    NOTMUCH_OPT_SUCCESS = 1\r
231 +} notmuch_opt_result_t;\r
232 +\r
233 +typedef struct notmuch_keyword {\r
234 +    const char *name;\r
235 +    int value;\r
236 +} notmuch_keyword_t;\r
237 +\r
238 +typedef struct notmuch_opt_desc {\r
239 +    const char *name;\r
240 +    int  arg_id;\r
241 +    enum notmuch_opt_type opt_type;\r
242 +    struct notmuch_keyword *keywords;\r
243 +    void *output_var;\r
244 +} notmuch_opt_desc_t;\r
245 +\r
246 +typedef struct notmuch_opt {\r
247 +    int arg_id;\r
248 +    int keyword_id;\r
249 +    const char *string;\r
250 +} notmuch_opt_t;\r
251 +\r
252 +notmuch_bool_t\r
253 +parse_option (const char *arg, const notmuch_opt_desc_t* options);\r
254 +\r
255 +notmuch_bool_t\r
256 +parse_position_arg (const char *arg,\r
257 +                   int position_arg_index,\r
258 +                   const notmuch_opt_desc_t* options);\r
259 +\r
260 +int\r
261 +notmuch_parse_args(int argc, char **argv, const notmuch_opt_desc_t *options, int opt_index);\r
262 +\r
263 +#endif\r
264 -- \r
265 1.7.5.4\r
266 \r