Blame view

mh/mh_argp.c 7.39 KB
Wojciech Polak authored
1
/* GNU Mailutils -- a suite of utilities for electronic mail
2 3
   Copyright (C) 1999, 2000, 2001, 2002, 2005, 2006, 2007, 2009, 2010
   Free Software Foundation, Inc.
4

Wojciech Polak authored
5
   GNU Mailutils is free software; you can redistribute it and/or modify
6
   it under the terms of the GNU General Public License as published by
7
   the Free Software Foundation; either version 3, or (at your option)
8 9
   any later version.

Wojciech Polak authored
10
   GNU Mailutils is distributed in the hope that it will be useful,
11 12 13 14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

15
   You should have received a copy of the GNU General Public License
16
   along with GNU Mailutils.  If not, see <http://www.gnu.org/licenses/>. */
17 18 19 20 21 22 23 24

/* Coexistence between GNU long options, traditional UNIX-style short
   options and traditional MH long options. */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

25
#include <mh.h>
26
#include <string.h>
27
#include <mailutils/argcv.h>
28
#include "argp.h"
29 30 31
#ifdef MU_ALPHA_RELEASE
# include <git-describe.h>
#endif
32 33 34 35 36

static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
  struct mh_argp_data *data = state->input;
37 38
  error_t ret = ARGP_ERR_UNKNOWN;
  
39 40 41 42
  switch (key)
    {
    case ARGP_KEY_ARG:
      if (arg[0] == '+')
43 44 45
	ret = data->handler (ARG_FOLDER, arg + 1, state);
      break;
      
46
    default:
47 48
      ret = data->handler (key, arg, state);
      if (ret == 0)
49 50 51 52
	{
	  if (key == ARGP_KEY_ERROR)
	    data->errind = state->next;
	}
53
    }
54 55

  return ret;
56 57
}

58 59 60 61 62 63 64
static int
my_argp_parse (struct argp *argp, int argc, char **argv, int flags,
	       int *end_index, struct mh_argp_data *data)
{
  int rc;
  int f = 0;
  int index = 0;
65

66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
  if (flags & ARGP_NO_ERRS)
    {
      while (argc > 0
	     && (rc = argp_parse (argp, argc, argv, flags|f, end_index, data))
	     == EINVAL)
	{
	  if (data->errind == -1)
	    break;
	  data->errind--;
	  if (f)
	    data->errind--;
	  argc -= data->errind;
	  argv += data->errind;
	  index += data->errind;
	  if (argc < 2 || memcmp (argv[1], "--", 2))
	    {
	      if (end_index)
		*end_index = index + 1;
	      break;
	    }
	  f = ARGP_PARSE_ARGV0;
	}
      if (rc == 0 && end_index)
	*end_index += index;
      rc = 0;
    }
  else
    rc = argp_parse (argp, argc, argv, flags, end_index, data);
  return rc;
}

97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
const char version_etc_copyright[] =
  /* Do *not* mark this string for translation.  %s is a copyright
     symbol suitable for this locale, and %d is the copyright
     year.  */
  "Copyright %s 2010 Free Software Foundation, inc.";

/* This is almost the same as mu_program_version_hook from muinit.c,
   except for different formatting of the first line. MH uses:

      progname (GNU Mailutils X.Y.Z)

   where X.Y.Z stands for the version number. Emacs MH-E uses this
   to determine Mailutils presence and its version number (see
   lisp/mh-e/mh-e.el, function mh-variant-mu-mh-info). */
static void
mh_program_version_hook (FILE *stream, struct argp_state *state)
{
#ifdef GIT_DESCRIBE
  fprintf (stream, "%s (%s %s) [%s]\n",
	   mu_program_name, PACKAGE_NAME, PACKAGE_VERSION, GIT_DESCRIBE);
#else
  fprintf (stream, "%s (%s %s)\n", mu_program_name,
	   PACKAGE_NAME, PACKAGE_VERSION);
#endif
  /* TRANSLATORS: Translate "(C)" to the copyright symbol
     (C-in-a-circle), if this symbol is available in the user's
     locale.  Otherwise, do not translate "(C)"; leave it as-is.  */
  fprintf (stream, version_etc_copyright, _("(C)"));

  fputs (_("\
\n\
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to change and redistribute it.\n\
There is NO WARRANTY, to the extent permitted by law.\n\
\n\
"),
	 stream);
}

135
void
136
mh_argp_init ()
137 138
{
  argp_program_bug_address =  "<" PACKAGE_BUGREPORT ">";
139
  argp_program_version_hook = mh_program_version_hook;
140 141
}

142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163

enum
  {
    OPT_DEBUG_LEVEL = 256,
    OPT_DEBUG_LINE_INFO,
  };

