📄 opt.c
字号:
}voidsvn_opt_print_generic_help(const char *header, const svn_opt_subcommand_desc_t *cmd_table, const apr_getopt_option_t *opt_table, const char *footer, apr_pool_t *pool, FILE *stream){ int i = 0; svn_error_t *err; if (header) if ((err = svn_cmdline_fputs(header, stream, pool))) goto print_error; while (cmd_table[i].name) { if ((err = svn_cmdline_fputs(" ", stream, pool)) || (err = print_command_info(cmd_table + i, opt_table, FALSE, pool, stream)) || (err = svn_cmdline_fputs("\n", stream, pool))) goto print_error; i++; } if ((err = svn_cmdline_fputs("\n", stream, pool))) goto print_error; if (footer) if ((err = svn_cmdline_fputs(footer, stream, pool))) goto print_error; return; print_error: svn_handle_error2(err, stderr, FALSE, "svn: "); svn_error_clear(err);}voidsvn_opt_format_option(const char **string, const apr_getopt_option_t *opt, svn_boolean_t doc, apr_pool_t *pool){ char *opts; if (opt == NULL) { *string = "?"; return; } /* We have a valid option which may or may not have a "short name" (a single-character alias for the long option). */ if (opt->optch <= 255) opts = apr_psprintf(pool, "-%c [--%s]", opt->optch, opt->name); else opts = apr_psprintf(pool, "--%s", opt->name); if (opt->has_arg) opts = apr_pstrcat(pool, opts, _(" arg"), NULL); if (doc) opts = apr_psprintf(pool, "%-24s : %s", opts, _(opt->description)); *string = opts;}voidsvn_opt_subcommand_help2(const char *subcommand, const svn_opt_subcommand_desc2_t *table, const apr_getopt_option_t *options_table, apr_pool_t *pool){ const svn_opt_subcommand_desc2_t *cmd = svn_opt_get_canonical_subcommand2(table, subcommand); svn_error_t *err; if (cmd) err = print_command_info2(cmd, options_table, TRUE, pool, stdout); else err = svn_cmdline_fprintf(stderr, pool, _("\"%s\": unknown command.\n\n"), subcommand); if (err) { svn_handle_error2(err, stderr, FALSE, "svn: "); svn_error_clear(err); }}voidsvn_opt_subcommand_help(const char *subcommand, const svn_opt_subcommand_desc_t *table, const apr_getopt_option_t *options_table, apr_pool_t *pool){ const svn_opt_subcommand_desc_t *cmd = svn_opt_get_canonical_subcommand(table, subcommand); svn_error_t *err; if (cmd) err = print_command_info(cmd, options_table, TRUE, pool, stdout); else err = svn_cmdline_fprintf(stderr, pool, _("\"%s\": unknown command.\n\n"), subcommand); if (err) { svn_handle_error2(err, stderr, FALSE, "svn: "); svn_error_clear(err); }}/*** Parsing revision and date options. ***//** Parsing "X:Y"-style arguments. **//* If WORD matches one of the special revision descriptors, * case-insensitively, set *REVISION accordingly: * * - For "head", set REVISION->kind to svn_opt_revision_head. * * - For "prev", set REVISION->kind to svn_opt_revision_previous. * * - For "base", set REVISION->kind to svn_opt_revision_base. * * - For "committed", set REVISION->kind to svn_opt_revision_committed. * * If match, return 0, else return -1 and don't touch REVISION. */static intrevision_from_word(svn_opt_revision_t *revision, const char *word){ if (strcasecmp(word, "head") == 0) { revision->kind = svn_opt_revision_head; } else if (strcasecmp(word, "prev") == 0) { revision->kind = svn_opt_revision_previous; } else if (strcasecmp(word, "base") == 0) { revision->kind = svn_opt_revision_base; } else if (strcasecmp(word, "committed") == 0) { revision->kind = svn_opt_revision_committed; } else return -1; return 0;}/* Parse one revision specification. Return pointer to character after revision, or NULL if the revision is invalid. Modifies str, so make sure to pass a copy of anything precious. Uses POOL for temporary allocation. */static char *parse_one_rev(svn_opt_revision_t *revision, char *str, apr_pool_t *pool){ char *end, save; if (*str == '{') { svn_boolean_t matched; apr_time_t tm; svn_error_t *err; /* Brackets denote a date. */ str++; end = strchr(str, '}'); if (!end) return NULL; *end = '\0'; err = svn_parse_date(&matched, &tm, str, apr_time_now(), pool); if (err) { svn_error_clear(err); return NULL; } if (!matched) return NULL; revision->kind = svn_opt_revision_date; revision->value.date = tm; return end + 1; } else if (apr_isdigit(*str)) { /* It's a number. */ end = str + 1; while (apr_isdigit(*end)) end++; save = *end; *end = '\0'; revision->kind = svn_opt_revision_number; revision->value.number = SVN_STR_TO_REV(str); *end = save; return end; } else if (apr_isalpha(*str)) { end = str + 1; while (apr_isalpha(*end)) end++; save = *end; *end = '\0'; if (revision_from_word(revision, str) != 0) return NULL; *end = save; return end; } else return NULL;}intsvn_opt_parse_revision(svn_opt_revision_t *start_revision, svn_opt_revision_t *end_revision, const char *arg, apr_pool_t *pool){ char *left_rev, *right_rev, *end; /* Operate on a copy of the argument. */ left_rev = apr_pstrdup(pool, arg); right_rev = parse_one_rev(start_revision, left_rev, pool); if (right_rev && *right_rev == ':') { right_rev++; end = parse_one_rev(end_revision, right_rev, pool); if (!end || *end != '\0') return -1; } else if (!right_rev || *right_rev != '\0') return -1; return 0;}/*** Parsing arguments. ***/#define DEFAULT_ARRAY_SIZE 5/* Copy STR into POOL and push the copy onto ARRAY. */static void array_push_str(apr_array_header_t *array, const char *str, apr_pool_t *pool){ /* ### Not sure if this function is still necessary. It used to convert str to svn_stringbuf_t * and push it, but now it just dups str in pool and pushes the copy. So its only effect is transfer str's lifetime to pool. Is that something callers are depending on? */ (*((const char **) apr_array_push(array))) = apr_pstrdup(pool, str);}voidsvn_opt_push_implicit_dot_target(apr_array_header_t *targets, apr_pool_t *pool){ if (targets->nelts == 0) array_push_str(targets, "", pool); /* Ha! "", not ".", is the canonical */ assert(targets->nelts);}svn_error_t *svn_opt_parse_num_args(apr_array_header_t **args_p, apr_getopt_t *os, int num_args, apr_pool_t *pool){ int i; apr_array_header_t *args = apr_array_make(pool, DEFAULT_ARRAY_SIZE, sizeof(const char *)); /* loop for num_args and add each arg to the args array */ for (i = 0; i < num_args; i++) { if (os->ind >= os->argc) { return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL); } array_push_str(args, os->argv[os->ind++], pool); } *args_p = args; return SVN_NO_ERROR;}svn_error_t *svn_opt_parse_all_args(apr_array_header_t **args_p, apr_getopt_t *os, apr_pool_t *pool){ apr_array_header_t *args = apr_array_make(pool, DEFAULT_ARRAY_SIZE, sizeof(const char *)); if (os->ind > os->argc) { return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, 0, NULL); } while (os->ind < os->argc) { array_push_str(args, os->argv[os->ind++], pool); } *args_p = args; return SVN_NO_ERROR;}svn_error_t *svn_opt_parse_path(svn_opt_revision_t *rev, const char **truepath, const char *path /* UTF-8! */, apr_pool_t *pool){ int i; /* scanning from right to left, just to be friendly to any screwed-up filenames that might *actually* contain @-signs. :-) */ for (i = (strlen(path) - 1); i >= 0; i--) { /* If we hit a path separator, stop looking. */ /* This is OK only because our revision specifiers can't contain '/'. */ if (path[i] == '/') break; if (path[i] == '@') { svn_boolean_t is_url; int ret; svn_opt_revision_t start_revision, end_revision; end_revision.kind = svn_opt_revision_unspecified; /* URLs get treated differently from wc paths. */ is_url = svn_path_is_url(path); if (path[i + 1] == '\0') /* looking at empty peg revision */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -