#include "config.h"
#include "system.h"
#include "intl.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "ggc.h"
#include "output.h"
#include "langhooks.h"
#include "opts.h"
#include "options.h"
#include "flags.h"
#include "toplev.h"
#include "params.h"
#include "diagnostic.h"
#include "tm_p.h"
#include "insn-attr.h"
#include "target.h"
unsigned HOST_WIDE_INT g_switch_value;
bool g_switch_set;
bool exit_after_options;
bool version_flag;
bool extra_warnings;
bool inhibit_warnings;
bool warnings_are_errors;
bool warn_aggregate_return;
bool warn_cast_align;
bool warn_deprecated_decl = true;
bool warn_disabled_optimization;
bool warn_inline;
bool warn_larger_than;
HOST_WIDE_INT larger_than_size;
bool warn_missing_noreturn;
bool warn_notreached;
bool warn_packed;
bool warn_padded;
bool warn_shadow;
int warn_strict_aliasing;
bool warn_switch;
bool warn_switch_default;
bool warn_switch_enum;
bool warn_system_headers;
int warn_uninitialized;
bool warn_unused_function;
bool warn_unused_label;
bool warn_unused_parameter;
bool warn_unused_variable;
bool warn_unused_value;
static bool maybe_warn_unused_parameter;
enum debug_info_type write_symbols = NO_DEBUG;
enum debug_info_type orig_write_symbols = NO_DEBUG;
int flag_grepository = 0;
enum debug_info_level debug_info_level = DINFO_LEVEL_NONE;
bool use_gnu_debug_info_extensions;
static unsigned int columns = 80;
static const char undocumented_msg[] = N_("This switch lacks documentation");
static bool profile_arc_flag_set, flag_profile_values_set;
static bool flag_unroll_loops_set, flag_tracer_set;
static bool flag_value_profile_transformations_set;
static bool flag_peel_loops_set, flag_branch_probabilities_set;
const char **in_fnames;
unsigned num_in_fnames;
static size_t find_opt (const char *, int);
static int common_handle_option (size_t scode, const char *arg, int value);
static void handle_param (const char *);
static void set_Wextra (int);
static unsigned int handle_option (const char **argv, unsigned int lang_mask);
static char *write_langs (unsigned int lang_mask);
static void complain_wrong_lang (const char *, const struct cl_option *,
unsigned int lang_mask);
static void handle_options (unsigned int, const char **, unsigned int);
static void wrap_help (const char *help, const char *item, unsigned int);
static void print_help (void);
static void print_param_help (void);
static void print_filtered_help (unsigned int flag);
static unsigned int print_switch (const char *text, unsigned int indent);
static void set_debug_level (enum debug_info_type type, int extended,
const char *arg);
static size_t
find_opt (const char *input, int lang_mask)
{
size_t mn, mx, md, opt_len;
size_t match_wrong_lang;
int comp;
mn = 0;
mx = cl_options_count;
while (mx - mn > 1)
{
md = (mn + mx) / 2;
opt_len = cl_options[md].opt_len;
comp = strncmp (input, cl_options[md].opt_text + 1, opt_len);
if (comp < 0)
mx = md;
else
mn = md;
}
match_wrong_lang = cl_options_count;
do
{
const struct cl_option *opt = &cl_options[mn];
if (!strncmp (input, opt->opt_text + 1, opt->opt_len))
{
if ((opt->flags & lang_mask)
&& (input[opt->opt_len] == '\0' || (opt->flags & CL_JOINED)))
return mn;
if (match_wrong_lang == cl_options_count)
match_wrong_lang = mn;
}
mn = opt->back_chain;
}
while (mn != cl_options_count);
return match_wrong_lang;
}
static int
integral_argument (const char *arg)
{
const char *p = arg;
while (*p && ISDIGIT (*p))
p++;
if (*p == '\0')
return atoi (arg);
return -1;
}
static char *
write_langs (unsigned int mask)
{
unsigned int n = 0, len = 0;
const char *lang_name;
char *result;
for (n = 0; (lang_name = lang_names[n]) != 0; n++)
if (mask & (1U << n))
len += strlen (lang_name) + 1;
result = xmalloc (len);
len = 0;
for (n = 0; (lang_name = lang_names[n]) != 0; n++)
if (mask & (1U << n))
{
if (len)
result[len++] = '/';
strcpy (result + len, lang_name);
len += strlen (lang_name);
}
result[len] = 0;
return result;
}
static void
complain_wrong_lang (const char *text, const struct cl_option *option,
unsigned int lang_mask)
{
char *ok_langs, *bad_lang;
ok_langs = write_langs (option->flags);
bad_lang = write_langs (lang_mask);
warning ("command line option \"%s\" is valid for %s but not for %s",
text, ok_langs, bad_lang);
free (ok_langs);
free (bad_lang);
}
static unsigned int
handle_option (const char **argv, unsigned int lang_mask)
{
size_t opt_index;
const char *opt, *arg = 0;
char *dup = 0;
int value = 1;
unsigned int result = 0;
const struct cl_option *option;
opt = argv[0];
if ((opt[1] == 'W' || opt[1] == 'f')
&& opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
{
size_t len = strlen (opt) - 3;
dup = xmalloc (len + 1);
dup[0] = '-';
dup[1] = opt[1];
memcpy (dup + 2, opt + 5, len - 2 + 1);
opt = dup;
value = 0;
}
opt_index = find_opt (opt + 1, lang_mask | CL_COMMON);
if (opt_index == cl_options_count)
goto done;
option = &cl_options[opt_index];
if (!value && (option->flags & CL_REJECT_NEGATIVE))
goto done;
result = 1;
if (option->flags & CL_JOINED)
{
arg = argv[0] + cl_options[opt_index].opt_len + 1;
if (!value)
arg += strlen ("no-");
if (*arg == '\0' && !(option->flags & CL_MISSING_OK))
{
if (option->flags & CL_SEPARATE)
{
arg = argv[1];
result = 2;
}
else
arg = NULL;
}
}
else if (option->flags & CL_SEPARATE)
{
arg = argv[1];
result = 2;
}
if (!(option->flags & (lang_mask | CL_COMMON)))
{
complain_wrong_lang (argv[0], option, lang_mask);
goto done;
}
if (arg == NULL && (option->flags & (CL_JOINED | CL_SEPARATE)))
{
if (!lang_hooks.missing_argument (opt, opt_index))
error ("missing argument to \"%s\"", opt);
goto done;
}
if (arg && (option->flags & CL_UINTEGER))
{
value = integral_argument (arg);
if (value == -1)
{
error ("argument to \"%s\" should be a non-negative integer",
option->opt_text);
goto done;
}
}
if (option->flags & lang_mask)
if (lang_hooks.handle_option (opt_index, arg, value) == 0)
result = 0;
if (result && (option->flags & CL_COMMON))
if (common_handle_option (opt_index, arg, value) == 0)
result = 0;
done:
if (dup)
free (dup);
return result;
}
static int add_env_options PARAMS ((unsigned int *, const char ***));
static int override_option PARAMS ((int, int, const char **));
static void
handle_options (unsigned int argc, const char **argv, unsigned int lang_mask)
{
unsigned int n, i;
do {
for (i = 1; i < argc; i += n)
{
const char *opt = argv[i];
if (!override_option (i, argc, argv))
{
++i;
n = 0;
continue;
}
if (opt[0] != '-' || opt[1] == '\0')
{
if (main_input_filename == NULL)
main_input_filename = opt;
add_input_filename (opt);
n = 1;
continue;
}
n = handle_option (argv + i, lang_mask);
if (!n)
{
n = 1;
error ("unrecognized command line option \"%s\"", opt);
}
}
} while (add_env_options (&argc, &argv));
}
struct env_overrides {
char *option;
unsigned short flags;
};
#define env_ovr_used 1
#define env_ovr_has_arg 2
#define env_ovr_add_arg 4
#define env_over_no_msg 8
static struct env_overrides *env_override_options;
static int n_overrides = 0;
static int env_override_options_max = 0;
static int have_added_opts = 0;
static int add_env_opts = 0;
static int env_ovr_confirm = 1;
static char *extract_override_options PARAMS ((void));
static void override_O_option PARAMS ((void));
static char *
extract_override_options (void)
{
int has_arg = 0, scnt = 0, added_flag;
char *override_O = NULL, s = 0;
char *opts = getenv ("QA_OVERRIDE_GCC3_OPTIONS");
if (opts && *opts)
{
char c, *p, quote;
static char *override_options_line;
override_options_line = xstrdup (opts);
if (override_options_line[0] == '#')
{
env_ovr_confirm = 0;
p = override_options_line;
}
else
{
env_ovr_confirm = 1;
p = override_options_line - 1;
}
if (env_ovr_confirm)
fprintf (stderr, "### QA_OVERRIDE_GCC3_OPTIONS: %s\n",
override_options_line);
n_overrides = 0;
while (1)
{
while (*++p == ' ') ;
if ((c = *p) == '\0')
break;
if (p[0] == '-' && p[1] == 'O')
override_O = p;
else
{
if (p[0] == '+')
{
have_added_opts = env_ovr_add_arg;
continue;
}
if (p[0] == 's')
{
s = p[1];
scnt = 0;
added_flag = 0;
}
else
{
s = scnt = 0;
added_flag = have_added_opts;
}
if (n_overrides >= env_override_options_max)
{
env_override_options_max += 6;
env_override_options = (struct env_overrides *)
xrealloc (env_override_options,
sizeof (struct env_overrides)
* env_override_options_max);
if (n_overrides == 0)
++n_overrides;
}
if (!has_arg && p[0] == '-' && p[1] == '-')
{
env_override_options[n_overrides].flags = env_ovr_has_arg | added_flag;
env_override_options[n_overrides].option = p + 1;
has_arg = 1;
}
else
{
env_override_options[n_overrides].flags = added_flag;
env_override_options[n_overrides].option = p--;
has_arg = 0;
}
++n_overrides;
}
quote = 0;
while (*++p && (*p != ' ' || quote || s))
if (*p == '"' || *p == '\'')
quote = (quote && *p == quote) ? 0 : *p;
else if (*p == '\\')
++p;
else if (*p == s && ++scnt == 3)
s = 0;
if (!*p)
break;
*p = '\0';
}
}
if (has_arg)
fatal_error ("QA_OVERRIDE_GCC3_OPTIONS invalid - last option should have an argument");
return override_O;
}
static void
override_O_option (void)
{
char *overide_opt = extract_override_options ();
int optimize0 = optimize, optimize_size0 = optimize_size;
if (!overide_opt)
return;
optimize = -1;
if (!strcmp (overide_opt, "-O"))
{
optimize = 1;
optimize_size = 0;
}
else if (overide_opt[0] == '-' && overide_opt[1] == 'O')
{
char *p = overide_opt + 2;
if ((p[0] == 's') && (p[1] == 0))
{
optimize_size = 1;
optimize = 2;
}
else
{
const int optimize_val = read_integral_parameter (p, p - 2, -1);
if (optimize_val != -1)
{
optimize = optimize_val;
optimize_size = 0;
}
}
}
if (optimize < 0)
fatal_error ("QA_OVERRIDE_GCC3_OPTIONS set with an invalid O option (%s).",
overide_opt);
if (env_ovr_confirm
&& (optimize != optimize0 || optimize_size != optimize_size0))
fprintf (stderr, "### QA_OVERRIDE_GCC3_OPTIONS: Optimization set to %s\n", overide_opt);
}
static int
override_option (int i, int argc, const char **argv)
{
int j, len, parg;
char *p;
const char *opt;
char letter_opt1, letter_opt2, s = 0;
char *repopt = NULL;
char *reparg, *repend;
static char rep_option[256], rep_arg[256];
if (n_overrides == 0)
return 1;
if (add_env_opts)
{
if ((env_override_options[i].flags & env_ovr_add_arg) == 0
|| (env_override_options[i].flags & env_ovr_used) != 0
|| env_override_options[i].option == NULL)
return 0;
argv[i] = env_override_options[i].option;
if (env_override_options[i].flags & env_ovr_has_arg)
{
argv[i+1] = env_override_options[i+1].option;
if (env_ovr_confirm
&& (env_override_options[i].flags & env_over_no_msg) == 0)
fprintf (stderr,
"### QA_OVERRIDE_GCC3_OPTIONS: Adding command line option '%s %s'\n",
argv[i], argv[i+1]);
}
else if (env_ovr_confirm
&& (env_override_options[i].flags & env_over_no_msg) == 0)
fprintf (stderr, "### QA_OVERRIDE_GCC3_OPTIONS: Adding command line option '%s'\n",
argv[i]);
return 1;
}
if (!argv[i])
return 0;
opt = argv[i];
letter_opt1 = 0;
if (opt[0] == '-')
{
if (opt[1] == 'f' || opt[1] == 'm' || opt[1] == 'W')
{
letter_opt1 = opt[1];
opt += 2;
}
if (opt[0] == 'n' && opt[1] == 'o' && opt[2] == '-')
opt += 3;
}
for (j = 1; j < n_overrides; ++j)
{
p = env_override_options[j].option;
letter_opt2 = 0;
s = 0;
parg = 0;
if (p[0] == 's')
{
s = p[1];
p += 2;
repopt = strchr (p, s);
if (!repopt)
return 1;
*repopt++ = '\0';
if (p[0] == '-' && p[1] == '-')
{
parg = 1;
++p;
}
}
if (p[0] == '-')
{
if (p[1] == 'f' || p[1] == 'm' || p[1] == 'W')
{
letter_opt2 = p[1];
p += 2;
}
if (p[0] == 'n' && p[1] == 'o' && p[2] == '-')
p += 3;
}
if (strcmp (p, opt) == 0 && letter_opt1 == letter_opt2)
{
if (i < argc - 1
&& (env_override_options[j].flags & env_ovr_has_arg))
argv[i + 1] = env_override_options[j + 1].option;
if (s)
{
repend = strchr (repopt, s);
reparg = NULL;
if (repend)
{
reparg = strchr(repopt, ' ');
if (reparg)
{
strncpy (rep_option, repopt, len = reparg - repopt);
rep_option[len] = '\0';
++reparg;
strncpy (rep_arg, reparg, len = repend - reparg);
rep_arg[len] = '\0';
}
else
{
strncpy (rep_option, repopt, len = repend - repopt);
rep_option[len] = rep_arg[0] = '\0';
}
if (len)
{
if (parg)
{
if (reparg)
{
if (strcmp (argv[i], rep_option) != 0
|| strcmp (argv[i+1], rep_arg) == 0)
{
if (env_ovr_confirm
&& (env_override_options[j].flags & env_ovr_used) == 0)
fprintf (stderr,
"### QA_OVERRIDE_GCC3_OPTIONS: Replacing command line option '%s %s' with '%s %s'\n",
argv[i], argv[i + 1], rep_option, rep_arg);
argv[i] = rep_option;
argv[i + 1] = rep_arg;
}
}
else
{
if (env_ovr_confirm
&& (env_override_options[j].flags & env_ovr_used) == 0)
fprintf (stderr,
"### QA_OVERRIDE_GCC3_OPTIONS: Replacing command line option '%s %s' with '%s'\n",
argv[i], argv[i + 1], rep_option);
argv[i] = rep_option;
argv[i+1] = NULL;
}
}
else if (reparg)
{
if (env_ovr_confirm
&& (env_override_options[j].flags & env_ovr_used) == 0)
fprintf (stderr,
"### QA_OVERRIDE_GCC3_OPTIONS: Replacing command line option '%s' with '%s %s'\n",
argv[i], rep_option, rep_arg);
if (n_overrides+1 >= env_override_options_max)
{
env_override_options_max += 6;
env_override_options = (struct env_overrides *)
xrealloc (env_override_options,
sizeof (struct env_overrides)
* env_override_options_max);
if (n_overrides == 0)
++n_overrides;
}
env_override_options[n_overrides ].option = rep_option;
env_override_options[n_overrides++].flags = env_ovr_has_arg | env_ovr_add_arg | env_over_no_msg;
env_override_options[n_overrides ].option = rep_arg;
env_override_options[n_overrides++].flags = env_ovr_add_arg | env_over_no_msg;
argv[i] = NULL;
have_added_opts = 1;
}
else if (strcmp (argv[i], rep_option) != 0)
{
if (env_ovr_confirm
&& (env_override_options[j].flags & env_ovr_used) == 0)
fprintf (stderr,
"### QA_OVERRIDE_GCC3_OPTIONS: Replacing command line option '%s' with '%s'\n",
argv[i], rep_option);
argv[i] = rep_option;
}
}
else
{
if (env_ovr_confirm
&& (env_override_options[j].flags & env_ovr_used) == 0)
fprintf (stderr, "### QA_OVERRIDE_GCC3_OPTIONS: Deleting command line option '%s", argv[i]);
if (parg)
{
if (env_ovr_confirm
&& (env_override_options[j].flags & env_ovr_used) == 0)
fprintf (stderr, " %s", argv[i + 1]);
argv[i + 1] = NULL;
}
if (env_ovr_confirm
&& (env_override_options[j].flags & env_ovr_used) == 0)
fputs ("'\n", stderr);
argv[i] = NULL;
}
}
*(repopt-1) = s;
env_override_options[j].flags |= env_ovr_used;
return argv[i] != NULL;
}
else if (strcmp (argv[i], env_override_options[j].option) != 0)
{
if (env_ovr_confirm
&& (env_override_options[j].flags & env_ovr_used) == 0)
fprintf (stderr,
"### QA_OVERRIDE_GCC3_OPTIONS: Overriding command line option '%s' with '%s'\n",
argv[i], env_override_options[j].option);
argv[i] = env_override_options[j].option;
env_override_options[j].flags |= env_ovr_used;
return 1;
}
}
else if (s)
*(repopt-1) = s;
}
return 1;
}
static int
add_env_options (unsigned int *argc, const char ***argv)
{
static unsigned int save_argc;
static const char **save_argv;
if (have_added_opts)
{
if (!add_env_opts)
{
save_argv = *argv;
save_argc = *argc;
*argc = n_overrides;
*argv = xmalloc (n_overrides * sizeof (char *));
add_env_opts = 1;
return 1;
}
free (*argv);
*argc = save_argc;
*argv = save_argv;
add_env_opts = 0;
}
return 0;
}
void
add_input_filename (const char *filename)
{
num_in_fnames++;
in_fnames = xrealloc (in_fnames, num_in_fnames * sizeof (in_fnames[0]));
in_fnames[num_in_fnames - 1] = filename;
}
void
decode_options (unsigned int argc, const char **argv)
{
unsigned int i, lang_mask;
lang_mask = lang_hooks.init_options (argc, argv);
lang_hooks.initialize_diagnostics (global_dc);
for (i = 1; i < argc; i++)
{
if (!strcmp (argv[i], "-O"))
{
optimize = 1;
optimize_size = 0;
}
else if (argv[i][0] == '-' && argv[i][1] == 'O')
{
const char *p = &argv[i][2];
if ((p[0] == 's') && (p[1] == 0))
{
optimize_size = 1;
optimize = 2;
}
else
{
const int optimize_val = read_integral_parameter (p, p - 2, -1);
if (optimize_val != -1)
{
optimize = optimize_val;
optimize_size = 0;
}
}
}
else if (argv[i][0] == '-' && argv[i][1] == 'f')
{
const char *p = &argv[i][2];
if (!strcmp(p, "ast"))
flag_fast = 1;
else if (!strcmp(p, "astf"))
flag_fastf = 1;
else if (!strcmp(p, "astcp"))
flag_fastcp = 1;
}
}
if (flag_fast || flag_fastf || flag_fastcp )
{
optimize = 3;
optimize_size = 0;
if (flag_fast || flag_fastcp)
flag_no_common = 1;
}
override_O_option ();
if (!optimize)
{
flag_merge_constants = 0;
}
if (optimize >= 1)
{
flag_defer_pop = 1;
flag_thread_jumps = 1;
#ifdef DELAY_SLOTS
flag_delayed_branch = 1;
#endif
#ifdef CAN_DEBUG_WITHOUT_FP
flag_omit_frame_pointer = 1;
#endif
flag_guess_branch_prob = 1;
flag_cprop_registers = 1;
flag_loop_optimize2 = 1;
flag_if_conversion = 1;
flag_if_conversion2 = 1;
flag_tree_ccp = 1;
flag_tree_dce = 1;
flag_tree_dom = 1;
flag_tree_dse = 1;
flag_tree_loop = 1;
flag_tree_vectorize = 0;
flag_tree_pre = 1;
flag_scalar_evolutions = 0;
flag_all_data_deps = 0;
flag_tree_elim_checks = 0;
flag_ddg = 0;
flag_tree_ter = 1;
flag_tree_live_range_split = 1;
flag_tree_sra = 1;
flag_tree_copyrename = 1;
if (!optimize_size)
{
flag_tree_ch = 1;
}
}
if (optimize >= 2)
{
flag_crossjumping = 1;
flag_optimize_sibling_calls = 1;
flag_cse_follow_jumps = 1;
flag_cse_skip_blocks = 1;
flag_gcse = 1;
flag_expensive_optimizations = 1;
flag_strength_reduce = 1;
flag_rerun_cse_after_loop = 1;
flag_rerun_loop_opt = 1;
flag_caller_saves = 1;
flag_force_mem = 1;
flag_peephole2 = 1;
#ifdef INSN_SCHEDULING
flag_schedule_insns = 1;
flag_schedule_insns_after_reload = 1;
#endif
flag_regmove = 1;
flag_strict_aliasing = 1;
flag_delete_null_pointer_checks = 1;
flag_reorder_blocks = 1;
flag_reorder_functions = 1;
flag_unit_at_a_time = 1;
}
if (optimize >= 3)
{
flag_inline_functions = 1;
flag_unswitch_loops = 1;
flag_gcse_after_reload = 1;
}
if (optimize < 2 || optimize_size)
{
align_loops = 1;
align_jumps = 1;
align_labels = 1;
align_functions = 1;
flag_reorder_blocks = 0;
flag_reorder_blocks_and_partition = 0;
}
if (optimize_size)
{
set_param_value ("max-inline-insns-single", 5);
set_param_value ("max-inline-insns-auto", 5);
set_param_value ("max-inline-insns-rtl", 10);
flag_inline_functions = 1;
}
flag_signed_char = DEFAULT_SIGNED_CHAR;
flag_short_enums = 2;
target_flags = 0;
set_target_switch ("");
#ifdef IA64_UNWIND_INFO
flag_unwind_tables = IA64_UNWIND_INFO;
#endif
#ifdef OPTIMIZATION_OPTIONS
OPTIMIZATION_OPTIONS (optimize, optimize_size);
#endif
handle_options (argc, argv, lang_mask);
if (flag_pie)
flag_pic = flag_pie;
if (flag_pic && !flag_pie)
flag_shlib = 1;
if (flag_no_inline == 2)
flag_no_inline = 0;
else
flag_really_no_inline = flag_no_inline;
if (optimize == 0)
{
flag_no_inline = 1;
warn_inline = 0;
if (warn_uninitialized == 1)
warning ("-Wuninitialized is not supported without -O");
}
if (flag_really_no_inline == 2)
flag_really_no_inline = flag_no_inline;
if (flag_exceptions && flag_reorder_blocks_and_partition)
{
warning
("-freorder-blocks-and-partition does not work with exceptions");
flag_reorder_blocks_and_partition = 0;
flag_reorder_blocks = 1;
}
}
static int
common_handle_option (size_t scode, const char *arg,
int value ATTRIBUTE_UNUSED)
{
enum opt_code code = (enum opt_code) scode;
switch (code)
{
default:
abort ();
case OPT_arch:
break;
case OPT__help:
print_help ();
exit_after_options = true;
break;
case OPT__param:
handle_param (arg);
break;
case OPT__target_help:
display_target_options ();
exit_after_options = true;
break;
case OPT__version:
print_version (stderr, "");
exit_after_options = true;
break;
case OPT_G:
g_switch_value = value;
g_switch_set = true;
break;
case OPT_O:
case OPT_Os:
break;
case OPT_W:
set_Wextra (value);
break;
case OPT_Waggregate_return:
warn_aggregate_return = value;
break;
case OPT_Wcast_align:
warn_cast_align = value;
break;
case OPT_Wdeprecated_declarations:
warn_deprecated_decl = value;
break;
case OPT_Wdisabled_optimization:
warn_disabled_optimization = value;
break;
case OPT_Werror:
warnings_are_errors = value;
break;
case OPT_Wextra:
set_Wextra (value);
break;
case OPT_Wfatal_errors:
flag_fatal_errors = value;
break;
case OPT_Winline:
warn_inline = value;
break;
case OPT_Wlarger_than_:
larger_than_size = value;
warn_larger_than = value != -1;
break;
case OPT_Wmissing_noreturn:
warn_missing_noreturn = value;
break;
case OPT_Wpacked:
warn_packed = value;
break;
case OPT_Wpadded:
warn_padded = value;
break;
case OPT_Wshadow:
warn_shadow = value;
break;
case OPT_Wstrict_aliasing:
case OPT_Wstrict_aliasing_:
warn_strict_aliasing = value;
break;
case OPT_Wswitch:
warn_switch = value;
break;
case OPT_Wswitch_default:
warn_switch_default = value;
break;
case OPT_Wswitch_enum:
warn_switch_enum = value;
break;
case OPT_Wsystem_headers:
warn_system_headers = value;
break;
case OPT_Wuninitialized:
warn_uninitialized = value;
break;
case OPT_Wunreachable_code:
warn_notreached = value;
break;
case OPT_Wunused:
set_Wunused (value);
break;
case OPT_Wunused_function:
warn_unused_function = value;
break;
case OPT_Wunused_label:
warn_unused_label = value;
break;
case OPT_Wunused_parameter:
warn_unused_parameter = value;
break;
case OPT_Wunused_value:
warn_unused_value = value;
break;
case OPT_Wunused_variable:
warn_unused_variable = value;
break;
case OPT_aux_info:
case OPT_aux_info_:
aux_info_file_name = arg;
flag_gen_aux_info = 1;
break;
case OPT_auxbase:
aux_base_name = arg;
break;
case OPT_auxbase_strip:
{
char *tmp = xstrdup (arg);
strip_off_ending (tmp, strlen (tmp));
if (tmp[0])
aux_base_name = tmp;
}
break;
case OPT_d:
decode_d_option (arg);
break;
case OPT_dumpbase:
dump_base_name = arg;
break;
case OPT_fPIC:
flag_pic = value + value;
break;
case OPT_fPIE:
flag_pie = value + value;
break;
case OPT_floop_transpose:
flag_loop_transpose = value;
break;
case OPT_fabi_version_:
flag_abi_version = value;
break;
case OPT_falign_functions:
align_functions = !value;
break;
case OPT_falign_functions_:
align_functions = value;
break;
case OPT_falign_jumps:
align_jumps = !value;
break;
case OPT_falign_jumps_:
align_jumps = value;
break;
case OPT_falign_labels:
align_labels = !value;
break;
case OPT_falign_labels_:
align_labels = value;
break;
case OPT_falign_loops:
align_loops = !value;
break;
case OPT_falign_loops_:
align_loops = value;
break;
case OPT_fpredictive_compilation:
predictive_compilation = 0;
break;
case OPT_fpredictive_compilation_:
{
char* buf = xmalloc (strlen(arg) + 1);
sprintf (buf, "%d", value);
if (strcmp(buf, arg))
{
error ("argument to \"-fpredictive-compilation=\" should be a valid non-negative integer instead of \"%s\"", arg);
value = 0;
}
free(buf);
predictive_compilation = value;
break;
}
case OPT_fargument_alias:
flag_argument_noalias = !value;
break;
case OPT_fargument_noalias:
flag_argument_noalias = value;
break;
case OPT_fargument_noalias_global:
flag_argument_noalias = value + value;
break;
case OPT_fasynchronous_unwind_tables:
flag_asynchronous_unwind_tables = value;
break;
case OPT_fbounds_check:
flag_bounds_check = value;
break;
case OPT_fbranch_count_reg:
flag_branch_on_count_reg = value;
break;
case OPT_fbranch_probabilities:
flag_branch_probabilities_set = true;
flag_branch_probabilities = value;
break;
case OPT_fbranch_target_load_optimize:
flag_branch_target_load_optimize = value;
break;
case OPT_fbranch_target_load_optimize2:
flag_branch_target_load_optimize2 = value;
break;
case OPT_fbtr_bb_exclusive:
flag_btr_bb_exclusive = value;
break;
case OPT_fcall_used_:
fix_register (arg, 0, 1);
break;
case OPT_fcall_saved_:
fix_register (arg, 0, 0);
break;
case OPT_fcaller_saves:
flag_caller_saves = value;
break;
case OPT_fcommon:
flag_no_common = !value;
break;
case OPT_fcprop_registers:
flag_cprop_registers = value;
break;
case OPT_fcrossjumping:
flag_crossjumping = value;
break;
case OPT_fcse_follow_jumps:
flag_cse_follow_jumps = value;
break;
case OPT_fcse_skip_blocks:
flag_cse_skip_blocks = value;
break;
case OPT_fdata_sections:
flag_data_sections = value;
break;
case OPT_fdefer_pop:
flag_defer_pop = value;
break;
case OPT_fdelayed_branch:
flag_delayed_branch = value;
break;
case OPT_fdelete_null_pointer_checks:
flag_delete_null_pointer_checks = value;
break;
case OPT_fdiagnostics_show_location_:
if (!strcmp (arg, "once"))
diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
else if (!strcmp (arg, "every-line"))
diagnostic_prefixing_rule (global_dc)
= DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE;
else
return 0;
break;
case OPT_fdump_:
if (!dump_switch_p (arg))
return 0;
break;
case OPT_fdump_unnumbered:
flag_dump_unnumbered = value;
break;
case OPT_feliminate_dwarf2_dups:
flag_eliminate_dwarf2_dups = value;
break;
case OPT_feliminate_unused_debug_types:
flag_eliminate_unused_debug_types = value;
break;
case OPT_feliminate_unused_debug_symbols:
flag_debug_only_used_symbols = value;
break;
case OPT_fexceptions:
flag_exceptions = value;
break;
case OPT_fexpensive_optimizations:
flag_expensive_optimizations = value;
break;
case OPT_ffast_math:
set_fast_math_flags (value);
break;
case OPT_ffinite_math_only:
flag_finite_math_only = value;
break;
case OPT_ffixed_:
fix_register (arg, 1, 1);
break;
case OPT_ffunction_cse:
flag_no_function_cse = !value;
break;
case OPT_ffloat_store:
flag_float_store = value;
break;
case OPT_fforce_addr:
flag_force_addr = value;
break;
case OPT_fforce_mem:
flag_force_mem = value;
break;
case OPT_ffunction_sections:
flag_function_sections = value;
break;
case OPT_fgcse:
flag_gcse = value;
break;
case OPT_fgcse_lm:
flag_gcse_lm = value;
break;
case OPT_fgcse_sm:
flag_gcse_sm = value;
break;
case OPT_fgcse_after_reload:
flag_gcse_after_reload = value;
break;
case OPT_fgcse_las:
flag_gcse_las = value;
break;
case OPT_fguess_branch_probability:
flag_guess_branch_prob = value;
break;
case OPT_fident:
flag_no_ident = !value;
break;
case OPT_fif_conversion:
flag_if_conversion = value;
break;
case OPT_fif_conversion2:
flag_if_conversion2 = value;
break;
case OPT_finhibit_size_directive:
flag_inhibit_size_directive = value;
break;
case OPT_finline:
flag_no_inline = !value;
break;
case OPT_finline_functions:
flag_inline_functions = value;
break;
case OPT_finline_limit_:
case OPT_finline_limit_eq:
set_param_value ("max-inline-insns-single", value / 2);
set_param_value ("max-inline-insns-auto", value / 2);
set_param_value ("max-inline-insns-rtl", value);
break;
case OPT_finstrument_functions:
flag_instrument_function_entry_exit = value;
break;
case OPT_fkeep_inline_functions:
flag_keep_inline_functions =value;
break;
case OPT_fkeep_static_consts:
flag_keep_static_consts = value;
break;
case OPT_fleading_underscore:
flag_leading_underscore = value;
break;
case OPT_floop_optimize:
flag_loop_optimize = value;
break;
case OPT_floop_optimize2:
flag_loop_optimize2 = value;
break;
case OPT_fmath_errno:
flag_errno_math = value;
break;
case OPT_fmem_report:
mem_report = value;
break;
case OPT_fmerge_all_constants:
flag_merge_constants = value + value;
break;
case OPT_fmerge_constants:
flag_merge_constants = value;
break;
case OPT_fmessage_length_:
pp_set_line_maximum_length (global_dc->printer, value);
break;
case OPT_fmove_all_movables:
flag_move_all_movables = value;
break;
case OPT_fmudflap:
flag_mudflap = value;
break;
case OPT_fmudflapth:
flag_mudflap = value;
flag_mudflap_threads = value;
break;
case OPT_fmudflapir:
flag_mudflap_ignore_reads = value;
break;
case OPT_fnew_ra:
flag_new_regalloc = value;
break;
case OPT_fnon_call_exceptions:
flag_non_call_exceptions = value;
break;
case OPT_fomit_frame_pointer:
flag_omit_frame_pointer = value;
break;
case OPT_foptimize_register_move:
flag_regmove = value;
break;
case OPT_foptimize_sibling_calls:
flag_optimize_sibling_calls = value;
break;
case OPT_fpack_struct:
flag_pack_struct = value;
break;
case OPT_fpeel_loops:
flag_peel_loops_set = true;
flag_peel_loops = value;
break;
case OPT_fpcc_struct_return:
flag_pcc_struct_return = value;
break;
case OPT_fpeephole:
flag_no_peephole = !value;
break;
case OPT_fpeephole2:
flag_peephole2 = value;
break;
case OPT_fpic:
flag_pic = value;
break;
case OPT_fpie:
flag_pie = value;
break;
case OPT_fprefetch_loop_arrays:
flag_prefetch_loop_arrays = value;
break;
case OPT_fprofile:
profile_flag = value;
break;
case OPT_fprofile_arcs:
profile_arc_flag_set = true;
profile_arc_flag = value;
break;
case OPT_fuse_profile:
case OPT_fprofile_use:
if (!flag_branch_probabilities_set)
flag_branch_probabilities = value;
if (!flag_profile_values_set)
flag_profile_values = value;
if (!flag_unroll_loops_set)
flag_unroll_loops = value;
if (!flag_peel_loops_set)
flag_peel_loops = value;
if (!flag_tracer_set)
flag_tracer = value;
if (!flag_value_profile_transformations_set)
flag_value_profile_transformations = value;
break;
case OPT_fcreate_profile:
case OPT_fprofile_generate:
if (!profile_arc_flag_set)
profile_arc_flag = value;
if (!flag_profile_values_set)
flag_profile_values = value;
if (!flag_value_profile_transformations_set)
flag_value_profile_transformations = value;
break;
case OPT_fprofile_values:
flag_profile_values_set = true;
flag_profile_values = value;
break;
case OPT_fvpt:
flag_value_profile_transformations_set = value;
flag_value_profile_transformations = value;
break;
case OPT_frandom_seed:
if (value)
return 0;
flag_random_seed = NULL;
break;
case OPT_frandom_seed_:
flag_random_seed = arg;
break;
case OPT_freduce_all_givs:
flag_reduce_all_givs = value;
break;
case OPT_freg_struct_return:
flag_pcc_struct_return = !value;
break;
case OPT_fregmove:
flag_regmove = value;
break;
case OPT_frename_registers:
flag_rename_registers = value;
break;
case OPT_freorder_blocks:
flag_reorder_blocks = value;
break;
case OPT_freorder_blocks_and_partition:
flag_reorder_blocks_and_partition = value;
break;
case OPT_freorder_functions:
flag_reorder_functions = value;
break;
case OPT_frerun_cse_after_loop:
flag_rerun_cse_after_loop = value;
break;
case OPT_frerun_loop_opt:
flag_rerun_loop_opt = value;
break;
case OPT_frounding_math:
flag_rounding_math = value;
break;
case OPT_fsched_interblock:
flag_schedule_interblock = value;
break;
case OPT_fsched_spec:
flag_schedule_speculative = value;
break;
case OPT_fsched_spec_load:
flag_schedule_speculative_load = value;
break;
case OPT_fsched_spec_load_dangerous:
flag_schedule_speculative_load_dangerous = value;
break;
case OPT_fsched_verbose_:
#ifdef INSN_SCHEDULING
fix_sched_param ("verbose", arg);
break;
#else
return 0;
#endif
case OPT_fsched2_use_superblocks:
flag_sched2_use_superblocks = value;
break;
case OPT_fsched2_use_traces:
flag_sched2_use_traces = value;
break;
case OPT_fschedule_insns:
flag_schedule_insns = value;
break;
case OPT_fschedule_insns2:
flag_schedule_insns_after_reload = value;
break;
case OPT_fsched_stalled_insns:
flag_sched_stalled_insns = value;
break;
case OPT_fsched_stalled_insns_:
flag_sched_stalled_insns = value;
if (flag_sched_stalled_insns == 0)
flag_sched_stalled_insns = -1;
break;
case OPT_fsched_stalled_insns_dep:
flag_sched_stalled_insns_dep = 1;
break;
case OPT_fsched_stalled_insns_dep_:
flag_sched_stalled_insns_dep = value;
break;
case OPT_fmodulo_sched:
flag_modulo_sched = 1;
break;
case OPT_fshared_data:
flag_shared_data = value;
break;
case OPT_fsignaling_nans:
flag_signaling_nans = value;
break;
case OPT_fsingle_precision_constant:
flag_single_precision_constant = value;
break;
case OPT_fstack_check:
flag_stack_check = value;
break;
case OPT_fstack_limit:
if (value)
return 0;
stack_limit_rtx = NULL_RTX;
break;
case OPT_fstack_limit_register_:
{
int reg = decode_reg_name (arg);
if (reg < 0)
error ("unrecognized register name \"%s\"", arg);
else
stack_limit_rtx = gen_rtx_REG (Pmode, reg);
}
break;
case OPT_fstack_limit_symbol_:
stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (arg));
break;
case OPT_fstrength_reduce:
flag_strength_reduce = value;
break;
case OPT_fstrict_aliasing:
flag_strict_aliasing = value;
break;
case OPT_fsyntax_only:
flag_syntax_only = value;
break;
case OPT_ftest_coverage:
flag_test_coverage = value;
break;
case OPT_fthread_jumps:
flag_thread_jumps = value;
break;
case OPT_ftime_report:
time_report = value;
break;
case OPT_ftls_model_:
if (!strcmp (arg, "global-dynamic"))
flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC;
else if (!strcmp (arg, "local-dynamic"))
flag_tls_default = TLS_MODEL_LOCAL_DYNAMIC;
else if (!strcmp (arg, "initial-exec"))
flag_tls_default = TLS_MODEL_INITIAL_EXEC;
else if (!strcmp (arg, "local-exec"))
flag_tls_default = TLS_MODEL_LOCAL_EXEC;
else
warning ("unknown tls-model \"%s\"", arg);
break;
case OPT_ftracer:
flag_tracer_set = true;
flag_tracer = value;
break;
case OPT_ftrapping_math:
flag_trapping_math = value;
break;
case OPT_ftrapv:
flag_trapv = value;
break;
case OPT_ftree_based_profiling:
flag_tree_based_profiling = value;
break;
case OPT_ftree_ccp:
flag_tree_ccp = value;
break;
case OPT_ftree_dce:
flag_tree_dce = value;
break;
case OPT_fscalar_evolutions:
flag_scalar_evolutions = value;
break;
case OPT_fall_data_deps:
flag_all_data_deps = value;
break;
case OPT_ftree_loop_linear:
flag_tree_loop_linear = value;
break;
case OPT_ftree_loop_optimize:
flag_tree_loop = value;
break;
case OPT_ftree_elim_checks:
flag_tree_elim_checks = value;
break;
case OPT_ftree_ddg:
flag_ddg = value;
break;
case OPT_ftree_vectorize:
flag_tree_vectorize = value;
break;
case OPT_ftree_combine_temps:
flag_tree_combine_temps = value;
break;
case OPT_ftree_ter:
flag_tree_ter = value;
break;
case OPT_ftree_lrs:
flag_tree_live_range_split = value;
break;
case OPT_ftree_dominator_opts:
flag_tree_dom = value;
break;
case OPT_ftree_copyrename:
flag_tree_copyrename = value;
break;
case OPT_ftree_ch:
flag_tree_ch = value;
break;
case OPT_ftree_dse:
flag_tree_dse = value;
break;
case OPT_ftree_sra:
flag_tree_sra = value;
break;
case OPT_ftree_points_to_:
if (!strcmp (arg, "andersen"))
#ifdef HAVE_BANSHEE
flag_tree_points_to = PTA_ANDERSEN;
#else
warning ("Andersen's PTA not available - libbanshee not compiled.");
#endif
else if (!strcmp (arg, "none"))
flag_tree_points_to = PTA_NONE;
else
{
warning ("`%s`: unknown points-to analysis algorithm", arg);
return 0;
}
break;
case OPT_ftree_pre:
flag_tree_pre = value;
break;
case OPT_funit_at_a_time:
flag_unit_at_a_time = value;
break;
case OPT_funroll_all_loops:
flag_unroll_all_loops = value;
break;
case OPT_funroll_loops:
flag_unroll_loops_set = true;
flag_unroll_loops = value;
break;
case OPT_funsafe_math_optimizations:
flag_unsafe_math_optimizations = value;
break;
case OPT_funswitch_loops:
flag_unswitch_loops = value;
break;
case OPT_funwind_tables:
flag_unwind_tables = value;
break;
case OPT_fvar_tracking:
flag_var_tracking = value;
break;
case OPT_fverbose_asm:
flag_verbose_asm = value;
break;
case OPT_fweb:
flag_web = value;
break;
case OPT_fwrapv:
flag_wrapv = value;
break;
case OPT_fzero_initialized_in_bss:
flag_zero_initialized_in_bss = value;
break;
case OPT_g:
set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg);
break;
case OPT_gcoff:
set_debug_level (SDB_DEBUG, false, arg);
break;
case OPT_gdwarf_2:
set_debug_level (DWARF2_DEBUG, false, arg);
break;
case OPT_ggdb:
set_debug_level (NO_DEBUG, 2, arg);
break;
case OPT_gstabs:
case OPT_gstabs_:
set_debug_level (DBX_DEBUG, code == OPT_gstabs_, arg);
break;
case OPT_gvms:
set_debug_level (VMS_DEBUG, false, arg);
break;
case OPT_gxcoff:
case OPT_gxcoff_:
set_debug_level (XCOFF_DEBUG, code == OPT_gxcoff_, arg);
break;
case OPT_m:
set_target_switch (arg);
break;
case OPT_o:
asm_file_name = arg;
break;
case OPT_p:
profile_flag = 1;
break;
case OPT_pedantic:
pedantic = 1;
break;
case OPT_pedantic_errors:
flag_pedantic_errors = pedantic = 1;
break;
case OPT_quiet:
quiet_flag = 1;
break;
case OPT_version:
version_flag = 1;
break;
case OPT_w:
inhibit_warnings = true;
break;
}
return 1;
}
static void
handle_param (const char *carg)
{
char *equal, *arg;
int value;
arg = xstrdup (carg);
equal = strchr (arg, '=');
if (!equal)
error ("%s: --param arguments should be of the form NAME=VALUE", arg);
else
{
value = integral_argument (equal + 1);
if (value == -1)
error ("invalid --param value `%s'", equal + 1);
else
{
*equal = '\0';
set_param_value (arg, value);
}
}
free (arg);
}
static void
set_Wextra (int setting)
{
extra_warnings = setting;
warn_unused_value = setting;
warn_unused_parameter = (setting && maybe_warn_unused_parameter);
if (setting == 0)
warn_uninitialized = 0;
else if (warn_uninitialized != 1)
warn_uninitialized = 2;
}
void
set_Wunused (int setting)
{
warn_unused_function = setting;
warn_unused_label = setting;
maybe_warn_unused_parameter = setting;
warn_unused_parameter = (setting && extra_warnings);
warn_unused_variable = setting;
warn_unused_value = setting;
}
void
set_fast_math_flags (int set)
{
flag_trapping_math = !set;
flag_unsafe_math_optimizations = set;
flag_finite_math_only = set;
flag_errno_math = !set;
if (set)
{
flag_signaling_nans = 0;
flag_rounding_math = 0;
}
}
bool
fast_math_flags_set_p (void)
{
return (!flag_trapping_math
&& flag_unsafe_math_optimizations
&& flag_finite_math_only
&& !flag_errno_math);
}
static void
set_debug_level (enum debug_info_type type, int extended, const char *arg)
{
static bool type_explicit;
int g_all_len = 0;
use_gnu_debug_info_extensions = extended;
#ifdef DBX_ONLY_USED_SYMBOLS
if (strncmp (arg, "full", 4) == 0 || strncmp (arg, "-full", 5) == 0)
{
char *p = (char *)arg + (*(char *)arg == '-') + 4;
flag_debug_only_used_symbols = 0;
if (*p == '-')
++p;
g_all_len = p - arg;
arg += g_all_len;
}
if (strncmp (arg, "used", 4) == 0 || strncmp (arg, "-used", 5) == 0)
{
char *p = (char *)arg + (*(char *)arg == '-') + 4;
flag_debug_only_used_symbols = 1;
if (*p == '-')
++p;
g_all_len = p - arg;
arg += g_all_len;
}
#endif
if (strncmp (arg, "repository", 10) == 0 || strncmp (arg, "-repository", 11) == 0)
{
char *p = (char *)arg + (*(char *)arg == '-') + 10;
flag_grepository = 1;
if (*p == '-')
++p;
g_all_len = p - arg;
arg += g_all_len;
}
if (type == NO_DEBUG)
{
if (write_symbols == NO_DEBUG)
{
write_symbols = PREFERRED_DEBUGGING_TYPE;
if (extended == 2)
{
#ifdef DWARF2_DEBUGGING_INFO
write_symbols = DWARF2_DEBUG;
#elif defined DBX_DEBUGGING_INFO
write_symbols = DBX_DEBUG;
#endif
write_symbols = DBX_DEBUG;
}
if (write_symbols == NO_DEBUG)
warning ("target system does not support debug output");
}
}
else
{
if (type_explicit && write_symbols != NO_DEBUG && type != write_symbols)
error ("debug format \"%s\" conflicts with prior selection",
debug_type_names[type]);
write_symbols = type;
type_explicit = true;
}
if (*arg == '\0')
{
if (!debug_info_level)
debug_info_level = 2;
}
else
{
debug_info_level = integral_argument (arg);
if (debug_info_level == (unsigned int) -1)
error ("unrecognised debug output level \"%s\"", arg);
else if (debug_info_level > 3)
error ("debug output level %s is too high", arg);
}
orig_write_symbols = write_symbols;
}
static void
print_help (void)
{
size_t i;
const char *p;
GET_ENVIRONMENT (p, "COLUMNS");
if (p)
{
int value = atoi (p);
if (value > 0)
columns = value;
}
puts (_("The following options are language-independent:\n"));
print_filtered_help (CL_COMMON);
print_param_help ();
for (i = 0; lang_names[i]; i++)
{
printf (_("The %s front end recognizes the following options:\n\n"),
lang_names[i]);
print_filtered_help (1U << i);
}
display_target_options ();
}
static void
print_param_help (void)
{
size_t i;
puts (_("The --param option recognizes the following as parameters:\n"));
for (i = 0; i < LAST_PARAM; i++)
{
const char *help = compiler_params[i].help;
const char *param = compiler_params[i].option;
if (help == NULL || *help == '\0')
help = undocumented_msg;
help = _(help);
wrap_help (help, param, strlen (param));
}
putchar ('\n');
}
static void
print_filtered_help (unsigned int flag)
{
unsigned int i, len, filter, indent = 0;
bool duplicates = false;
const char *help, *opt, *tab;
static char *printed;
if (flag == CL_COMMON)
{
filter = flag;
if (!printed)
printed = xmalloc (cl_options_count);
memset (printed, 0, cl_options_count);
}
else
{
filter = flag | CL_COMMON;
for (i = 0; i < cl_options_count; i++)
{
if ((cl_options[i].flags & filter) != flag)
continue;
if (cl_options[i].flags & CL_UNDOCUMENTED)
continue;
if (printed[i])
{
duplicates = true;
indent = print_switch (cl_options[i].opt_text, indent);
}
}
if (duplicates)
{
putchar ('\n');
putchar ('\n');
}
}
for (i = 0; i < cl_options_count; i++)
{
if ((cl_options[i].flags & filter) != flag)
continue;
if (cl_options[i].flags & CL_UNDOCUMENTED)
continue;
if (printed[i])
continue;
printed[i] = true;
help = cl_options[i].help;
if (!help)
help = undocumented_msg;
help = _(help);
tab = strchr (help, '\t');
if (tab)
{
len = tab - help;
opt = help;
help = tab + 1;
}
else
{
opt = cl_options[i].opt_text;
len = strlen (opt);
}
wrap_help (help, opt, len);
}
putchar ('\n');
}
static unsigned int
print_switch (const char *text, unsigned int indent)
{
unsigned int len = strlen (text) + 1;
if (indent)
{
putchar (',');
if (indent + len > columns)
{
putchar ('\n');
putchar (' ');
indent = 1;
}
}
else
putchar (' ');
putchar (' ');
fputs (text, stdout);
return indent + len + 1;
}
static void
wrap_help (const char *help, const char *item, unsigned int item_width)
{
unsigned int col_width = 27;
unsigned int remaining, room, len;
remaining = strlen (help);
do
{
room = columns - 3 - MAX (col_width, item_width);
if (room > columns)
room = 0;
len = remaining;
if (room < len)
{
unsigned int i;
for (i = 0; help[i]; i++)
{
if (i >= room && len != remaining)
break;
if (help[i] == ' ')
len = i;
else if ((help[i] == '-' || help[i] == '/')
&& help[i + 1] != ' '
&& i > 0 && ISALPHA (help[i - 1]))
len = i + 1;
}
}
printf( " %-*.*s %.*s\n", col_width, item_width, item, len, help);
item_width = 0;
while (help[len] == ' ')
len++;
help += len;
remaining -= len;
}
while (remaining);
}