make the new function hoptdescribe(), which is exactly like hoptusage() except it has an additional verbose flag that tells it to do a more described list of the options

This commit is contained in:
david parsons
2022-07-31 23:34:13 -07:00
parent f8512ad0f0
commit 26ba488a8a
3 changed files with 109 additions and 33 deletions
+105 -33
View File
@@ -49,7 +49,7 @@ hopterr(ctx,val)
struct h_context *ctx; struct h_context *ctx;
{ {
int old = ctx->opterr; int old = ctx->opterr;
ctx->opterr = !!val; ctx->opterr = !!val;
return old; return old;
} }
@@ -63,14 +63,14 @@ int nropts;
{ {
int i; int i;
int dashes; int dashes;
if ( (ctx == 0) || ctx->optend || (ctx->optind >= ctx->argc) ) if ( (ctx == 0) || ctx->optend || (ctx->optind >= ctx->argc) )
return 0; return 0;
ctx->optarg = 0; ctx->optarg = 0;
ctx->optopt = 0; ctx->optopt = 0;
if ( ctx->optchar == 0) { if ( ctx->optchar == 0) {
/* check for leading - /* check for leading -
*/ */
@@ -99,7 +99,7 @@ int nropts;
*/ */
dashes = 2; dashes = 2;
} }
for ( i=0; i < nropts; i++ ) { for ( i=0; i < nropts; i++ ) {
if ( ! opts[i].optword ) if ( ! opts[i].optword )
continue; continue;
@@ -189,50 +189,122 @@ int nropts;
void void
hoptusage(char *pgm, struct h_opt opts[], int nropts, char *arguments) hoptdescribe(char *pgm, struct h_opt opts[], int nropts, char *arguments, int verbose)
{ {
int i; int i;
int optcount; int sz;
fprintf(stderr, "usage: %s", pgm); if ( verbose ) {
fprintf(stderr, "usage: %s", pgm);
if ( nropts > 0 )
fprintf(stderr, " [options]");
if ( arguments )
fprintf(stderr, " %s", arguments);
fputc('\n', stderr);
}
else
fprintf(stderr, "usage: %s", pgm);
/* print out the options that don't have flags first */ /* print out the options that don't have flags first */
for ( optcount=i=0; i < nropts; i++ ) { if ( verbose ) {
if ( opts[i].optchar && !opts[i].opthasarg) { int maxoptwidth = 0;
if (optcount == 0 ) int maxargwidth = 0;
fputs(" [-", stderr); int hasoptchar = 0;
fputc(opts[i].optchar, stderr); int j;
optcount++;
if ( nropts > 0 )
fprintf(stderr, "options:\n");
/* find column widths */
for ( i=0; i < nropts; i++ ) {
if ( opts[i].optword && (( sz = strlen(opts[i].optword) ) > maxoptwidth ) )
maxoptwidth = sz;
if ( opts[i].opthasarg && (( sz = strlen(opts[i].opthasarg) ) > maxargwidth ) )
maxargwidth = sz;
if ( opts[i].optchar )
hasoptchar = 1;
}
for ( i=0; i < nropts; i++ ) {
if ( opts[i].optword ) {
fprintf(stderr, " -%s", opts[i].optword);
j = strlen(opts[i].optword);
}
else j = -2;
while ( j++ < maxoptwidth )
fputc(' ', stderr);
if ( opts[i].optchar )
fprintf(stderr, " -%c ", opts[i].optchar);
else if ( hasoptchar )
fprintf(stderr, " ");
if ( maxargwidth > 0 ) {
if ( opts[i].opthasarg ) {
fprintf(stderr, " [%s]", opts[i].opthasarg);
j = strlen(opts[i].opthasarg);
}
else {
fprintf(stderr, " ");
j = 0;
}
while ( j++ < maxargwidth )
fputc(' ', stderr);
}
if ( opts[i].optdesc )
fprintf(stderr, " %s", opts[i].optdesc);
fputc('\n', stderr);
} }
} }
if ( optcount ) else {
fputc(']', stderr); int optcount;
/* print out the options WITH flags */ for ( optcount=i=0; i < nropts; i++ ) {
for ( i = 0; i < nropts; i++ ) if ( opts[i].optchar && !opts[i].opthasarg) {
if ( opts[i].optchar && opts[i].opthasarg) if (optcount == 0 )
fprintf(stderr, " [-%c %s]", opts[i].optchar, opts[i].opthasarg); fputs(" [-", stderr);
fputc(opts[i].optchar, stderr);
/* print out the long options */ optcount++;
for ( i = 0; i < nropts; i++ ) }
if ( opts[i].optword ) {
fprintf(stderr, " [-%s", opts[i].optword);
if ( opts[i].opthasarg )
fprintf(stderr, " %s", opts[i].opthasarg);
fputc(']', stderr);
} }
if ( optcount )
fputc(']', stderr);
/* print out the arguments string, if any */ /* print out the options WITH flags */
for ( i = 0; i < nropts; i++ )
if ( opts[i].optchar && opts[i].opthasarg)
fprintf(stderr, " [-%c %s]", opts[i].optchar, opts[i].opthasarg);
if ( arguments ) /* print out the long options */
fprintf(stderr, " %s", arguments); for ( i = 0; i < nropts; i++ )
if ( opts[i].optword ) {
fprintf(stderr, " [-%s", opts[i].optword);
if ( opts[i].opthasarg )
fprintf(stderr, " %s", opts[i].opthasarg);
fputc(']', stderr);
}
if ( arguments )
fprintf(stderr, " %s", arguments);
}
/* and we're done */ /* and we're done */
fputc('\n', stderr); fputc('\n', stderr);
} }
void
hoptusage(char *pgm, struct h_opt opts[], int nropts, char *arguments)
{
hoptdescribe(pgm, opts, nropts, arguments, 0);
}
#if DEBUG #if DEBUG
struct h_opt opts[] = { struct h_opt opts[] = {
{ 0, "css", 0, 1, "css file" }, { 0, "css", 0, 1, "css file" },
+1
View File
@@ -39,5 +39,6 @@ extern int hopterr(struct h_context *, int);
extern struct h_opt *gethopt(struct h_context *, struct h_opt*, int); extern struct h_opt *gethopt(struct h_context *, struct h_opt*, int);
extern void hoptusage(char *, struct h_opt*, int, char *); extern void hoptusage(char *, struct h_opt*, int, char *);
extern void hoptdescribe(char *, struct h_opt*, int, char *, int);
#endif/*__GETHOPT_D*/ #endif/*__GETHOPT_D*/
+3
View File
@@ -159,6 +159,7 @@ struct h_opt opts[] = {
{ 0, 0, 'o', "file", "write output to file" }, { 0, 0, 'o', "file", "write output to file" },
{ 0, "squash", 'x', 0, "squash toc labels to be more like github" }, { 0, "squash", 'x', 0, "squash toc labels to be more like github" },
{ 0, "codefmt",'X', 0, "use an external code formatter" }, { 0, "codefmt",'X', 0, "use an external code formatter" },
{ 0, "help", '?', 0, "print a detailed usage message" },
}; };
#define NROPTS (sizeof opts/sizeof opts[0]) #define NROPTS (sizeof opts/sizeof opts[0])
@@ -268,6 +269,8 @@ main(int argc, char **argv)
case 'X': use_e_codefmt = 1; case 'X': use_e_codefmt = 1;
mkd_set_flag_num(flags, MKD_FENCEDCODE); mkd_set_flag_num(flags, MKD_FENCEDCODE);
break; break;
case '?': hoptdescribe(pgm, opts, NROPTS, "[file]", 1);
return 0;
} }
} }