Blame view

libmu_argp/muinit.c 5.25 KB
1
/* GNU Mailutils -- a suite of utilities for electronic mail
2
   Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 3 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General
   Public License along with this library; if not, write to the
   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301 USA */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
22
#include "cmdline.h"
23 24
#include <unistd.h>
#include <stdlib.h>
25
#include <mailutils/stream.h>
26 27
#include "xalloc.h"
#include <string.h>
28 29 30
#ifdef MU_ALPHA_RELEASE
# include <git-describe.h>
#endif
31
struct mu_cfg_tree *mu_argp_tree;
32

33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
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.";

void
mu_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);
}

63 64 65
void
mu_argp_init (const char *vers, const char *bugaddr)
{
66 67 68 69
  if (vers)
    argp_program_version = vers;
  else
    argp_program_version_hook = mu_program_version_hook;
70 71
  argp_program_bug_address = bugaddr ? bugaddr : "<" PACKAGE_BUGREPORT ">";
}
72

73 74 75 76 77
static char *
get_canonical_name ()
{
  char *name;
  size_t len;
Sergey Poznyakoff authored
78 79 80 81
  char *p;

  if (!argp_program_version ||
      !(p = strchr (argp_program_version, ' ')))
82 83
    return strdup (mu_program_name);
  len = p - argp_program_version;
Sergey Poznyakoff authored
84 85 86
  name = malloc (len + 1);
  if (!name)
    abort ();
87 88 89 90 91 92
  memcpy (name, argp_program_version, len);
  name[len] = 0;
  return name;
}

int mu_help_config_mode;
Sergey Poznyakoff authored
93
int mu_rcfile_lint;
94

95 96
int (*mu_app_cfg_verifier) (void) = NULL;

97 98 99 100 101 102 103
int
mu_app_init (struct argp *myargp, const char **capa,
	     struct mu_cfg_param *cfg_param,
	     int argc, char **argv, int flags, int *pindex, void *data)
{
  int rc, i;
  struct argp *argp;
104
  struct argp argpnull = { 0 };
105
  char **excapa;
106
  struct mu_cfg_tree *parse_tree = NULL;
107
  
108 109
  mu_set_program_name (argv[0]);
  mu_libargp_init ();
110 111 112
  if (capa)
    for (i = 0; capa[i]; i++)
      mu_gocs_register_std (capa[i]); /*FIXME*/
113 114
  if (!myargp)
    myargp = &argpnull;
115
  argp = mu_argp_build (myargp, &excapa);
116 117

  mu_cfg_tree_create (&mu_argp_tree);
118 119 120 121
  rc = argp_parse (argp, argc, argv, flags, pindex, data);
  mu_argp_done (argp);
  if (rc)
    return rc;
122 123 124 125

  /* Reset program name, it may have been changed using the `--program-name'
     option. */
  mu_set_program_name (program_invocation_name);
126
  
127 128
  mu_libcfg_init (excapa);
  free (excapa);
129

130 131
  if (mu_help_config_mode)
    {
132
      char *comment;
133 134
      char *canonical_name = get_canonical_name ();
      mu_stream_t stream;
135
      mu_stdio_stream_create (&stream, MU_STDOUT_FD, 0);
136
      mu_stream_open (stream);
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
      asprintf (&comment,
		"Configuration file structure for %s utility.",
		mu_program_name);
      mu_cfg_format_docstring (stream, comment, 0);
      free (comment);
      asprintf (&comment,
		"For use in global configuration file (%s), enclose it "
		"in `program %s { ... };",
		MU_CONFIG_FILE,
		mu_program_name);		   
      mu_cfg_format_docstring (stream, comment, 0);
      free (comment);
      asprintf (&comment, "For more information, use `info %s'.",
		canonical_name);
      mu_cfg_format_docstring (stream, comment, 0);
      free (comment);
153 154
      
      mu_format_config_tree (stream, mu_program_name, cfg_param, 0);
155
      mu_stream_destroy (&stream);
156 157
      exit (0);
    }
Sergey Poznyakoff authored
158

159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
  rc = mu_libcfg_parse_config (&parse_tree);
  if (rc == 0)
    {
      int cfgflags = MU_PARSE_CONFIG_PLAIN;

      if (mu_cfg_parser_verbose)
	cfgflags |= MU_PARSE_CONFIG_VERBOSE;
      if (mu_cfg_parser_verbose > 1)
	cfgflags |= MU_PARSE_CONFIG_DUMP;
      mu_cfg_tree_postprocess (mu_argp_tree, cfgflags);
      mu_cfg_tree_union (&parse_tree, &mu_argp_tree);
      rc = mu_cfg_tree_reduce (parse_tree, mu_program_name, cfg_param,
			       cfgflags, data);
    }
  
174 175 176 177 178 179 180 181 182
  if (mu_rcfile_lint)
    {
      if (rc || mu_cfg_error_count)
	exit (1);
      if (mu_app_cfg_verifier)
	rc = mu_app_cfg_verifier ();
      exit (rc ? 1 : 0);
    }
  
183
  mu_gocs_flush ();
184
  mu_cfg_destroy_tree (&mu_argp_tree);
185

186
  return !!(rc || mu_cfg_error_count);
187
}
188