📄 dmalloc_argv.c
字号:
return; } /* print the usage message header */ (void)fprintf(argv_error_stream, "%s%s", USAGE_LABEL, argv_program); col_c += USAGE_LABEL_LENGTH + strlen(argv_program); /* * print all of the boolean arguments first. * NOTE: we assume they all fit on the line */ for (arg_p = args; arg_p->ar_short_arg != ARGV_LAST; arg_p++) { /* skip or-specifiers */ if (arg_p->ar_short_arg == ARGV_OR || arg_p->ar_short_arg == ARGV_XOR) { continue; } /* skip non booleans */ if (HAS_ARG(arg_p->ar_type)) { continue; } /* skip args with no short component */ if (arg_p->ar_short_arg == '\0') { continue; } if (! mark_b) { len = 2 + SHORT_PREFIX_LENGTH; prefix = " ["; /* we check for -2 here because we should have 1 arg and ] on line */ if (col_c + len > SCREEN_WIDTH - 2) { (void)fprintf(argv_error_stream, "\n%*.*s", (int)USAGE_LABEL_LENGTH, (int)USAGE_LABEL_LENGTH, ""); col_c = USAGE_LABEL_LENGTH; /* if we are the start of a line, skip any starting spaces */ if (*prefix == ' ') { prefix++; len--; } } (void)fprintf(argv_error_stream, "%s%s", prefix, SHORT_PREFIX); col_c += len; mark_b = ARGV_TRUE; } len = 1; /* we check for -1 here because we should need ] */ if (col_c + len > SCREEN_WIDTH - 1) { (void)fprintf(argv_error_stream, "]\n%*.*s", (int)USAGE_LABEL_LENGTH, (int)USAGE_LABEL_LENGTH, ""); col_c = USAGE_LABEL_LENGTH; /* restart the short option list */ (void)fprintf(argv_error_stream, "[%s", SHORT_PREFIX); col_c += 1 + SHORT_PREFIX_LENGTH; } (void)fprintf(argv_error_stream, "%c", arg_p->ar_short_arg); col_c++; } if (mark_b) { (void)fprintf(argv_error_stream, "]"); col_c++; } /* print remaining (non-boolean) arguments */ for (arg_p = args; arg_p->ar_short_arg != ARGV_LAST; arg_p++) { int var_len; char *var_str, *postfix; /* skip or-specifiers */ if (arg_p->ar_short_arg == ARGV_OR || arg_p->ar_short_arg == ARGV_XOR) { continue; } /* skip booleans types */ if (! HAS_ARG(arg_p->ar_type)) { continue; } if (arg_p->ar_var_label == NULL) { if (ARGV_TYPE(arg_p->ar_type) == ARGV_BOOL_ARG || ARGV_TYPE(arg_p->ar_type) == ARGV_BOOL_INT_ARG) { var_str = BOOL_ARG_LABEL; var_len = BOOL_ARG_LENGTH; } else { var_len = UNKNOWN_ARG_LENGTH; var_str = UNKNOWN_ARG; } } else { var_len = strlen(arg_p->ar_var_label); var_str = arg_p->ar_var_label; } if (arg_p->ar_short_arg == ARGV_MAND) { /* print the mandatory argument desc */ len = 1 + var_len; prefix = " "; postfix = ""; } else if (arg_p->ar_short_arg == ARGV_MAYBE) { /* print the maybe argument desc */ len = 2 + var_len + 1; prefix = " ["; postfix = "]"; } else { /* handle options with arguments */ /* " [" + short_prefix + char */ len = 2 + SHORT_PREFIX_LENGTH + 1; prefix = " ["; /* do we need to wrap */ if (col_c + len > SCREEN_WIDTH) { (void)fprintf(argv_error_stream, "\n%*.*s", (int)USAGE_LABEL_LENGTH, (int)USAGE_LABEL_LENGTH, ""); col_c = USAGE_LABEL_LENGTH; /* if we are the start of a line, skip any starting spaces */ if (*prefix == ' ') { prefix++; len--; } } (void)fprintf(argv_error_stream, "%s%s%c", prefix, SHORT_PREFIX, arg_p->ar_short_arg); col_c += len; len = 1 + var_len + 1; prefix = " "; postfix = "]"; } if (col_c + len > SCREEN_WIDTH) { (void)fprintf(argv_error_stream, "\n%*.*s", (int)USAGE_LABEL_LENGTH, (int)USAGE_LABEL_LENGTH, ""); col_c = USAGE_LABEL_LENGTH; /* if we are the start of a line, skip any starting spaces */ if (*prefix == ' ') { prefix++; len--; } } (void)fprintf(argv_error_stream, "%s%s%s", prefix, var_str, postfix); col_c += len; } (void)fprintf(argv_error_stream, "\n"); if (flag == ARGV_USAGE_SHORT_REM) { (void)fprintf(argv_error_stream, "%*.*sUse the '%s%s' argument for more assistance.\n", (int)USAGE_LABEL_LENGTH, (int)USAGE_LABEL_LENGTH, "", LONG_PREFIX, USAGE_ARG); }}/* * static void display_arg * * DESCRIPTION: * * Display an argument type while keeping track of the column we are * in. * * RETURNS: * * None. * * ARGUMENTS: * * stream - Output stream we are writing to. * * arg_p - Argument that we are displaying. * * max - Maximum column position to write to. * * col_cp - Pointer to an integer to record the column position. */static void display_arg(FILE *stream, const argv_t *arg_p, const int max, int *col_cp){ int var_len, len; if (arg_p->ar_var_label == NULL) { var_len = 0; } else { var_len = strlen(arg_p->ar_var_label); } switch (ARGV_TYPE(arg_p->ar_type)) { case ARGV_BOOL: case ARGV_BOOL_NEG: case ARGV_INCR: case ARGV_BOOL_INT: case ARGV_BOOL_INT_NEG: break; case ARGV_BOOL_ARG: case ARGV_BOOL_INT_ARG: (void)fprintf(stream, "%s", BOOL_ARG_LABEL); (*col_cp) += BOOL_ARG_LENGTH; break; case ARGV_CHAR: case ARGV_CHAR_P: case ARGV_SHORT: case ARGV_U_SHORT: case ARGV_INT: case ARGV_U_INT: case ARGV_LONG: case ARGV_U_LONG: case ARGV_FLOAT: case ARGV_DOUBLE: case ARGV_BIN: case ARGV_OCT: case ARGV_HEX: case ARGV_SIZE: case ARGV_U_SIZE: if (arg_p->ar_var_label == NULL) { len = max - *col_cp; (void)fprintf(stream, "%-.*s", len, UNKNOWN_ARG); *col_cp += MIN(len, (int)UNKNOWN_ARG_LENGTH); } else { len = max - *col_cp; (void)fprintf(stream, "%-.*s", len, arg_p->ar_var_label); *col_cp += MIN(len, var_len); } break; }}/* * static void display_option * * DESCRIPTION: * * Display an option entry while while keeping track of the column we * are in. * * RETURNS: * * None. * * ARGUMENTS: * * stream - Output stream we are writing to. * * arg_p - Argument that we are displaying. * * max - Maximum column position to write to. * * col_cp - Pointer to an integer to record the column position. */static void display_option(FILE *stream, const argv_t *arg_p, int *col_cp){ if (stream == NULL) { return; } (void)fputc('[', stream); (*col_cp)++; /* arg maybe does not have a -? preface */ if (arg_p->ar_short_arg != ARGV_MAYBE) { (void)fprintf(stream, "%s%c", SHORT_PREFIX, arg_p->ar_short_arg); *col_cp += SHORT_PREFIX_LENGTH + 1; if (HAS_ARG(arg_p->ar_type)) { /* display optional argument */ (void)fputc(' ', stream); (*col_cp)++; } } display_arg(stream, arg_p, LONG_COLUMN - 1, col_cp); (void)fputc(']', stream); (*col_cp)++;}/* * static void usage_long * * DESCRIPTION: * * Print a long-format usage message. * * RETURNS: * * None. * * ars - Array of argv_t structures whose usage we are printing. */static void usage_long(const argv_t *args){ const argv_t *arg_p; int col_c, len; if (argv_error_stream == NULL) { return; } /* print the usage message header */ (void)fprintf(argv_error_stream, "%s%s\n", USAGE_LABEL, argv_program); /* run through the argument structure */ for (arg_p = args; arg_p->ar_short_arg != ARGV_LAST; arg_p++) { /* skip or specifiers */ if (arg_p->ar_short_arg == ARGV_OR || arg_p->ar_short_arg == ARGV_XOR) { continue; } /* indent to the short-option col_c */ (void)fprintf(argv_error_stream, "%*.*s", SHORT_COLUMN, SHORT_COLUMN, ""); /* start column counter */ col_c = SHORT_COLUMN; /* print the short-arg stuff if there */ if (arg_p->ar_short_arg == '\0') { (void)fputc('[', argv_error_stream); col_c++; } else { if (arg_p->ar_short_arg == '\0') { ; } else if (arg_p->ar_short_arg == ARGV_MAND) { display_arg(argv_error_stream, arg_p, COMMENT_COLUMN, &col_c); } else { /* ARGV_MAYBE handled here */ display_option(argv_error_stream, arg_p, &col_c); } /* put the long-option message on the correct column */ if (col_c < LONG_COLUMN) { (void)fprintf(argv_error_stream, "%*.*s", LONG_COLUMN - col_c, LONG_COLUMN - col_c, ""); col_c = LONG_COLUMN; } } /* print the long-option message */ if (arg_p->ar_long_arg != NULL) { len = COMMENT_COLUMN - col_c - (LONG_PREFIX_LENGTH + 1); if (arg_p->ar_short_arg != '\0') { (void)fprintf(argv_error_stream, "%s", LONG_LABEL); col_c += LONG_LABEL_LENGTH; len -= LONG_LABEL_LENGTH; } (void)fprintf(argv_error_stream, "%s%-.*s", LONG_PREFIX, len, arg_p->ar_long_arg); col_c += LONG_PREFIX_LENGTH + MIN(len, (int)strlen(arg_p->ar_long_arg)); } /* add the optional argument if no short-arg */ if (arg_p->ar_short_arg == '\0') { if (HAS_ARG(arg_p->ar_type)) { (void)fputc(' ', argv_error_stream); col_c++; } /* display any optional arguments */ display_arg(argv_error_stream, arg_p, COMMENT_COLUMN - 1, &col_c); (void)fputc(']', argv_error_stream); col_c++; } /* print the comment */ if (arg_p->ar_comment != NULL) { /* put the comment message on the correct column */ if (col_c < COMMENT_COLUMN) { (void)fprintf(argv_error_stream, "%*.*s", COMMENT_COLUMN - col_c, COMMENT_COLUMN - col_c, ""); col_c = COMMENT_COLUMN; } len = SCREEN_WIDTH - col_c - COMMENT_LABEL_LENGTH; (void)fprintf(argv_error_stream, "%s%-.*s", COMMENT_LABEL, len, arg_p->ar_comment); } (void)fprintf(argv_error_stream, "\n"); }}/* * static void do_usage * * DESCRIPTION: * * Print the usage messages. * * RETURNS: * * None. * * ARGUMENTS: * * args - Array of argv_t structures. * * flag - Users flags which will tell us whether to display short or * long usage messages. */static void do_usage(const argv_t *args, const int flag){ if (argv_error_stream == NULL) { return; } if (flag == ARGV_USAGE_SEE) { (void)fprintf(argv_error_stream, "%*.*sUse the '%s%s' argument for assistance.\n", (int)USAGE_LABEL_LENGTH, (int)USAGE_LABEL_LENGTH, "", LONG_PREFIX, USAGE_ARG); } else if (flag == ARGV_USAGE_SHORT || flag == ARGV_USAGE_SHORT_REM) { usage_short(args, flag); } else if (flag == ARGV_USAGE_LONG || flag == ARGV_USAGE_ALL) { usage_long(args); } if (flag == ARGV_USAGE_ALL) { (void)fprintf(argv_error_stream, "\n"); (void)fprintf(argv_error_stream, "%*.*sUse '%s%s' for default usage information.\n", SHORT_COLUMN, SHORT_COLUMN, "", LONG_PREFIX, USAGE_ARG); (void)fprintf(argv_error_stream, "%*.*sUse '%s%s' for short usage information.\n", SHORT_COLUMN, SHORT_COLUMN, "", LONG_PREFIX, USAGE_SHORT_ARG); (void)fprintf(argv_error_stream, "%*.*sUse '%s%s' for long usage information.\n", SHORT_COLUMN, SHORT_COLUMN, "", LONG_PREFIX, USAGE_LONG_ARG); (void)fprintf(argv_error_stream, "%*.*sUse '%s%s' for all usage information.\n", SHORT_COLUMN, SHORT_COLUMN, "", LONG_PREFIX, USAGE_ALL_ARG); (void)fprintf(argv_error_stream, "%*.*sUse '%s%s' to display the help message.\n", SHORT_COLUMN, SHORT_COLUMN, "", LONG_PREFIX, HELP_ARG); (void)fprintf(argv_error_stream, "%*.*sUse '%s%s' to display the version message.\n", SHORT_COLUMN, SHORT_COLUMN, "", LONG_PREFIX, VERSION_ARG); (void)fprintf(argv_error_stream, "%*.*sUse '%s%s' to display the options and their values.\n", SHORT_COLUMN, SHORT_COLUMN, "", LONG_PREFIX, DISPLAY_ARG); }}/******************************* preprocessing *******************************//* * static int preprocess_array * * DESCRIPTION: * * Preprocess argument array entries and set the mandatory and maybe * flags. * * RETURNS: * * Success - 0 * * Faulure - -1 * * ARGUMENTS: * * args - Array of argv_t structures. * * arg_n - Number of entries in the argv_t array. We need this for a * couple of reasons. */static int preprocess_array(argv_t *args, const int arg_n){ argv_t *arg_p; int mand_array_b = ARGV_FALSE, maybe_field_b = ARGV_FALSE; /* count the args and find the first mandatory */ for (arg_p = args; arg_p < args + arg_n; arg_p++) { /* clear internal flags */ arg_p->ar_type &= ~ARGV_FLAG_USED; /* do we have a mandatory-array? */ if (arg_p->ar_short_arg == ARGV_MAND) { if (mand_array_b) { if (argv_error_stream != NULL) { (void)fprintf(argv_error_stream, "%s: %s, no ARGV_MAND's can follow a MAND or MAYBE array\n", argv_program, INTERNAL_ERROR_NAME); } if (argv_interactive) { (void)exit(EXIT_CODE); } return ERROR; } if (maybe_field_b) { if (argv_error_stream != NULL) { (void)fprintf(argv_error_stream, "%s: %s, no ARGV_MAND's can follow a ARGV_MAYBE\n", argv_program, INTERNAL_ERROR_NAME); } if (argv_interactive) { (void)exit(EXIT_CODE); } return ERROR; } if (arg_p->ar_type & ARGV_FLAG_ARRAY) { mand_array_b = ARGV_TRUE; } } /* do we have a maybe field? */ if (arg_p->ar_short_arg == ARGV_MAYBE) { if (mand_array_b) { if (argv_error_stream != NULL) { (void)fprintf(argv_error_stream,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -