Freeciv-3.1: /fast/freeciv/nightly/S3_1/common/fc_cmdhelp.c Source File

Freeciv-3.1

Loading...
Searching...
No Matches
fc_cmdhelp.c
Go to the documentation of this file.
1/*****************************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12*****************************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <stdarg.h>
19
20/* utility */
21#include "fciconv.h"
22#include "fcintl.h"
23#include "mem.h"
24#include "shared.h"
25#include "support.h"
26
27#include "fc_cmdhelp.h"
28
29 struct cmdarg {
30 char shortarg;
31 char *longarg;
32 char *helpstr;
33};
34
35/* 'struct cmdarg_list' and related functions. */
36#define SPECLIST_TAG cmdarg
37#define SPECLIST_TYPE struct cmdarg
38#include "speclist.h"
39#define cmdarg_list_iterate(cmdarg_list, pcmdarg) \
40 TYPED_LIST_ITERATE(struct cmdarg, cmdarg_list, pcmdarg)
41#define cmdarg_list_iterate_end LIST_ITERATE_END
42
43 struct cmdhelp {
44 char *cmdname;
45 struct cmdarg_list *cmdarglist;
46};
47
48static struct cmdarg *cmdarg_new(const char *shortarg, const char *longarg,
49 const char *helpstr);
50static void cmdarg_destroy(struct cmdarg *pcmdarg);
51static int cmdarg_compare(const struct cmdarg *const *pcmdarg0,
52 const struct cmdarg *const *pcmdarg1);
53
54/*************************************************************************/
57 struct cmdhelp *cmdhelp_new(const char *cmdname)
58{
59 struct cmdhelp *pcmdhelp = fc_calloc(1, sizeof(*pcmdhelp));
60
61 pcmdhelp->cmdname = fc_strdup(fc_basename(cmdname));
62 pcmdhelp->cmdarglist = cmdarg_list_new();
63
64 return pcmdhelp;
65}
66
67/*************************************************************************/
70 void cmdhelp_destroy(struct cmdhelp *pcmdhelp)
71{
72 if (pcmdhelp) {
73 if (pcmdhelp->cmdname) {
74 free(pcmdhelp->cmdname);
75 }
76 cmdarg_list_iterate(pcmdhelp->cmdarglist, pcmdarg) {
77 cmdarg_destroy(pcmdarg);
78 } cmdarg_list_iterate_end;
79 }
80 free(pcmdhelp);
81}
82
83/*************************************************************************/
86 void cmdhelp_add(struct cmdhelp *pcmdhelp, const char *shortarg,
87 const char *longarg, const char *helpstr, ...)
88{
89 va_list args;
90 char buf[512];
91 struct cmdarg *pcmdarg;
92
93 va_start(args, helpstr);
94 fc_vsnprintf(buf, sizeof(buf), helpstr, args);
95 va_end(args);
96
97 pcmdarg = cmdarg_new(shortarg, longarg, buf);
98 cmdarg_list_append(pcmdhelp->cmdarglist, pcmdarg);
99}
100
101/*************************************************************************/
104 void cmdhelp_display(struct cmdhelp *pcmdhelp, bool sort, bool gui_options,
105 bool report_bugs)
106{
107 fc_fprintf(stderr, _("Usage: %s [option ...]\nValid option are:\n"),
108 pcmdhelp->cmdname);
109
110 cmdarg_list_sort(pcmdhelp->cmdarglist, cmdarg_compare);
111 cmdarg_list_iterate(pcmdhelp->cmdarglist, pcmdarg) {
112 if (pcmdarg->shortarg != '\0') {
113 fc_fprintf(stderr, " -%c, --%-15s %s\n", pcmdarg->shortarg,
114 pcmdarg->longarg, pcmdarg->helpstr);
115 } else {
116 fc_fprintf(stderr, " --%-15s %s\n", pcmdarg->longarg,
117 pcmdarg->helpstr);
118 }
119 } cmdarg_list_iterate_end;
120
121 if (gui_options) {
122 char buf[128];
123
124 fc_snprintf(buf, sizeof(buf), _("Try \"%s -- --help\" for more."),
125 pcmdhelp->cmdname);
126
127 /* The nearly empty strings in the two functions below have to be adapted
128 * if the format of the command argument list above is changed.*/
129 fc_fprintf(stderr, " -- %s\n",
130 _("Pass any following options to the UI."));
131 fc_fprintf(stderr, " %s\n", buf);
132 }
133
134 if (report_bugs) {
135 /* TRANS: No full stop after the URL, could cause confusion. */
136 fc_fprintf(stderr, _("Report bugs at %s\n"), BUG_URL);
137 }
138}
139
140/*************************************************************************/
143 static struct cmdarg *cmdarg_new(const char *shortarg, const char *longarg,
144 const char *helpstr)
145{
146 struct cmdarg *pcmdarg = fc_calloc(1, sizeof(*pcmdarg));
147
148 if (shortarg && strlen(shortarg) == 1) {
149 pcmdarg->shortarg = shortarg[0];
150 } else {
151 /* '\0' means no short argument for this option. */
152 pcmdarg->shortarg = '\0';
153 }
154 pcmdarg->longarg = fc_strdup(longarg);
155 pcmdarg->helpstr = fc_strdup(helpstr);
156
157 return pcmdarg;
158}
159
160/*************************************************************************/
163 static void cmdarg_destroy(struct cmdarg *pcmdarg)
164{
165 if (pcmdarg) {
166 if (pcmdarg->longarg) {
167 free(pcmdarg->longarg);
168 }
169 if (pcmdarg->helpstr) {
170 free(pcmdarg->helpstr);
171 }
172 }
173 free(pcmdarg);
174}
175
176/*************************************************************************/
179 static int cmdarg_compare(const struct cmdarg *const *pp0,
180 const struct cmdarg *const *pp1)
181{
182 const struct cmdarg *pcmdarg0 = *pp0;
183 const struct cmdarg *pcmdarg1 = *pp1;
184 int c0, c1;
185
186 if (pcmdarg0 == NULL) {
187 return -1;
188 }
189 if (pcmdarg1 == NULL) {
190 return 1;
191 }
192
193 /* Arguments without a short option are listed at the end sorted by the
194 * long option. */
195 if (pcmdarg0->shortarg == '\0') {
196 if (pcmdarg1->shortarg == '\0') {
197 return fc_strcasecmp(pcmdarg0->longarg, pcmdarg1->longarg);
198 } else {
199 return 1;
200 }
201 }
202 if (pcmdarg1->shortarg == '\0') {
203 return -1;
204 }
205
206 /* All other are sorted alphabetically by the shortarg in the following
207 * order: AaBbCcDd... */
208 c0 = (int) (unsigned char) fc_tolower(pcmdarg0->shortarg);
209 c1 = (int) (unsigned char) fc_tolower(pcmdarg1->shortarg);
210 if (c0 == c1) {
211 return (int) (unsigned char)pcmdarg0->shortarg
212 - (int) (unsigned char)pcmdarg1->shortarg;
213 } else {
214 return c0 - c1;
215 }
216}
cmdarg_new
static struct cmdarg * cmdarg_new(const char *shortarg, const char *longarg, const char *helpstr)
Definition fc_cmdhelp.c:143
cmdarg_compare
static int cmdarg_compare(const struct cmdarg *const *pcmdarg0, const struct cmdarg *const *pcmdarg1)
Definition fc_cmdhelp.c:179
cmdhelp_destroy
void cmdhelp_destroy(struct cmdhelp *pcmdhelp)
Definition fc_cmdhelp.c:70
cmdarg_list_iterate
#define cmdarg_list_iterate(cmdarg_list, pcmdarg)
Definition fc_cmdhelp.c:39
cmdhelp_display
void cmdhelp_display(struct cmdhelp *pcmdhelp, bool sort, bool gui_options, bool report_bugs)
Definition fc_cmdhelp.c:104
cmdarg_list_iterate_end
#define cmdarg_list_iterate_end
Definition fc_cmdhelp.c:41
cmdarg_destroy
static void cmdarg_destroy(struct cmdarg *pcmdarg)
Definition fc_cmdhelp.c:163
cmdhelp_new
struct cmdhelp * cmdhelp_new(const char *cmdname)
Definition fc_cmdhelp.c:57
cmdhelp_add
void cmdhelp_add(struct cmdhelp *pcmdhelp, const char *shortarg, const char *longarg, const char *helpstr,...)
Definition fc_cmdhelp.c:86
fc_cmdhelp.h
fciconv.h
fc_fprintf
void fc_fprintf(FILE *stream, const char *format,...) fc__attribute((__format__(__printf__
fcintl.h
_
#define _(String)
Definition fcintl.h:67
mem.h
fc_calloc
#define fc_calloc(n, esz)
Definition mem.h:38
fc_strdup
#define fc_strdup(str)
Definition mem.h:43
gui_options
struct client_options gui_options
Definition options.c:71
shared.h
speclist.h
cmdarg
Definition fc_cmdhelp.c:29
cmdarg::longarg
char * longarg
Definition fc_cmdhelp.c:31
cmdarg::shortarg
char shortarg
Definition fc_cmdhelp.c:30
cmdarg::helpstr
char * helpstr
Definition fc_cmdhelp.c:32
cmdhelp
Definition fc_cmdhelp.c:43
cmdhelp::cmdarglist
struct cmdarg_list * cmdarglist
Definition fc_cmdhelp.c:45
cmdhelp::cmdname
char * cmdname
Definition fc_cmdhelp.c:44
fc_snprintf
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:969
fc_strcasecmp
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:189
fc_vsnprintf
int fc_vsnprintf(char *str, size_t n, const char *format, va_list ap)
Definition support.c:896
fc_basename
const char * fc_basename(const char *path)
Definition support.c:1296
fc_tolower
char fc_tolower(char c)
Definition support.c:1282
support.h