Mixe for Privacy and Anonymity in the Internet
popthelp.cpp
Go to the documentation of this file.
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 
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 */
6 
7 #include "../StdAfx.h"
8 #include "poptint.h"
9 
10 static void displayArgs(poptContext con,
11  /*@unused@*/ enum poptCallbackReason /*foo*/,
12  struct poptOption * key,
13  /*@unused@*/ const char * /*arg*/, /*@unused@*/ void * /*data*/) {
14  if (key->shortName== '?')
15  poptPrintHelp(con, stdout, 0);
16  else
17  poptPrintUsage(con, stdout, 0);
18  exit(0);
19 }
20 
21 struct poptOption poptHelpOptions[] = {
22  { NULL, '\0', POPT_ARG_CALLBACK, (void *)&displayArgs, '\0', NULL, NULL },
23  { "help", '?', 0, NULL, '?', N_("Show this help message"), NULL },
24  { "usage", 'u', 0, NULL, 'u', N_("Display brief usage message"), NULL },
25  { NULL, '\0', 0, NULL, 0, NULL, NULL }
26 } ;
27 
28 
29 /*@observer@*/ /*@null@*/ static const char *const
30 getTableTranslationDomain(const struct poptOption *table)
31 {
32  const struct poptOption *opt;
33 
34  for(opt = table;
35  opt->longName || opt->shortName || opt->arg;
36  opt++) {
37  if(opt->argInfo == POPT_ARG_INTL_DOMAIN)
38  return (const char* const)opt->arg;
39  }
40 
41  return NULL;
42 }
43 
44 /*@observer@*/ /*@null@*/ static const char *const
45 getArgDescrip(const struct poptOption * opt, const char *translation_domain)
46 {
47  if (!(opt->argInfo & POPT_ARG_MASK)) return NULL;
48 
49  if (opt == (poptHelpOptions + 1) || opt == (poptHelpOptions + 2))
50  if (opt->argDescrip) return POPT_(opt->argDescrip);
51 
52  if (opt->argDescrip) return D_(translation_domain, opt->argDescrip);
53  return POPT_("ARG");
54 }
55 
56 static void singleOptionHelp(FILE * f, int maxLeftCol,
57  const struct poptOption * opt,
58  const char *translation_domain) {
59  int indentLength = maxLeftCol + 5;
60  int lineLength = 79 - indentLength;
61  const char * help = D_(translation_domain, opt->descrip);
62  int helpLength;
63  const char * ch;
64  char format[130];
65  char * left;
66  const char * argDescrip = getArgDescrip(opt, translation_domain);
67 
68  left = (char*)malloc(maxLeftCol + 1);
69  *left = '\0';
70 
71  if (opt->longName && opt->shortName)
72  sprintf(left, "-%c, --%s", opt->shortName, opt->longName);
73  else if (opt->shortName)
74  sprintf(left, "-%c", opt->shortName);
75  else if (opt->longName)
76  sprintf(left, "--%s", opt->longName);
77  if (!*left) return ;
78  if (argDescrip) {
79  strcat(left, "=");
80  strcat(left, argDescrip);
81  }
82 
83  if (help)
84  fprintf(f," %-*s ", maxLeftCol, left);
85  else {
86  fprintf(f," %s\n", left);
87  goto out;
88  }
89 
90  helpLength = strlen(help);
91  while (helpLength > lineLength) {
92  ch = help + lineLength - 1;
93  while (ch > help && !isspace(*ch)) ch--;
94  if (ch == help) break; /* give up */
95  while (ch > (help + 1) && isspace(*ch)) ch--;
96  ch++;
97 
98  sprintf(format, "%%.%ds\n%%%ds", (int) (ch - help), indentLength);
99  fprintf(f, format, help, " ");
100  help = ch;
101  while (isspace(*help) && *help) help++;
102  helpLength = strlen(help);
103  }
104 
105  if (helpLength) fprintf(f, "%s\n", help);
106 
107  out:
108  free(left);
109 }
110 
111 static int maxArgWidth(const struct poptOption * opt,
112  const char * translation_domain) {
113  int max = 0;
114  int thiS;
115  const char * s;
116 
117  while (opt->longName || opt->shortName || opt->arg) {
118  if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
119  thiS = maxArgWidth((struct poptOption*)opt->arg, translation_domain);
120  if (thiS > max) max = thiS;
121  } else if (!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
122  thiS = opt->shortName ? 2 : 0;
123  if (opt->longName) {
124  if (thiS) thiS += 2;
125  thiS += strlen(opt->longName) + 2;
126  }
127 
128  s = getArgDescrip(opt, translation_domain);
129  if (s)
130  thiS += strlen(s) + 1;
131  if (thiS > max) max = thiS;
132  }
133 
134  opt++;
135  }
136 
137  return max;
138 }
139 
140 static void singleTableHelp(FILE * f, const struct poptOption * table,
141  int left,
142  const char *translation_domain) {
143  const struct poptOption * opt;
144  const char *sub_transdom;
145 
146  opt = table;
147  while (opt->longName || opt->shortName || opt->arg) {
148  if ((opt->longName || opt->shortName) &&
150  singleOptionHelp(f, left, opt, translation_domain);
151  opt++;
152  }
153 
154  opt = table;
155  while (opt->longName || opt->shortName || opt->arg) {
156  if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
157  sub_transdom = getTableTranslationDomain((struct poptOption*)opt->arg);
158  if(!sub_transdom)
159  sub_transdom = translation_domain;
160 
161  if (opt->descrip)
162  fprintf(f, "\n%s\n", D_(sub_transdom, opt->descrip));
163 
164  singleTableHelp(f, (struct poptOption*)opt->arg, left, sub_transdom);
165  }
166  opt++;
167  }
168 
169 }
170 
171 static int showHelpIntro(poptContext con, FILE * f) {
172  int len = 6;
173  const char * fn;
174 
175  fprintf(f, POPT_("Usage:"));
176  if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) {
177  fn = con->optionStack->argv[0];
178  if (strchr(fn, '/')) fn = strchr(fn, '/') + 1;
179  fprintf(f, " %s", fn);
180  len += strlen(fn) + 1;
181  }
182 
183  return len;
184 }
185 
186 void poptPrintHelp(poptContext con, FILE * f, /*@unused@*/ int /*flags*/) {
187  int leftColWidth;
188 
189  showHelpIntro(con, f);
190  if (con->otherHelp)
191  fprintf(f, " %s\n", con->otherHelp);
192  else
193  fprintf(f, " %s\n", POPT_("[OPTION...]"));
194 
195  leftColWidth = maxArgWidth(con->options, NULL);
196  singleTableHelp(f, con->options, leftColWidth, NULL);
197 }
198 
199 static int singleOptionUsage(FILE * f, int cursor,
200  const struct poptOption * opt,
201  const char *translation_domain) {
202  int len = 3;
203  char shortStr[2] = { '\0', '\0' };
204  const char * item = shortStr;
205  const char * argDescrip = getArgDescrip(opt, translation_domain);
206 
207  if (opt->shortName) {
208  if (!(opt->argInfo & POPT_ARG_MASK))
209  return cursor; /* we did these already */
210  len++;
211  *shortStr = opt->shortName;
212  shortStr[1] = '\0';
213  } else if (opt->longName) {
214  len += 1 + strlen(opt->longName);
215  item = opt->longName;
216  }
217 
218  if (len == 3) return cursor;
219 
220  if (argDescrip)
221  len += strlen(argDescrip) + 1;
222 
223  if ((cursor + len) > 79) {
224  fprintf(f, "\n ");
225  cursor = 7;
226  }
227 
228  fprintf(f, " [-%s%s%s%s]", opt->shortName ? "" : "-", item,
229  argDescrip ? (opt->shortName ? " " : "=") : "",
230  argDescrip ? argDescrip : "");
231 
232  return cursor + len + 1;
233 }
234 
235 static int singleTableUsage(FILE * f, int cursor, const struct poptOption * table,
236  const char *translation_domain) {
237  const struct poptOption * opt;
238 
239  opt = table;
240  while (opt->longName || opt->shortName || opt->arg) {
242  translation_domain = (const char *)opt->arg;
243  else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
244  cursor = singleTableUsage(f, cursor, (struct poptOption*)opt->arg,
245  translation_domain);
246  else if ((opt->longName || opt->shortName) &&
248  cursor = singleOptionUsage(f, cursor, opt, translation_domain);
249 
250  opt++;
251  }
252 
253  return cursor;
254 }
255 
256 static int showShortOptions(const struct poptOption * opt, FILE * f,
257  char * str) {
258  char s[300]; /* this is larger then the ascii set, so
259  it should do just fine */
260 
261  s[0] = '\0';
262  if (str == NULL) {
263  memset(s, 0, sizeof(s));
264  str = s;
265  }
266 
267  while (opt->longName || opt->shortName || opt->arg) {
268  if (opt->shortName && !(opt->argInfo & POPT_ARG_MASK))
269  str[strlen(str)] = opt->shortName;
270  else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
271  showShortOptions((struct poptOption*)opt->arg, f, str);
272 
273  opt++;
274  }
275 
276  if (s != str || !*s)
277  return 0;
278 
279  fprintf(f, " [-%s]", s);
280  return strlen(s) + 4;
281 }
282 
283 void poptPrintUsage(poptContext con, FILE * f, /*@unused@*/ int /*flags*/) {
284  int cursor;
285 
286  cursor = showHelpIntro(con, f);
287  cursor += showShortOptions(con->options, f, NULL);
288  singleTableUsage(f, cursor, con->options, NULL);
289 
290  if (con->otherHelp) {
291  cursor += strlen(con->otherHelp) + 1;
292  if (cursor > 79) fprintf(f, "\n ");
293  fprintf(f, " %s", con->otherHelp);
294  }
295 
296  fprintf(f, "\n");
297 }
298 
299 void poptSetOtherOptionHelp(poptContext con, const char * text) {
300  if (con->otherHelp) xfree(con->otherHelp);
301  con->otherHelp = xstrdup(text);
302 }
#define max(a, b)
Definition: StdAfx.h:654
#define POPT_CONTEXT_KEEP_FIRST
Definition: popt.h:45
#define POPT_ARG_MASK
Definition: popt.h:24
#define POPT_ARGFLAG_DOC_HIDDEN
Definition: popt.h:26
#define POPT_ARG_INTL_DOMAIN
Definition: popt.h:22
#define POPT_ARG_INCLUDE_TABLE
Definition: popt.h:20
#define POPT_ARG_CALLBACK
Definition: popt.h:21
poptCallbackReason
Definition: popt.h:74
struct poptOption poptHelpOptions[]
Definition: popthelp.cpp:21
void poptPrintHelp(poptContext con, FILE *f, int)
Definition: popthelp.cpp:186
void poptSetOtherOptionHelp(poptContext con, const char *text)
Definition: popthelp.cpp:299
void poptPrintUsage(poptContext con, FILE *f, int)
Definition: popthelp.cpp:283
#define POPT_(foo)
Definition: poptint.h:81
#define xfree(_a)
Definition: poptint.h:65
#define N_(foo)
Definition: poptint.h:85
#define D_(dom, str)
Definition: poptint.h:82
const char ** argv
Definition: poptint.h:26
const struct poptOption * options
Definition: poptint.h:47
const char * otherHelp
Definition: poptint.h:61
struct optionStackEntry optionStack[POPT_OPTION_DEPTH]
Definition: poptint.h:42
int argInfo
Definition: popt.h:51
void * arg
Definition: popt.h:52
char shortName
Definition: popt.h:50
const char * argDescrip
Definition: popt.h:55
const char * longName
Definition: popt.h:49
const char * descrip
Definition: popt.h:54
char * xstrdup(const char *str)
UINT16 len
Definition: typedefs.hpp:0