Just a little correction at the it.po file.
[midnight-commander.git] / src / popthelp.c
blobb220b0b7c69347d80b1ce2f10322825a68cd44d0
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 "popt.h"
17 #include "poptint.h"
19 static void displayArgs(poptContext con, enum poptCallbackReason foo,
20 struct poptOption * key,
21 const char * arg, void * data) {
22 if (key->shortName== '?')
23 poptPrintHelp(con, stdout, 0);
24 else
25 poptPrintUsage(con, stdout, 0);
26 exit(0);
29 struct poptOption const poptHelpOptions[] = {
30 { NULL, '\0', POPT_ARG_CALLBACK, (void *)&displayArgs, '\0', NULL },
31 { "help", '?', 0, NULL, '?', N_("Show this help message") },
32 { "usage", '\0', 0, NULL, 'u', N_("Display brief usage message") },
33 { NULL, '\0', 0, NULL, 0 }
34 } ;
37 static const char *
38 getTableTranslationDomain(const struct poptOption *table)
40 const struct poptOption *opt;
42 for(opt = table;
43 opt->longName || opt->shortName || opt->arg;
44 opt++) {
45 if(opt->argInfo == POPT_ARG_INTL_DOMAIN)
46 return opt->arg;
49 return NULL;
52 static const char * getArgDescrip(const struct poptOption * opt,
53 const char *translation_domain) {
54 if (!(opt->argInfo & POPT_ARG_MASK)) return NULL;
56 if (opt == (poptHelpOptions + 1) || opt == (poptHelpOptions + 2))
57 if (opt->argDescrip) return POPT_(opt->argDescrip);
59 if (opt->argDescrip) return D_(translation_domain, opt->argDescrip);
60 return _("ARG");
63 static void singleOptionHelp(FILE * f, int maxLeftCol,
64 const struct poptOption * opt,
65 const char *translation_domain) {
66 int indentLength = maxLeftCol + 5;
67 int lineLength = 79 - indentLength;
68 const unsigned char * help = D_(translation_domain, opt->descrip);
69 int helpLength;
70 const unsigned char * ch;
71 char * left;
72 const char * argDescrip = getArgDescrip(opt, translation_domain);
74 left = malloc(maxLeftCol + 1);
75 *left = '\0';
77 if (opt->longName && opt->shortName)
78 sprintf(left, "-%c, --%s", opt->shortName, opt->longName);
79 else if (opt->shortName)
80 sprintf(left, "-%c", opt->shortName);
81 else if (opt->longName)
82 sprintf(left, "--%s", opt->longName);
83 if (!*left) return ;
84 if (argDescrip) {
85 strcat(left, "=");
86 strcat(left, argDescrip);
89 if (help)
90 fprintf(f," %-*s ", maxLeftCol, left);
91 else {
92 fprintf(f," %s\n", left);
93 goto out;
96 helpLength = strlen(help);
97 while (helpLength > lineLength) {
98 ch = help + lineLength - 1;
99 while (ch > help && !isspace(*ch)) ch--;
100 if (ch == help) break; /* give up */
101 while (ch > (help + 1) && isspace(*ch)) ch--;
102 ch++;
104 fprintf(f, "%.*s\n%*s", (int) (ch - help), help, indentLength, " ");
105 help = ch;
106 while (isspace(*help) && *help) help++;
107 helpLength = strlen(help);
110 if (helpLength) fprintf(f, "%s\n", help);
112 out:
113 free(left);
116 static int maxArgWidth(const struct poptOption * opt,
117 const char * translation_domain) {
118 int max = 0;
119 int this;
120 const char * s;
122 while (opt->longName || opt->shortName || opt->arg) {
123 if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
124 this = maxArgWidth(opt->arg, translation_domain);
125 if (this > max) max = this;
126 } else if (!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
127 this = opt->shortName ? 2 : 0;
128 if (opt->longName) {
129 if (this) this += 2;
130 this += strlen(opt->longName) + 2;
133 s = getArgDescrip(opt, translation_domain);
134 if (s)
135 this += strlen(s) + 1;
136 if (this > max) max = this;
139 opt++;
142 return max;
145 static void singleTableHelp(FILE * f, const struct poptOption * table,
146 int left,
147 const char *translation_domain) {
148 const struct poptOption * opt;
149 const char *sub_transdom;
151 opt = table;
152 while (opt->longName || opt->shortName || opt->arg) {
153 if ((opt->longName || opt->shortName) &&
154 !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
155 singleOptionHelp(f, left, opt, translation_domain);
156 opt++;
159 opt = table;
160 while (opt->longName || opt->shortName || opt->arg) {
161 if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
162 sub_transdom = getTableTranslationDomain(opt->arg);
163 if(!sub_transdom)
164 sub_transdom = translation_domain;
166 if (opt->descrip)
167 fprintf(f, "\n%s\n", D_(sub_transdom, opt->descrip));
169 singleTableHelp(f, opt->arg, left, sub_transdom);
171 opt++;
175 static int showHelpIntro(poptContext con, FILE * f) {
176 int len = 6;
177 char * fn;
179 fprintf(f, _("Usage:"));
180 if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) {
181 fn = con->optionStack->argv[0];
182 if (strchr(fn, '/')) fn = strchr(fn, '/') + 1;
183 fprintf(f, " %s", fn);
184 len += strlen(fn) + 1;
187 return len;
190 int poptPrintHelp(poptContext con, FILE * f, int flags) {
191 int leftColWidth;
193 showHelpIntro(con, f);
194 if (con->otherHelp)
195 fprintf(f, " %s\n", con->otherHelp);
196 else
197 fprintf(f, " %s\n", POPT_("[OPTION...]"));
199 leftColWidth = maxArgWidth(con->options, NULL);
200 singleTableHelp(f, con->options, leftColWidth, NULL);
201 return leftColWidth;
204 static int singleOptionUsage(FILE * f, int cursor,
205 const struct poptOption * opt,
206 const char *translation_domain) {
207 int len = 3;
208 char shortStr[2];
209 const char * item = shortStr;
210 const char * argDescrip = getArgDescrip(opt, translation_domain);
212 if (opt->shortName) {
213 if (!(opt->argInfo & POPT_ARG_MASK))
214 return cursor; /* we did these already */
215 len++;
216 *shortStr = opt->shortName;
217 shortStr[1] = '\0';
218 } else if (opt->longName) {
219 len += 1 + strlen(opt->longName);
220 item = opt->longName;
223 if (len == 3) return cursor;
225 if (argDescrip)
226 len += strlen(argDescrip) + 1;
228 if ((cursor + len) > 79) {
229 fprintf(f, "\n ");
230 cursor = 7;
233 fprintf(f, " [-%s%s%s%s]", opt->shortName ? "" : "-", item,
234 argDescrip ? (opt->shortName ? " " : "=") : "",
235 argDescrip ? argDescrip : "");
237 return cursor + len + 1;
240 static int singleTableUsage(FILE * f, int cursor, const struct poptOption * table,
241 const char *translation_domain) {
242 const struct poptOption * opt;
244 opt = table;
245 while (opt->longName || opt->shortName || opt->arg) {
246 if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN)
247 translation_domain = (const char *)opt->arg;
248 else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
249 cursor = singleTableUsage(f, cursor, opt->arg,
250 translation_domain);
251 else if ((opt->longName || opt->shortName) &&
252 !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
253 cursor = singleOptionUsage(f, cursor, opt, translation_domain);
255 opt++;
258 return cursor;
261 static int showShortOptions(const struct poptOption * opt, FILE * f,
262 char * str) {
263 char s[300]; /* this is larger then the ascii set, so
264 it should do just fine */
266 if (!str) {
267 str = s;
268 memset(str, 0, sizeof(s));
271 while (opt->longName || opt->shortName || opt->arg) {
272 if (opt->shortName && !(opt->argInfo & POPT_ARG_MASK))
273 str[strlen(str)] = opt->shortName;
274 else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
275 showShortOptions(opt->arg, f, str);
277 opt++;
280 if (s != str || !*s)
281 return 0;
283 fprintf(f, " [-%s]", s);
284 return strlen(s) + 4;
287 void poptPrintUsage(poptContext con, FILE * f, int flags) {
288 int cursor;
290 cursor = showHelpIntro(con, f);
291 cursor += showShortOptions(con->options, f, NULL);
292 singleTableUsage(f, cursor, con->options, NULL);
294 if (con->otherHelp) {
295 cursor += strlen(con->otherHelp) + 1;
296 if (cursor > 79) fprintf(f, "\n ");
297 fprintf(f, " %s", con->otherHelp);
300 fprintf(f, "\n");
303 void poptSetOtherOptionHelp(poptContext con, const char * text) {
304 if (con->otherHelp) free(con->otherHelp);
305 con->otherHelp = strdup(text);