Reverted the use of bool in favour of gboolean
[midnight-commander.git] / src / popthelp.c
blob801acacb96680296607225d5d7d7108b5b4779a4
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
3 /* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
4 file accompanying popt source distributions, available from
5 ftp://ftp.redhat.com/pub/code/popt */
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
11 #include <ctype.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
16 #include "global.h"
17 #include "popt.h"
18 #include "poptint.h"
20 static void displayArgs(poptContext con, enum poptCallbackReason foo,
21 struct poptOption * key,
22 const char * arg, void * data)
24 (void) foo;
25 (void) arg;
26 (void) data;
28 if (key->shortName== '?')
29 poptPrintHelp(con, stdout, 0);
30 else
31 poptPrintUsage(con, stdout, 0);
32 exit(0);
35 struct poptOption const poptHelpOptions[] = {
36 { NULL, '\0', POPT_ARG_CALLBACK, (void *)&displayArgs, '\0', NULL, NULL },
37 { "help", '?', 0, NULL, '?', N_("Show this help message"), NULL },
38 { "usage", '\0', 0, NULL, 'u', N_("Display brief usage message"), NULL },
39 { NULL, '\0', 0, NULL, 0, NULL, NULL }
40 } ;
43 static const char *
44 getTableTranslationDomain(const struct poptOption *table)
46 const struct poptOption *opt;
48 for(opt = table;
49 opt->longName || opt->shortName || opt->arg;
50 opt++) {
51 if(opt->argInfo == POPT_ARG_INTL_DOMAIN)
52 return opt->arg;
55 return NULL;
58 static const char * getArgDescrip(const struct poptOption * opt,
59 const char *translation_domain) {
60 (void) translation_domain;
62 if (!(opt->argInfo & POPT_ARG_MASK)) return NULL;
64 if (opt == (poptHelpOptions + 1) || opt == (poptHelpOptions + 2))
65 if (opt->argDescrip) return POPT_(opt->argDescrip);
67 if (opt->argDescrip) return D_(translation_domain, opt->argDescrip);
68 return _("ARG");
71 static void singleOptionHelp(FILE * f, int maxLeftCol,
72 const struct poptOption * opt,
73 const char *translation_domain) {
74 int indentLength = maxLeftCol + 5;
75 int lineLength = 79 - indentLength;
76 const char * help = D_(translation_domain, opt->descrip);
77 int helpLength;
78 const char * ch;
79 char * left;
80 const char * argDescrip = getArgDescrip(opt, translation_domain);
82 left = malloc(maxLeftCol + 1);
83 *left = '\0';
85 if (opt->longName && opt->shortName)
86 sprintf(left, "-%c, --%s", opt->shortName, opt->longName);
87 else if (opt->shortName)
88 sprintf(left, "-%c", opt->shortName);
89 else if (opt->longName)
90 sprintf(left, "--%s", opt->longName);
91 if (!*left) return ;
92 if (argDescrip) {
93 strcat(left, "=");
94 strcat(left, argDescrip);
97 if (help)
98 fprintf(f," %-*s ", maxLeftCol, left);
99 else {
100 fprintf(f," %s\n", left);
101 goto out;
104 helpLength = strlen(help);
105 while (helpLength > lineLength) {
106 ch = help + lineLength - 1;
107 while (ch > help && !isspace((unsigned char) *ch)) ch--;
108 if (ch == help) break; /* give up */
109 while (ch > (help + 1) && isspace((unsigned char) *ch)) ch--;
110 ch++;
112 fprintf(f, "%.*s\n%*s", (int) (ch - help), help, indentLength, " ");
113 help = ch;
114 while (isspace((unsigned char) *help) && *help) help++;
115 helpLength = strlen(help);
118 if (helpLength) fprintf(f, "%s\n", help);
120 out:
121 free(left);
124 static int maxArgWidth(const struct poptOption * opt,
125 const char * translation_domain) {
126 int max = 0;
127 int this;
128 const char * s;
130 while (opt->longName || opt->shortName || opt->arg) {
131 if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
132 this = maxArgWidth(opt->arg, translation_domain);
133 if (this > max) max = this;
134 } else if (!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
135 this = opt->shortName ? 2 : 0;
136 if (opt->longName) {
137 if (this) this += 2;
138 this += strlen(opt->longName) + 2;
141 s = getArgDescrip(opt, translation_domain);
142 if (s)
143 this += strlen(s) + 1;
144 if (this > max) max = this;
147 opt++;
150 return max;
153 static void singleTableHelp(FILE * f, const struct poptOption * table,
154 int left,
155 const char *translation_domain) {
156 const struct poptOption * opt;
157 const char *sub_transdom;
159 opt = table;
160 while (opt->longName || opt->shortName || opt->arg) {
161 if ((opt->longName || opt->shortName) &&
162 !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
163 singleOptionHelp(f, left, opt, translation_domain);
164 opt++;
167 opt = table;
168 while (opt->longName || opt->shortName || opt->arg) {
169 if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
170 sub_transdom = getTableTranslationDomain(opt->arg);
171 if(!sub_transdom)
172 sub_transdom = translation_domain;
174 if (opt->descrip)
175 fprintf(f, "\n%s\n", D_(sub_transdom, opt->descrip));
177 singleTableHelp(f, opt->arg, left, sub_transdom);
179 opt++;
183 static int showHelpIntro(poptContext con, FILE * f) {
184 int len = 6;
185 const char * fn;
187 fprintf(f, _("Usage:"));
188 if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) {
189 fn = con->optionStack->argv[0];
190 if (strrchr(fn, '/')) fn = strrchr(fn, '/') + 1;
191 fprintf(f, " %s", fn);
192 len += strlen(fn) + 1;
195 return len;
198 int poptPrintHelp(poptContext con, FILE * f, int flags) {
199 int leftColWidth;
201 (void) flags;
203 showHelpIntro(con, f);
204 if (con->otherHelp)
205 fprintf(f, " %s\n", con->otherHelp);
206 else
207 fprintf(f, " %s\n", POPT_("[OPTION...]"));
209 leftColWidth = maxArgWidth(con->options, NULL);
210 singleTableHelp(f, con->options, leftColWidth, NULL);
211 return leftColWidth;
214 static int singleOptionUsage(FILE * f, int cursor,
215 const struct poptOption * opt,
216 const char *translation_domain) {
217 int len = 3;
218 char shortStr[2];
219 const char * item = shortStr;
220 const char * argDescrip = getArgDescrip(opt, translation_domain);
222 if (opt->shortName) {
223 if (!(opt->argInfo & POPT_ARG_MASK))
224 return cursor; /* we did these already */
225 len++;
226 *shortStr = opt->shortName;
227 shortStr[1] = '\0';
228 } else if (opt->longName) {
229 len += 1 + strlen(opt->longName);
230 item = opt->longName;
233 if (len == 3) return cursor;
235 if (argDescrip)
236 len += strlen(argDescrip) + 1;
238 if ((cursor + len) > 79) {
239 fprintf(f, "\n ");
240 cursor = 7;
243 fprintf(f, " [-%s%s%s%s]", opt->shortName ? "" : "-", item,
244 argDescrip ? (opt->shortName ? " " : "=") : "",
245 argDescrip ? argDescrip : "");
247 return cursor + len + 1;
250 static int singleTableUsage(FILE * f, int cursor, const struct poptOption * table,
251 const char *translation_domain) {
252 const struct poptOption * opt;
254 opt = table;
255 while (opt->longName || opt->shortName || opt->arg) {
256 if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN)
257 translation_domain = (const char *)opt->arg;
258 else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
259 cursor = singleTableUsage(f, cursor, opt->arg,
260 translation_domain);
261 else if ((opt->longName || opt->shortName) &&
262 !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
263 cursor = singleOptionUsage(f, cursor, opt, translation_domain);
265 opt++;
268 return cursor;
271 static int showShortOptions(const struct poptOption * opt, FILE * f,
272 char * str) {
273 char s[300]; /* this is larger then the ascii set, so
274 it should do just fine */
276 if (!str) {
277 str = s;
278 memset(str, 0, sizeof(s));
281 while (opt->longName || opt->shortName || opt->arg) {
282 if (opt->shortName && !(opt->argInfo & POPT_ARG_MASK))
283 str[strlen(str)] = opt->shortName;
284 else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
285 showShortOptions(opt->arg, f, str);
287 opt++;
290 if (s != str || !*s)
291 return 0;
293 fprintf(f, " [-%s]", s);
294 return strlen(s) + 4;
297 void poptPrintUsage(poptContext con, FILE * f, int flags) {
298 int cursor;
300 (void) flags;
302 cursor = showHelpIntro(con, f);
303 cursor += showShortOptions(con->options, f, NULL);
304 singleTableUsage(f, cursor, con->options, NULL);
306 if (con->otherHelp) {
307 cursor += strlen(con->otherHelp) + 1;
308 if (cursor > 79) fprintf(f, "\n ");
309 fprintf(f, " %s", con->otherHelp);
312 fprintf(f, "\n");
315 void poptSetOtherOptionHelp(poptContext con, const char * text) {
316 if (con->otherHelp) free(con->otherHelp);
317 con->otherHelp = strdup(text);