static struct argp_option mu_debug_argp_options[] = 
{
  { "debug-level", OPT_DEBUG_LEVEL, N_("LEVEL"), 0,
    N_("set Mailutils debugging level"), 0 },
  { "debug-line-info", OPT_DEBUG_LINE_INFO, NULL, 0,
    N_("show source info with debugging messages"), 0 },
  { NULL }
};

static error_t
mu_debug_argp_parser (int key, char *arg, struct argp_state *state)
{
  switch (key)
    {
    case OPT_DEBUG_LEVEL:
164
      mu_debug_parse_spec (arg);
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
      break;

    case OPT_DEBUG_LINE_INFO:
      mu_debug_line_info = 1;
      break;
      
    default:
      return ARGP_ERR_UNKNOWN;
    }
  return 0;
}

struct argp mu_debug_argp = {
  mu_debug_argp_options,
  mu_debug_argp_parser,
};

struct argp_child mh_argp_children[] = {
183
  { &mu_debug_argp, 0, N_("Global debugging settings"), -2 },
184 185 186
  { NULL }
};

187
int
188
mh_argp_parse (int *pargc, char **pargv[],
189
	       int flags,
190 191 192
	       struct argp_option *option,
	       struct mh_option *mh_option,
	       char *argp_doc, char *doc,
193 194
	       argp_parser_t handler,
	       void *closure, int *pindex)
195 196 197
{
  struct argp argp;
  struct mh_argp_data data;
198
  const char *val;
199 200
  int index;
  int extra  = 0;
201

202
  mu_set_program_name ((*pargv)[0]);
203
  mh_init ();
204 205

  mh_option_init (mh_option);
206 207 208 209 210
  memset (&argp, 0, sizeof (argp));
  argp.options = option;
  argp.parser = parse_opt;
  argp.args_doc = argp_doc;
  argp.doc = doc;
211
  argp.children = mh_argp_children;
212 213 214
  data.mh_option = mh_option;
  data.closure = closure;
  data.handler = handler;
215
  data.doc = argp_doc;
216
  data.errind = -1;
217
  
218
  val = mh_global_profile_get (mu_program_name, NULL);
219
  if (val)
220
    {
221 222
      int argc;
      char **argv;
223
      int i, j;
224
      struct mu_wordsplit ws;
225
      
226 227 228 229 230 231
      if (mu_wordsplit (val, &ws, MU_WRDSF_DEFFLAGS))
	{
	  mu_error (_("cannot split line `%s': %s"), val,
		    mu_wordsplit_strerror (&ws));
	  exit (1);
	}
232

233 234
      argc = *pargc + ws.ws_wordc;
      argv = calloc (argc + 1, sizeof *argv);
235
      if (!argv)
236
        mh_err_memory (1);
237 238

      i = 0;
239
      argv[i++] = (*pargv)[0];
240 241
      for (j = 0; j < ws.ws_wordc; i++, j++)
	argv[i] = ws.ws_wordv[j];
242 243 244
      for (j = 1; i < argc; i++, j++)
	argv[i] = (*pargv)[j];
      argv[i] = NULL;
245 246 247

      ws.ws_wordc = 0;
      mu_wordsplit_free (&ws);
248
      
249
      mh_argv_preproc (argc, argv, &data);
250

251
      my_argp_parse (&argp, argc, argv, flags, &index, &data);
252

253
      extra = index < argc;
254 255 256 257 258 259 260 261 262

      *pargc = argc;
      *pargv = argv;
    }
  else
    {
      mh_argv_preproc (*pargc, *pargv, &data);
      my_argp_parse (&argp, *pargc, *pargv, flags, &index, &data);
      extra = index < *pargc;
263 264 265 266 267
    }
  if (pindex)
    *pindex = index;
  else if (extra)
    {
268
      mu_error (_("Extra arguments"));
269 270
      exit (1);
    }
271
  mh_init2 ();
272
  return 0;
273 274 275 276 277
}

void
mh_license (const char *name)
{
Wojciech Polak authored
278 279
  printf (_("This is %s\n\n"), name);
  printf (
Wojciech Polak authored
280 281
  _("   GNU Mailutils is free software; you can redistribute it and/or modify\n"
    "   it under the terms of the GNU General Public License as published by\n"
282
    "   the Free Software Foundation; either version 3 of the License, or\n"
Wojciech Polak authored
283 284 285 286 287 288 289
    "   (at your option) any later version.\n"
    "\n"
    "   GNU Mailutils is distributed in the hope that it will be useful,\n"
    "   but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
    "   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
    "   GNU General Public License for more details.\n"
    "\n"
290
    "   You should have received a copy of the GNU General Public License along\n"
291
    "   with GNU Mailutils.  If not, see <http://www.gnu.org/licenses/>.\n"
292 293 294
    "\n"
    "\n"
));
Wojciech Polak authored
295

296 297 298
  exit (0);
}