⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 opt.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * opt.c :  option and argument parsing for Subversion command lines
 *
 * ====================================================================
 * Copyright (c) 2000-2004 CollabNet.  All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at http://subversion.tigris.org/license-1.html.
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For exact contribution history, see the revision
 * history and logs, available at http://subversion.tigris.org/.
 * ====================================================================
 */



#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <apr_pools.h>
#include <apr_general.h>
#include <apr_lib.h>

#include "svn_cmdline.h"
#include "svn_version.h"
#include "svn_types.h"
#include "svn_wc.h"
#include "svn_opt.h"
#include "svn_error.h"
#include "svn_pools.h"
#include "svn_path.h"
#include "svn_utf.h"
#include "svn_time.h"

#include "svn_private_config.h"


/*** Code. ***/

const svn_opt_subcommand_desc_t *
svn_opt_get_canonical_subcommand (const svn_opt_subcommand_desc_t *table,
                                  const char *cmd_name)
{
  int i = 0;

  if (cmd_name == NULL)
    return NULL;

  while (table[i].name) {
    int j;
    if (strcmp (cmd_name, table[i].name) == 0)
      return table + i;
    for (j = 0; (j < SVN_OPT_MAX_ALIASES) && table[i].aliases[j]; j++)
      if (strcmp (cmd_name, table[i].aliases[j]) == 0)
        return table + i;

    i++;
  }

  /* If we get here, there was no matching subcommand name or alias. */
  return NULL;
}


const apr_getopt_option_t *
svn_opt_get_option_from_code (int code,
                              const apr_getopt_option_t *option_table)
{
  apr_size_t i;

  for (i = 0; option_table[i].optch; i++)
    if (option_table[i].optch == code)
      return &(option_table[i]);
  
  return NULL;
}


svn_boolean_t
svn_opt_subcommand_takes_option (const svn_opt_subcommand_desc_t *command,
                                 int option_code)
{
  apr_size_t i;
  
  for (i = 0; i < SVN_OPT_MAX_OPTIONS; i++)
    if (command->valid_options[i] == option_code)
      return TRUE;

  return FALSE;
}


/* Print the canonical command name for CMD, and all its aliases, to
   STREAM.  If HELP is set, print CMD's help string too, in which case
   obtain option usage from OPTIONS_TABLE. */
static svn_error_t *
print_command_info (const svn_opt_subcommand_desc_t *cmd,
                    const apr_getopt_option_t *options_table,
                    svn_boolean_t help, 
                    apr_pool_t *pool,
                    FILE *stream)
{
  svn_boolean_t first_time;
  apr_size_t i;

  /* Print the canonical command name. */
  SVN_ERR (svn_cmdline_fputs (cmd->name, stream, pool));

  /* Print the list of aliases. */
  first_time = TRUE;
  for (i = 0; i < SVN_OPT_MAX_ALIASES; i++) 
    {
      if (cmd->aliases[i] == NULL)
        break;

      if (first_time) {
        SVN_ERR (svn_cmdline_fputs (" (", stream, pool));
        first_time = FALSE;
      }
      else
        SVN_ERR (svn_cmdline_fputs (", ", stream, pool));
      
      SVN_ERR (svn_cmdline_fputs (cmd->aliases[i], stream, pool));
    }

  if (! first_time)
    SVN_ERR (svn_cmdline_fputs (")", stream, pool));
  
  if (help)
    {
      const apr_getopt_option_t *option;
      svn_boolean_t have_options = FALSE;

      SVN_ERR (svn_cmdline_fprintf (stream, pool, ": %s",
                                    dgettext (PACKAGE_NAME, cmd->help)));

      /* Loop over all valid option codes attached to the subcommand */
      for (i = 0; i < SVN_OPT_MAX_OPTIONS; i++)
        {
          if (cmd->valid_options[i])
            {
              if (have_options == FALSE)
                {
                  SVN_ERR (svn_cmdline_fputs (_("\nValid options:\n"),
                                              stream, pool));
                  have_options = TRUE;
                }

              /* convert each option code into an option */
              option = 
                svn_opt_get_option_from_code (cmd->valid_options[i],
                                              options_table);

              /* print the option's docstring */
              if (option)
                {
                  const char *optstr;
                  svn_opt_format_option (&optstr, option, TRUE, pool);
                  SVN_ERR (svn_cmdline_fprintf (stream, pool, "  %s\n",
                                                optstr));
                }
            }
        }

      if (have_options)
        SVN_ERR (svn_cmdline_fprintf (stream, pool, "\n"));
    }

  return SVN_NO_ERROR;
}


void
svn_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_error (err, stderr, FALSE);
  svn_error_clear (err);
}


void
svn_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,
                         dgettext( PACKAGE_NAME, opt->description));

  *string = opts;
}


void
svn_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_error (err, stderr, FALSE);
    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 int
revision_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;
}


int
svn_opt_parse_revision (svn_opt_revision_t *start_revision,
                        svn_opt_revision_t *end_revision,
                        const char *arg,
                        apr_pool_t *pool)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -