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

📄 sim-options.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
SIM_RCsim_parse_args (sd, argv)     SIM_DESC sd;     char **argv;{  int c, i, argc, num_opts;  char *p, *short_options;  /* The `val' option struct entry is dynamically assigned for options that     only come in the long form.  ORIG_VAL is used to get the original value     back.  */  int *orig_val;  struct option *lp, *long_options;  const struct option_list *ol;  const OPTION *opt;  OPTION_HANDLER **handlers;  sim_cpu **opt_cpu;  SIM_RC result = SIM_RC_OK;  /* Count the number of arguments.  */  for (argc = 0; argv[argc] != NULL; ++argc)    continue;  /* Count the number of options.  */  num_opts = 0;  for (ol = STATE_OPTIONS (sd); ol != NULL; ol = ol->next)    for (opt = ol->options; OPTION_VALID_P (opt); ++opt)      ++num_opts;  for (i = 0; i < MAX_NR_PROCESSORS; ++i)    for (ol = CPU_OPTIONS (STATE_CPU (sd, i)); ol != NULL; ol = ol->next)      for (opt = ol->options; OPTION_VALID_P (opt); ++opt)	++num_opts;  /* Initialize duplicate argument checker.  */  (void) dup_arg_p (NULL);  /* Build the option table for getopt.  */  long_options = NZALLOC (struct option, num_opts + 1);  lp = long_options;  short_options = NZALLOC (char, num_opts * 3 + 1);  p = short_options;  handlers = NZALLOC (OPTION_HANDLER *, OPTION_START + num_opts);  orig_val = NZALLOC (int, OPTION_START + num_opts);  opt_cpu = NZALLOC (sim_cpu *, OPTION_START + num_opts);  /* Set '+' as first char so argument permutation isn't done.  This     is done to stop getopt_long returning options that appear after     the target program.  Such options should be passed unchanged into     the program image. */  *p++ = '+';  for (i = OPTION_START, ol = STATE_OPTIONS (sd); ol != NULL; ol = ol->next)    for (opt = ol->options; OPTION_VALID_P (opt); ++opt)      {	if (dup_arg_p (opt->opt.name))	  continue;	if (opt->shortopt != 0)	  {	    *p++ = opt->shortopt;	    if (opt->opt.has_arg == required_argument)	      *p++ = ':';	    else if (opt->opt.has_arg == optional_argument)	      { *p++ = ':'; *p++ = ':'; }	    handlers[(unsigned char) opt->shortopt] = opt->handler;	    if (opt->opt.val != 0)	      orig_val[(unsigned char) opt->shortopt] = opt->opt.val;	    else	      orig_val[(unsigned char) opt->shortopt] = opt->shortopt;	  }	if (opt->opt.name != NULL)	  {	    *lp = opt->opt;	    /* Dynamically assign `val' numbers for long options. */	    lp->val = i++;	    handlers[lp->val] = opt->handler;	    orig_val[lp->val] = opt->opt.val;	    opt_cpu[lp->val] = NULL;	    ++lp;	  }      }  for (c = 0; c < MAX_NR_PROCESSORS; ++c)    {      sim_cpu *cpu = STATE_CPU (sd, c);      for (ol = CPU_OPTIONS (cpu); ol != NULL; ol = ol->next)	for (opt = ol->options; OPTION_VALID_P (opt); ++opt)	  {#if 0 /* Each option is prepended with --<cpuname>- so this greatly cuts down	 on the need for dup_arg_p checking.  Maybe in the future it'll be	 needed so this is just commented out, and not deleted.  */	    if (dup_arg_p (opt->opt.name))	      continue;#endif	    /* Don't allow short versions of cpu specific options for now.  */	    if (opt->shortopt != 0)	      {		sim_io_eprintf (sd, "internal error, short cpu specific option");		result = SIM_RC_FAIL;		break;	      }	    if (opt->opt.name != NULL)	      {		char *name;		*lp = opt->opt;		/* Prepend --<cpuname>- to the option.  */		asprintf (&name, "%s-%s", CPU_NAME (cpu), lp->name);		lp->name = name;		/* Dynamically assign `val' numbers for long options. */		lp->val = i++;		handlers[lp->val] = opt->handler;		orig_val[lp->val] = opt->opt.val;		opt_cpu[lp->val] = cpu;		++lp;	      }	  }    }	      /* Terminate the short and long option lists.  */  *p = 0;  lp->name = NULL;  /* Ensure getopt is initialized.  */  optind = 0;  while (1)    {      int longind, optc;      optc = getopt_long (argc, argv, short_options, long_options, &longind);      if (optc == -1)	{	  if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)	    STATE_PROG_ARGV (sd) = dupargv (argv + optind);	  break;	}      if (optc == '?')	{	  result = SIM_RC_FAIL;	  break;	}      if ((*handlers[optc]) (sd, opt_cpu[optc], orig_val[optc], optarg, 0/*!is_command*/) == SIM_RC_FAIL)	{	  result = SIM_RC_FAIL;	  break;	}    }  zfree (long_options);  zfree (short_options);  zfree (handlers);  zfree (opt_cpu);  zfree (orig_val);  return result;}/* Utility of sim_print_help to print a list of option tables.  */static voidprint_help (SIM_DESC sd, sim_cpu *cpu, const struct option_list *ol, int is_command){  const OPTION *opt;  for ( ; ol != NULL; ol = ol->next)    for (opt = ol->options; OPTION_VALID_P (opt); ++opt)      {	const int indent = 30;	int comma, len;	const OPTION *o;	if (dup_arg_p (opt->opt.name))	  continue;	if (opt->doc == NULL)	  continue;	if (opt->doc_name != NULL && opt->doc_name [0] == '\0')	  continue;	sim_io_printf (sd, "  ");	comma = 0;	len = 2;	/* list any short options (aliases) for the current OPT */	if (!is_command)	  {	    o = opt;	    do	      {		if (o->shortopt != '\0')		  {		    sim_io_printf (sd, "%s-%c", comma ? ", " : "", o->shortopt);		    len += (comma ? 2 : 0) + 2;		    if (o->arg != NULL)		      {			if (o->opt.has_arg == optional_argument)			  {			    sim_io_printf (sd, "[%s]", o->arg);			    len += 1 + strlen (o->arg) + 1;			  }			else			  {			    sim_io_printf (sd, " %s", o->arg);			    len += 1 + strlen (o->arg);			  }		      }		    comma = 1;		  }		++o;	      }	    while (OPTION_VALID_P (o) && o->doc == NULL);	  }		/* list any long options (aliases) for the current OPT */	o = opt;	do	  {	    const char *name;	    const char *cpu_prefix = cpu ? CPU_NAME (cpu) : NULL;	    if (o->doc_name != NULL)	      name = o->doc_name;	    else	      name = o->opt.name;	    if (name != NULL)	      {		sim_io_printf (sd, "%s%s%s%s%s",			       comma ? ", " : "",			       is_command ? "" : "--",			       cpu ? cpu_prefix : "",			       cpu ? "-" : "",			       name);		len += ((comma ? 2 : 0)			+ (is_command ? 0 : 2)			+ strlen (name));		if (o->arg != NULL)		  {		    if (o->opt.has_arg == optional_argument)		      {			sim_io_printf (sd, "[=%s]", o->arg);			len += 2 + strlen (o->arg) + 1;		      }		    else		      {			sim_io_printf (sd, " %s", o->arg);			len += 1 + strlen (o->arg);		      }		  }		comma = 1;	      }	    ++o;	  }	while (OPTION_VALID_P (o) && o->doc == NULL);	if (len >= indent)	  {	    sim_io_printf (sd, "\n%*s", indent, "");	  }	else	  sim_io_printf (sd, "%*s", indent - len, "");	/* print the description, word wrap long lines */	{	  const char *chp = opt->doc;	  unsigned doc_width = 80 - indent;	  while (strlen (chp) >= doc_width) /* some slack */	    {	      const char *end = chp + doc_width - 1;	      while (end > chp && !isspace (*end))		end --;	      if (end == chp)		end = chp + doc_width - 1;	      /* The cast should be ok - its distances between to                 points in a string.  */	      sim_io_printf (sd, "%.*s\n%*s", (int) (end - chp), chp, indent,			     "");	      chp = end;	      while (isspace (*chp) && *chp != '\0')		chp++;	    }	  sim_io_printf (sd, "%s\n", chp);	}      }}/* Print help messages for the options.  */voidsim_print_help (sd, is_command)     SIM_DESC sd;     int is_command;{  if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)    sim_io_printf (sd, "Usage: %s [options] program [program args]\n",		   STATE_MY_NAME (sd));  /* Initialize duplicate argument checker.  */  (void) dup_arg_p (NULL);  if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)    sim_io_printf (sd, "Options:\n");  else    sim_io_printf (sd, "Commands:\n");  print_help (sd, NULL, STATE_OPTIONS (sd), is_command);  sim_io_printf (sd, "\n");  /* Print cpu-specific options.  */  {    int i;    for (i = 0; i < MAX_NR_PROCESSORS; ++i)      {	sim_cpu *cpu = STATE_CPU (sd, i);	if (CPU_OPTIONS (cpu) == NULL)	  continue;	sim_io_printf (sd, "CPU %s specific options:\n", CPU_NAME (cpu));	print_help (sd, cpu, CPU_OPTIONS (cpu), is_command);	sim_io_printf (sd, "\n");      }  }  sim_io_printf (sd, "Note: Depending on the simulator configuration some %ss\n",		 STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE ? "option" : "command");  sim_io_printf (sd, "      may not be applicable\n");  if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)    {      sim_io_printf (sd, "\n");      sim_io_printf (sd, "program args    Arguments to pass to simulated program.\n");      sim_io_printf (sd, "                Note: Very few simulators support this.\n");    }}/* Utility of sim_args_command to find the closest match for a command.   Commands that have "-" in them can be specified as separate words.   e.g. sim memory-region 0x800000,0x4000   or   sim memory region 0x800000,0x4000   If CPU is non-null, use its option table list, otherwise use the main one.   *PARGI is where to start looking in ARGV.  It is updated to point past   the found option.  */static const OPTION *find_match (SIM_DESC sd, sim_cpu *cpu, char *argv[], int *pargi){  const struct option_list *ol;  const OPTION *opt;  /* most recent option match */  const OPTION *matching_opt = NULL;  int matching_argi = -1;  if (cpu)    ol = CPU_OPTIONS (cpu);  else    ol = STATE_OPTIONS (sd);  /* Skip passed elements specified by *PARGI.  */  argv += *pargi;  for ( ; ol != NULL; ol = ol->next)    for (opt = ol->options; OPTION_VALID_P (opt); ++opt)      {	int argi = 0;	const char *name = opt->opt.name;	if (name == NULL)	  continue;	while (argv [argi] != NULL	       && strncmp (name, argv [argi], strlen (argv [argi])) == 0)	  {	    name = &name [strlen (argv[argi])];	    if (name [0] == '-')	      {		/* leading match ...<a-b-c>-d-e-f - continue search */		name ++; /* skip `-' */		argi ++;		continue;	      }	    else if (name [0] == '\0')	      {		/* exact match ...<a-b-c-d-e-f> - better than before? */		if (argi > matching_argi)		  {		    matching_argi = argi;		    matching_opt = opt;		  }		break;	      }	    else	      break;	  }      }  *pargi = matching_argi;  return matching_opt;}SIM_RCsim_args_command (SIM_DESC sd, char *cmd){  /* something to do? */  if (cmd == NULL)    return SIM_RC_OK; /* FIXME - perhaps help would be better */    if (cmd [0] == '-')    {      /* user specified -<opt> ... form? */      char **argv = buildargv (cmd);      SIM_RC rc = sim_parse_args (sd, argv);      freeargv (argv);      return rc;    }  else    {      char **argv = buildargv (cmd);      const OPTION *matching_opt = NULL;      int matching_argi;      sim_cpu *cpu;      if (argv [0] == NULL)	return SIM_RC_OK; /* FIXME - perhaps help would be better */      /* First check for a cpu selector.  */      {	char *cpu_name = xstrdup (argv[0]);	char *hyphen = strchr (cpu_name, '-');	if (hyphen)	  *hyphen = 0;	cpu = sim_cpu_lookup (sd, cpu_name);	if (cpu)	  {	    /* If <cpuname>-<command>, point argv[0] at <command>.  */	    if (hyphen)	      {		matching_argi = 0;		argv[0] += hyphen - cpu_name + 1;	      }	    else	      matching_argi = 1;	    matching_opt = find_match (sd, cpu, argv, &matching_argi);	    /* If hyphen found restore argv[0].  */	    if (hyphen)	      argv[0] -= hyphen - cpu_name + 1;	  }	free (cpu_name);      }      /* If that failed, try the main table.  */      if (matching_opt == NULL)	{	  matching_argi = 0;	  matching_opt = find_match (sd, NULL, argv, &matching_argi);	}      if (matching_opt != NULL)	{	  switch (matching_opt->opt.has_arg)	    {	    case no_argument:	      if (argv [matching_argi + 1] == NULL)		matching_opt->handler (sd, cpu, matching_opt->opt.val,				       NULL, 1/*is_command*/);	      else		sim_io_eprintf (sd, "Command `%s' takes no arguments\n",				matching_opt->opt.name);	      break;	    case optional_argument:	      if (argv [matching_argi + 1] == NULL)		matching_opt->handler (sd, cpu, matching_opt->opt.val,				       NULL, 1/*is_command*/);	      else if (argv [matching_argi + 2] == NULL)		matching_opt->handler (sd, cpu, matching_opt->opt.val,				       argv [matching_argi + 1], 1/*is_command*/);	      else		sim_io_eprintf (sd, "Command `%s' requires no more than one argument\n",				matching_opt->opt.name);	      break;	    case required_argument:	      if (argv [matching_argi + 1] == NULL)		sim_io_eprintf (sd, "Command `%s' requires an argument\n",				matching_opt->opt.name);	      else if (argv [matching_argi + 2] == NULL)		matching_opt->handler (sd, cpu, matching_opt->opt.val,				       argv [matching_argi + 1], 1/*is_command*/);	      else		sim_io_eprintf (sd, "Command `%s' requires only one argument\n",				matching_opt->opt.name);	    }	  freeargv (argv);	  return SIM_RC_OK;	}      freeargv (argv);    }        /* didn't find anything that remotly matched */  return SIM_RC_FAIL;}

⌨️ 快捷键说明

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