/*
* fhist - file history and comparison tools
* Copyright (C) 1991-1995, 1998, 2000, 2002, 2004, 2005 Peter Miller;
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
*
* MANIFEST: functions to provide consistent treatment of -Help options
*/
#include <ac/stdlib.h>
#include <ac/unistd.h>
#include <arglex.h>
#include <env.h>
#include <error.h>
#include <error_intl.h>
#include <help.h>
#include <libdir.h>
#include <progname.h>
#include <quit.h>
#include <str_list.h>
#include <trace.h>
static void
help_env(void)
{
char *cp;
string_list_ty manpath;
string_ty *s;
string_list_ty lib;
string_list_ty lang;
size_t j, k;
string_list_ty wl;
/*
* Honour any existing MANPATH setting by appending only.
* Read the MANPATH to set the initial path.
*/
cp = getenv("MANPATH");
if (cp)
{
s = str_from_c(cp);
str2wl(&manpath, s, ":", 0);
str_free(s);
}
else
{
string_list_constructor(&manpath);
s = str_from_c("/usr/man");
string_list_append(&manpath, s);
str_free(s);
s = str_from_c("/usr/share/man");
string_list_append(&manpath, s);
str_free(s);
}
/*
* The list of library directories to look in.
*/
string_list_constructor(&lib);
s = str_from_c(configured_datadir());
string_list_append_unique(&lib, s);
str_free(s);
cp = getenv("FHIST_MESSAGE_LIBRARY");
if (cp)
{
s = str_from_c(cp);
str2wl(&wl, s, ":", 0);
for (j = 0; j < wl.nstrings; ++j)
string_list_append_unique(&lib, wl.string[j]);
string_list_destructor(&wl);
}
/*
* Use the LANGUAGE (or LANG) environment
* variables to know which languages to add.
* Default to "en" if not set.
*/
string_list_constructor(&lang);
cp = getenv("LANGUAGE");
if (cp)
{
s = str_from_c(cp);
str2wl(&wl, s, ":", 0);
for (j = 0; j < wl.nstrings; ++j)
string_list_append_unique(&lang, wl.string[j]);
string_list_destructor(&wl);
}
cp = getenv("LANG");
if (cp)
{
s = str_from_c(cp);
str2wl(&wl, s, ":", 0);
for (j = 0; j < wl.nstrings; ++j)
string_list_append_unique(&lang, wl.string[j]);
string_list_destructor(&wl);
}
if (!lang.nstrings)
{
s = str_from_c("en");
string_list_append(&lang, s);
str_free(s);
}
/*
* convolve the lib and lang lists and append them to the manpath
*/
for (j = 0; j < lib.nstrings; ++j)
{
string_list_append_unique(&manpath, lib.string[j]);
for (k = 0; k < lang.nstrings; ++k)
{
s = str_format("%S/%S", lib.string[j], lang.string[k]);
string_list_append_unique(&manpath, s);
str_free(s);
}
}
string_list_destructor(&lib);
string_list_destructor(&lang);
s = str_from_c(configured_mandir());
string_list_append_unique(&lib, s);
str_free(s);
/*
* set the MANPATH environment variable
*/
s = wl2str(&manpath, 0, manpath.nstrings, ":");
string_list_destructor(&manpath);
env_set("MANPATH", s->str_text);
str_free(s);
}
void
help(char *progname, void (*usage)(void))
{
char *argv[3];
sub_context_ty *scp;
/*
* collect the rest of the command line,
* if necessary
*/
if (usage)
{
arglex();
while (arglex_token != arglex_token_eoln)
bad_argument(usage);
}
if (!progname)
progname = progname_get();
/*
* set the MANPATH environment variable
* to point into the libraries
*/
help_env();
/*
* Invoke the appropriate ``man'' command. This will find the
* right language on the search path, and it already knows how
* to translate the *roff into text.
*/
argv[0] = "man";
argv[1] = progname;
argv[2] = 0;
error_raw("%s %s", argv[0], argv[1]);
execvp(argv[0], argv);
scp = sub_context_new();
sub_errno_set(scp);
sub_var_set_charstar(scp, "File_Name", argv[0]);
fatal_intl(scp, i18n("exec \"$filename\": $errno"));
/* NOTREACHED */
}
void
bad_argument(void (*usage)(void))
{
sub_context_ty *scp;
trace(("bad_argument()\n{\n"));
switch (arglex_token)
{
case arglex_token_string:
scp = sub_context_new();
sub_var_set_charstar(scp, "File_Name", arglex_value.alv_string);
error_intl(scp, i18n("misplaced file name (\"$filename\")"));
sub_context_delete(scp);
break;
case arglex_token_number:
scp = sub_context_new();
sub_var_set_charstar(scp, "Number", arglex_value.alv_string);
error_intl(scp, i18n("misplaced number ($number)"));
sub_context_delete(scp);
break;
case arglex_token_option:
scp = sub_context_new();
sub_var_set_charstar(scp, "Name", arglex_value.alv_string);
error_intl(scp, i18n("unknown \"$name\" option"));
sub_context_delete(scp);
break;
case arglex_token_eoln:
error_intl(0, i18n("command line too short"));
break;
default:
scp = sub_context_new();
sub_var_set_charstar(scp, "Name", arglex_token_name(arglex_token));
error_intl(scp, i18n("misplaced \"$name\" option"));
sub_context_delete(scp);
break;
}
usage();
trace(("}\n"));
quit(1);
/* NOTREACHED */
}
void
mutually_exclusive(int arg1, int arg2, void (*usage)(void))
{
sub_context_ty *scp;
scp = sub_context_new();
sub_var_set_charstar(scp, "Name1", arglex_token_name(arg1));
sub_var_set_charstar(scp, "Name2", arglex_token_name(arg2));
error_intl(scp, i18n("$name1 and $name2 mutually exclusive"));
sub_context_delete(scp);
usage();
quit(1);
}
syntax highlighted by Code2HTML, v. 0.9.1