|
Mixe for Privacy and Anonymity in the Internet
|
00001 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ 00002 00003 /* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING 00004 file accompanying popt source distributions, available from 00005 ftp://ftp.redhat.com/pub/code/popt */ 00006 00007 #include "../StdAfx.h" 00008 #include "poptint.h" 00009 00010 static void displayArgs(poptContext con, 00011 /*@unused@*/ enum poptCallbackReason /*foo*/, 00012 struct poptOption * key, 00013 /*@unused@*/ const char * /*arg*/, /*@unused@*/ void * /*data*/) { 00014 if (key->shortName== '?') 00015 poptPrintHelp(con, stdout, 0); 00016 else 00017 poptPrintUsage(con, stdout, 0); 00018 exit(0); 00019 } 00020 00021 struct poptOption poptHelpOptions[] = { 00022 { NULL, '\0', POPT_ARG_CALLBACK, (void *)&displayArgs, '\0', NULL, NULL }, 00023 { "help", '?', 0, NULL, '?', N_("Show this help message"), NULL }, 00024 { "usage", 'u', 0, NULL, 'u', N_("Display brief usage message"), NULL }, 00025 { NULL, '\0', 0, NULL, 0, NULL, NULL } 00026 } ; 00027 00028 00029 /*@observer@*/ /*@null@*/ static const char *const 00030 getTableTranslationDomain(const struct poptOption *table) 00031 { 00032 const struct poptOption *opt; 00033 00034 for(opt = table; 00035 opt->longName || opt->shortName || opt->arg; 00036 opt++) { 00037 if(opt->argInfo == POPT_ARG_INTL_DOMAIN) 00038 return (const char* const)opt->arg; 00039 } 00040 00041 return NULL; 00042 } 00043 00044 /*@observer@*/ /*@null@*/ static const char *const 00045 getArgDescrip(const struct poptOption * opt, const char *translation_domain) 00046 { 00047 if (!(opt->argInfo & POPT_ARG_MASK)) return NULL; 00048 00049 if (opt == (poptHelpOptions + 1) || opt == (poptHelpOptions + 2)) 00050 if (opt->argDescrip) return POPT_(opt->argDescrip); 00051 00052 if (opt->argDescrip) return D_(translation_domain, opt->argDescrip); 00053 return POPT_("ARG"); 00054 } 00055 00056 static void singleOptionHelp(FILE * f, int maxLeftCol, 00057 const struct poptOption * opt, 00058 const char *translation_domain) { 00059 int indentLength = maxLeftCol + 5; 00060 int lineLength = 79 - indentLength; 00061 const char * help = D_(translation_domain, opt->descrip); 00062 int helpLength; 00063 const char * ch; 00064 char format[130]; 00065 char * left; 00066 const char * argDescrip = getArgDescrip(opt, translation_domain); 00067 00068 left = (char*)malloc(maxLeftCol + 1); 00069 *left = '\0'; 00070 00071 if (opt->longName && opt->shortName) 00072 sprintf(left, "-%c, --%s", opt->shortName, opt->longName); 00073 else if (opt->shortName) 00074 sprintf(left, "-%c", opt->shortName); 00075 else if (opt->longName) 00076 sprintf(left, "--%s", opt->longName); 00077 if (!*left) return ; 00078 if (argDescrip) { 00079 strcat(left, "="); 00080 strcat(left, argDescrip); 00081 } 00082 00083 if (help) 00084 fprintf(f," %-*s ", maxLeftCol, left); 00085 else { 00086 fprintf(f," %s\n", left); 00087 goto out; 00088 } 00089 00090 helpLength = strlen(help); 00091 while (helpLength > lineLength) { 00092 ch = help + lineLength - 1; 00093 while (ch > help && !isspace(*ch)) ch--; 00094 if (ch == help) break; /* give up */ 00095 while (ch > (help + 1) && isspace(*ch)) ch--; 00096 ch++; 00097 00098 sprintf(format, "%%.%ds\n%%%ds", (int) (ch - help), indentLength); 00099 fprintf(f, format, help, " "); 00100 help = ch; 00101 while (isspace(*help) && *help) help++; 00102 helpLength = strlen(help); 00103 } 00104 00105 if (helpLength) fprintf(f, "%s\n", help); 00106 00107 out: 00108 free(left); 00109 } 00110 00111 static int maxArgWidth(const struct poptOption * opt, 00112 const char * translation_domain) { 00113 int max = 0; 00114 int thiS; 00115 const char * s; 00116 00117 while (opt->longName || opt->shortName || opt->arg) { 00118 if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { 00119 thiS = maxArgWidth((struct poptOption*)opt->arg, translation_domain); 00120 if (thiS > max) max = thiS; 00121 } else if (!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) { 00122 thiS = opt->shortName ? 2 : 0; 00123 if (opt->longName) { 00124 if (thiS) thiS += 2; 00125 thiS += strlen(opt->longName) + 2; 00126 } 00127 00128 s = getArgDescrip(opt, translation_domain); 00129 if (s) 00130 thiS += strlen(s) + 1; 00131 if (thiS > max) max = thiS; 00132 } 00133 00134 opt++; 00135 } 00136 00137 return max; 00138 } 00139 00140 static void singleTableHelp(FILE * f, const struct poptOption * table, 00141 int left, 00142 const char *translation_domain) { 00143 const struct poptOption * opt; 00144 const char *sub_transdom; 00145 00146 opt = table; 00147 while (opt->longName || opt->shortName || opt->arg) { 00148 if ((opt->longName || opt->shortName) && 00149 !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) 00150 singleOptionHelp(f, left, opt, translation_domain); 00151 opt++; 00152 } 00153 00154 opt = table; 00155 while (opt->longName || opt->shortName || opt->arg) { 00156 if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { 00157 sub_transdom = getTableTranslationDomain((struct poptOption*)opt->arg); 00158 if(!sub_transdom) 00159 sub_transdom = translation_domain; 00160 00161 if (opt->descrip) 00162 fprintf(f, "\n%s\n", D_(sub_transdom, opt->descrip)); 00163 00164 singleTableHelp(f, (struct poptOption*)opt->arg, left, sub_transdom); 00165 } 00166 opt++; 00167 } 00168 00169 } 00170 00171 static int showHelpIntro(poptContext con, FILE * f) { 00172 int len = 6; 00173 const char * fn; 00174 00175 fprintf(f, POPT_("Usage:")); 00176 if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) { 00177 fn = con->optionStack->argv[0]; 00178 if (strchr(fn, '/')) fn = strchr(fn, '/') + 1; 00179 fprintf(f, " %s", fn); 00180 len += strlen(fn) + 1; 00181 } 00182 00183 return len; 00184 } 00185 00186 void poptPrintHelp(poptContext con, FILE * f, /*@unused@*/ int /*flags*/) { 00187 int leftColWidth; 00188 00189 showHelpIntro(con, f); 00190 if (con->otherHelp) 00191 fprintf(f, " %s\n", con->otherHelp); 00192 else 00193 fprintf(f, " %s\n", POPT_("[OPTION...]")); 00194 00195 leftColWidth = maxArgWidth(con->options, NULL); 00196 singleTableHelp(f, con->options, leftColWidth, NULL); 00197 } 00198 00199 static int singleOptionUsage(FILE * f, int cursor, 00200 const struct poptOption * opt, 00201 const char *translation_domain) { 00202 int len = 3; 00203 char shortStr[2] = { '\0', '\0' }; 00204 const char * item = shortStr; 00205 const char * argDescrip = getArgDescrip(opt, translation_domain); 00206 00207 if (opt->shortName) { 00208 if (!(opt->argInfo & POPT_ARG_MASK)) 00209 return cursor; /* we did these already */ 00210 len++; 00211 *shortStr = opt->shortName; 00212 shortStr[1] = '\0'; 00213 } else if (opt->longName) { 00214 len += 1 + strlen(opt->longName); 00215 item = opt->longName; 00216 } 00217 00218 if (len == 3) return cursor; 00219 00220 if (argDescrip) 00221 len += strlen(argDescrip) + 1; 00222 00223 if ((cursor + len) > 79) { 00224 fprintf(f, "\n "); 00225 cursor = 7; 00226 } 00227 00228 fprintf(f, " [-%s%s%s%s]", opt->shortName ? "" : "-", item, 00229 argDescrip ? (opt->shortName ? " " : "=") : "", 00230 argDescrip ? argDescrip : ""); 00231 00232 return cursor + len + 1; 00233 } 00234 00235 static int singleTableUsage(FILE * f, int cursor, const struct poptOption * table, 00236 const char *translation_domain) { 00237 const struct poptOption * opt; 00238 00239 opt = table; 00240 while (opt->longName || opt->shortName || opt->arg) { 00241 if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) 00242 translation_domain = (const char *)opt->arg; 00243 else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) 00244 cursor = singleTableUsage(f, cursor, (struct poptOption*)opt->arg, 00245 translation_domain); 00246 else if ((opt->longName || opt->shortName) && 00247 !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) 00248 cursor = singleOptionUsage(f, cursor, opt, translation_domain); 00249 00250 opt++; 00251 } 00252 00253 return cursor; 00254 } 00255 00256 static int showShortOptions(const struct poptOption * opt, FILE * f, 00257 char * str) { 00258 char s[300]; /* this is larger then the ascii set, so 00259 it should do just fine */ 00260 00261 s[0] = '\0'; 00262 if (str == NULL) { 00263 memset(s, 0, sizeof(s)); 00264 str = s; 00265 } 00266 00267 while (opt->longName || opt->shortName || opt->arg) { 00268 if (opt->shortName && !(opt->argInfo & POPT_ARG_MASK)) 00269 str[strlen(str)] = opt->shortName; 00270 else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) 00271 showShortOptions((struct poptOption*)opt->arg, f, str); 00272 00273 opt++; 00274 } 00275 00276 if (s != str || !*s) 00277 return 0; 00278 00279 fprintf(f, " [-%s]", s); 00280 return strlen(s) + 4; 00281 } 00282 00283 void poptPrintUsage(poptContext con, FILE * f, /*@unused@*/ int /*flags*/) { 00284 int cursor; 00285 00286 cursor = showHelpIntro(con, f); 00287 cursor += showShortOptions(con->options, f, NULL); 00288 singleTableUsage(f, cursor, con->options, NULL); 00289 00290 if (con->otherHelp) { 00291 cursor += strlen(con->otherHelp) + 1; 00292 if (cursor > 79) fprintf(f, "\n "); 00293 fprintf(f, " %s", con->otherHelp); 00294 } 00295 00296 fprintf(f, "\n"); 00297 } 00298 00299 void poptSetOtherOptionHelp(poptContext con, const char * text) { 00300 if (con->otherHelp) xfree(con->otherHelp); 00301 con->otherHelp = xstrdup(text); 00302 }
1.7.6.1