Beispiel #1
0
bool parse_line(char *line)
{
    struct AstNode *node;
    int len = strlen(line);

    err_reset();
    node = parse_source(line, NULL, NULL);

    if (!node) {
        ++unexpected_fails;
        return false;
    }

    if (!rt_consume_list(rt, node, NULL, &last_loc)) {
        ++unexpected_fails;
        return false;
    }

    mem_free(last_expression);
    last_expression = mem_malloc(len - 1);
    memcpy(last_expression, line, len - 2);
    last_expression[len - 2] = '\0';

    return true;
}
Beispiel #2
0
void
load_conf(struct opts *opts)
{
  FILE *f;
  struct conf_entry *conf, *e;
  char *conf_file = opts->conf_file;
  if (!opts->conf_file)
    conf_file = DEFAULT_CONF_FILE;
  f = fopen (conf_file, "r");
  if (!f) {
    if (opts->conf_file) {
      pfatal ("can't open conf file '%s'", opts->conf_file);
    } else {
      pinfo ("can't open conf file '%s'", conf_file);
      return;
    }
  }
  conf = conf_parse (f);
  if (!conf)
    pfatal ("can't parse config file");

  for (e = conf; e; e = e->next) {
    if (!strcmp (e->key, "max-tries") && e->value) {
      opts->max_tries = atoi (e->value);
    } else if (!strcmp (e->key, "min-steady-state-interval") && e->value) {
      opts->min_steady_state_interval = atoi (e->value);
    } else if (!strcmp (e->key, "wait-between-tries") && e->value) {
      opts->wait_between_tries = atoi (e->value);
    } else if (!strcmp (e->key, "subprocess-tries") && e->value) {
      opts->subprocess_tries = atoi (e->value);
    } else if (!strcmp (e->key, "subprocess-wait-between-tries") && e->value) {
      opts->subprocess_wait_between_tries = atoi (e->value);
    } else if (!strcmp (e->key, "steady-state-interval") && e->value) {
      opts->steady_state_interval = atoi (e->value);
    } else if (!strcmp (e->key, "base-path") && e->value) {
      opts->base_path = strdup (e->value);
      if (!opts->base_path)
        fatal ("out of memory for base path");
    } else if (!strcmp (e->key, "should-sync-hwclock")) {
      opts->should_sync_hwclock = e->value ? !strcmp(e->value, "yes") : 1;
    } else if (!strcmp (e->key, "should-load-disk")) {
      opts->should_load_disk = e->value ? !strcmp(e->value, "yes") : 1;
    } else if (!strcmp (e->key, "should-save-disk")) {
      opts->should_save_disk = e->value ? !strcmp(e->value, "yes") : 1;
    } else if (!strcmp (e->key, "should-netlink")) {
      opts->should_netlink = e->value ? !strcmp(e->value, "yes") : 1;
    } else if (!strcmp (e->key, "dry-run")) {
      opts->dry_run = e->value ? !strcmp(e->value, "yes") : 1;
    } else if (!strcmp (e->key, "jitter") && e->value) {
      opts->jitter = atoi (e->value);
    } else if (!strcmp (e->key, "verbose")) {
      verbose = e->value ? !strcmp(e->value, "yes") : 1;
    } else if (!strcmp (e->key, "source")) {
      e = parse_source(opts, e);
    }
  }
}
Beispiel #3
0
static void bif_parse_atomic(
        struct Runtime *rt,
        VAL_LOC_T arg_loc,
        char *func,
        enum AstLiteralAtomicType type)
{
    VAL_LOC_T size_loc, data_begin, data_size;
    struct AstNode *ast = NULL;
    char *source, *err;

    /* Assert input. */
    if (!rt_val_is_string(rt, arg_loc)) {
        bif_text_error_arg(1, func, "must be a string");
        return;
    }

    /* Push header. */
    rt_val_push_tuple_init(&rt->stack, &size_loc);
    data_begin = rt->stack.top;

    source = rt_val_peek_cpd_as_string(rt, arg_loc);
    ast = parse_source(source, NULL, NULL);
    mem_free(source);

    /* Error detection. */
    if (!ast) {
        err = "Failed parsing atomic literal";
        rt_val_push_bool(&rt->stack, false);
        rt_val_push_string(&rt->stack, err, err + strlen(err));
        goto end;
    }
    if (ast->next != NULL) {
        err = "Too many nodes.";
        rt_val_push_bool(&rt->stack, false);
        rt_val_push_string(&rt->stack, err, err + strlen(err));
        goto end;
    }
    if (ast->type != AST_LITERAL_ATOMIC || ast->data.literal_atomic.type != type) {
        err = "Incorrect type.";
        rt_val_push_bool(&rt->stack, false);
        rt_val_push_string(&rt->stack, err, err + strlen(err));
        goto end;
    }

    /* Correct case. */
    rt_val_push_bool(&rt->stack, true);
    bif_parse_any_ast_literal_atomic(rt, &ast->data.literal_atomic);

end:
    data_size = rt->stack.top - data_begin;
    rt_val_push_cpd_final(&rt->stack, size_loc, data_size);
    if (ast) {
        ast_node_free(ast);
    }
}
Beispiel #4
0
/*
 * do_attach()
 *
 * This routine attaches a previously existing action to a source object.
 * The action will not do anything unless it is LINKed.
 *
 */
void
do_attach(int descr, dbref player, const char *action_name,
          const char *source_name)
{
    dbref action, source;
    dbref loc;                  /* player's current location */
    struct match_data md;
    char buf[BUFFER_LEN];

    if ((loc = DBFETCH(player)->location) == NOTHING)
        return;

    if (tp_db_readonly) {
        anotify_nolisten2(player, CFAIL DBRO_MESG);
        return;
    }

    if (!*action_name || !*source_name) {
        anotify_nolisten2(player,
                          CINFO
                          "You must specify an action name and a source object.");
        return;
    }
    init_match(descr, player, action_name, TYPE_EXIT, &md);
    match_all_exits(&md);
    match_registered(&md);
    match_absolute(&md);

    if ((action = noisy_match_result(&md)) == NOTHING)
        return;

    if (Typeof(action) != TYPE_EXIT) {
        anotify_nolisten2(player, CINFO "That's not an action.");
        return;
    } else if (!controls(player, action)) {
        anotify_fmt(player, CFAIL "%s", tp_noperm_mesg);
        return;
    }
    if (((source = parse_source(descr, player, source_name)) == NOTHING)
        || Typeof(source) == TYPE_PROGRAM)
        return;

    if (!unset_source(player, loc, action)) {
        return;
    }
    set_source(player, action, source);
    sprintf(buf, CSUCC "Action %s re-attached to %s.",
            unparse_object(player, action), NAME(source));
    anotify_nolisten2(player, buf);
    if (MLevel(action)) {
        SetMLevel(action, 0);
        anotify_nolisten2(player, CINFO "Action priority Level reset to zero.");
    }
}
Beispiel #5
0
Source_multi_or* parse_source_multi_or(
		char** input,
		ParserState* state
	) {
	Source* operands[PARSER_BUFFER_SIZE];
	int i = 0;


	if (**input != '(')
		return 0;
	*input += 1;


	do {
		if (i == PARSER_BUFFER_SIZE)
			break;

		operands[i] =
			parse_source(
				input,
				state
				);

		if (**input != ';')
			break;

		*input += 1; // sizeof(char)
	} while (operands[i++]);

	if (i == 0)
		return 0;


	if (**input != ')')
		return 0;
	*input += 1;


	Source_multi_or* retval =
		alloct(Source_multi_or); /// retval+

	String* ns =
		string_create(operands, sizeof(Source*) * i); /// ns+

	source_multi_or_init(
			retval,
			ns
		);

	release(ns); /// ns-

	return retval;
}
Beispiel #6
0
/** go through the source file(s) and create a
 * data structure with all the info about instruction sizes
 * and opcodes for all instructions without labels
 */
struct instruction *pass_first(FILE *infile, struct tab_entry *tabroot)
{
    struct instruction *root = NULL;
    label_root = NULL;

    /** build up the basic tree from the source file(s)
     * descends recursively into included source files
     */
    root = parse_source(infile, root, tabroot);

    return root;
}
Beispiel #7
0
int parser_t::eval(wcstring cmd, const io_chain_t &io, enum block_type_t block_type) {
    // Parse the source into a tree, if we can.
    parse_error_list_t error_list;
    parsed_source_ref_t ps = parse_source(cmd, parse_flag_none, &error_list);
    if (!ps) {
        // Get a backtrace. This includes the message.
        wcstring backtrace_and_desc;
        this->get_backtrace(cmd, error_list, backtrace_and_desc);

        // Print it.
        fwprintf(stderr, L"%ls\n", backtrace_and_desc.c_str());
        return 1;
    }
    this->eval(ps, io, block_type);
    return 0;
}
Beispiel #8
0
static void bif_parse_any(struct Runtime *rt, char *string)
{
    struct AstNode *ast;

    ast = parse_source(string, NULL, NULL);
    if (!ast) {
        bif_text_error_parse();
        return;
    }

    if (ast->next != NULL) {
        bif_text_error_parse();
        ast_node_free(ast);
        return;
    }

    bif_parse_any_ast(rt, ast);
    ast_node_free(ast);
}
Template_multi_and* parse_template_multi_and(
    char** input,
    ParserState* state
) {
    Template* operands[PARSER_BUFFER_SIZE];
    int i = 0;

    do {
        if (i == PARSER_BUFFER_SIZE)
            break;

        operands[i] =
            parse_source(
                input,
                state
            );

        if (**input != ' ')
            break;

        *input += 1; // sizeof(char)
    } while (operands[i++]);

    if (i == 0)
        return 0;



    Template_multi_and* retval =
        alloct(Template_multi_and); /// retval+

    String* ns =
        string_create(operands, sizeof(Template*) * i); /// ns+

    template_multi_and_init(
        retval,
        ns
    );

    release(ns); /// ns-

    return retval;
}
Beispiel #10
0
struct AstNode *parse_source_build_alm(
        char *source,
        struct AstLocMap *alm)
{
    return parse_source(source, alm, parse_source_on_ast);
}
Beispiel #11
0
/*
 * do_action()
 *
 * This routine attaches a new existing action to a source object,
 * where possible.
 * The action will not do anything until it is LINKed.
 *
 */
void
do_action(int descr, dbref player, const char *action_name,
          const char *source_name)
{
    dbref action, source;
    static char buf[BUFFER_LEN];
    char buf2[BUFFER_LEN];
    char *rname, *qname;

    if (!Builder(player)) {
        anotify_nolisten2(player, CFAIL NOBBIT_MESG);
        return;
    }

    if (!tp_building || tp_db_readonly) {
        anotify_nolisten2(player, CFAIL NOBUILD_MESG);
        return;
    }

    strcpy(buf2, source_name);
    for (rname = buf2; (*rname && (*rname != '=')); rname++) ;
    qname = rname;
    if (*rname)
        *(rname++) = '\0';
    while ((qname > buf2) && (isspace(*qname)))
        *(qname--) = '\0';
    qname = buf2;
    for (; *rname && isspace(*rname); rname++) ;

    if (!*action_name || !*qname) {
        anotify_nolisten2(player,
                          CINFO
                          "You must specify an action name and a source object.");
        return;
    } else if (!ok_name(action_name)) {
        anotify_nolisten2(player, CINFO "That's a strange name for an action!");
        return;
    }
    if (((source = parse_source(descr, player, qname)) == NOTHING))
        return;
    if (!payfor(player, tp_exit_cost)) {
        anotify_fmt(player, SYSRED
                    "You don't have enough %s to make an action.", tp_pennies);
        return;
    }

    action = new_object(player);

    NAME(action) = alloc_string(action_name);
    DBFETCH(action)->location = NOTHING;
    OWNER(action) = OWNER(player);
    DBFETCH(action)->sp.exit.ndest = 0;
    DBFETCH(action)->sp.exit.dest = NULL;
    FLAGS(action) = TYPE_EXIT;

    set_source(player, action, source);
    sprintf(buf, CSUCC "Action %s created and attached to %s.",
            unparse_object(player, action), NAME(source));
    anotify_nolisten2(player, buf);
    DBDIRTY(action);

    if (*rname) {
        PData pdat;

        sprintf(buf, CINFO "Registered as $%s", rname);
        anotify_nolisten2(player, buf);
        sprintf(buf, "_reg/%s", rname);
        pdat.flags = PROP_REFTYP;
        pdat.data.ref = action;
        set_property(player, buf, &pdat);
    }
    if (tp_autolinking) {
        DBFETCH(action)->sp.exit.ndest = 1;
        DBFETCH(action)->sp.exit.dest = (dbref *) malloc(sizeof(dbref));
        (DBFETCH(action)->sp.exit.dest)[0] = NIL;
        sprintf(buf, CINFO "Linked to NIL.");
        anotify_nolisten2(player, buf);
    }

}
Beispiel #12
0
/* Parse a options. */
static bool
parse_options (int argc, char *argv[])
{
  int opt;

  static const char helpText[] =
    "Usage: %s [OPTION...]\n"
    "  -a, --access-mode=STRING        Set CD control access mode\n"
    "  -m, --mode=MODE-TYPE            set CD-ROM read mode (audio, auto, m1f1, m1f2,\n"
    "                                  m2mf1, m2f2)\n"
    "  -d, --debug=INT                 Set debugging to LEVEL\n"
    "  -x, --hexdump                   Show output as a hex dump. The default is a\n"
    "                                  hex dump when output goes to stdout and no\n"
    "                                  hex dump when output is to a file.\n"
    "  -j, --just-hex                  Don't display printable chars on hex\n"
    "                                  dump. The default is print chars too.\n"
    "  --no-header                     Don't display header and copyright (for\n"
    "                                  regression testing)\n"
    "  --no-hexdump                    Don't show output as a hex dump.\n"
    "  -s, --start=INT                 Set LBA to start reading from\n"
    "  -e, --end=INT                   Set LBA to end reading from\n"
    "  -n, --number=INT                Set number of sectors to read\n"
    "  -b, --bin-file[=FILE]           set \"bin\" CD-ROM disk image file as source\n"
    "  -c, --cue-file[=FILE]           set \"cue\" CD-ROM disk image file as source\n"
    "  -i, --input[=FILE]              set source and determine if \"bin\" image or\n"
    "                                  device\n"
    "  -C, --cdrom-device[=DEVICE]     set CD-ROM device as source\n"
    "  -N, --nrg-file[=FILE]           set Nero CD-ROM disk image file as source\n"
    "  -t, --toc-file[=FILE]           set \"TOC\" CD-ROM disk image file as source\n"
    "  -o, --output-file=FILE          Output blocks to file rather than give a\n"
    "                                  hexdump.\n"
    "  -V, --version                   display version and copyright information\n"
    "                                  and exit\n"
    "\n"
    "Help options:\n"
    "  -?, --help                      Show this help message\n"
    "  --usage                         Display brief usage message\n";
  
  static const char usageText[] =
    "Usage: %s [-a|--access-mode STRING] [-m|--mode MODE-TYPE]\n"
    "        [-d|--debug INT] [-x|--hexdump] [--no-header] [--no-hexdump]\n"
    "        [-s|--start INT] [-e|--end INT] [-n|--number INT] [-b|--bin-file FILE]\n"
    "        [-c|--cue-file FILE] [-i|--input FILE] [-C|--cdrom-device DEVICE]\n"
    "        [-N|--nrg-file FILE] [-t|--toc-file FILE] [-o|--output-file FILE]\n"
    "        [-V|--version] [-?|--help] [--usage]\n";
  
  /* Command-line options */
  static const char optionsString[] = "a:m:d:xjs:e:n:b::c::i::C::N::t::o:V?";
  static const struct option optionsTable[] = {
  
    {"access-mode", required_argument, NULL, 'a'},
    {"mode", required_argument, NULL, 'm'},
    {"debug", required_argument, NULL, 'd'},
    {"hexdump", no_argument, NULL, 'x'},
    {"no-header", no_argument, &opts.no_header, 1},
    {"no-hexdump", no_argument, &opts.nohexdump, 1},
    {"just-hex", no_argument, &opts.just_hex, 'j'},
    {"start", required_argument, NULL, 's'},
    {"end", required_argument, NULL, 'e'},
    {"number", required_argument, NULL, 'n'},
    {"bin-file", optional_argument, NULL, 'b'},
    {"cue-file", optional_argument, NULL, 'c'},
    {"input", optional_argument, NULL, 'i'},
    {"cdrom-device", optional_argument, NULL, 'C'},
    {"nrg-file", optional_argument, NULL, 'N'},
    {"toc-file", optional_argument, NULL, 't'},
    {"output-file", required_argument, NULL, 'o'},
    {"version", no_argument, NULL, 'V'},
   
    {"help", no_argument, NULL, '?' },
    {"usage", no_argument, NULL, OP_USAGE },
    { NULL, 0, NULL, 0 }
  };
  
  program_name = strrchr(argv[0],'/');
  program_name = program_name ? strdup(program_name+1) : strdup(argv[0]);

  while ((opt = getopt_long(argc, argv, optionsString, optionsTable, NULL)) >= 0)
    switch (opt)
      {
      case 'a': opts.access_mode = strdup(optarg); break;
      case 'd': opts.debug_level = atoi(optarg); break;
      case 'x': opts.hexdump = 1; break;
      case 's': opts.start_lsn = atoi(optarg); break;
      case 'e': opts.end_lsn = atoi(optarg); break;
      case 'n': opts.num_sectors = atoi(optarg); break;
      case 'b': parse_source(OP_SOURCE_BIN); break;
      case 'c': parse_source(OP_SOURCE_CUE); break;
      case 'i': parse_source(OP_SOURCE_AUTO); break;
      case 'C': parse_source(OP_SOURCE_DEVICE); break;
      case 'N': parse_source(OP_SOURCE_NRG); break;
      case 't': parse_source(OP_SOURCE_CDRDAO); break;
      case 'o': opts.output_file = strdup(optarg); break;
     
      case 'm':
	process_suboption(optarg, modes_sublist,
			  sizeof(modes_sublist) / sizeof(subopt_entry_t),
                            "--mode");
        break;

      case 'V':
        print_version(program_name, VERSION, 0, true);
	free(program_name);
        exit (EXIT_SUCCESS);
        break;

      case '?':
	fprintf(stdout, helpText, program_name);
	free(program_name);
	exit(EXIT_INFO);
	break;
	
      case OP_USAGE:
	fprintf(stderr, usageText, program_name);
	free(program_name);
	exit(EXIT_FAILURE);
	break;

      case OP_HANDLED:
	break;
      }

  if (optind < argc) {
    const char *remaining_arg = argv[optind++];

    /* NOTE: A bug in the libpopt version checked source_image, which
       rendered the subsequent source_image test useless.
    */
    if (source_name != NULL) {
      report( stderr, "%s: Source specified in option %s and as %s\n", 
	      program_name, source_name, remaining_arg );
      free(program_name);
      exit (EXIT_FAILURE);
    }

    if (opts.source_image == INPUT_DEVICE)
      source_name = fillout_device_name(remaining_arg);
    else 
      source_name = strdup(remaining_arg);
      
    if (optind < argc) {
      report( stderr, "%s: Source specified in previously %s and %s\n", 
	      program_name, source_name, remaining_arg );
      free(program_name);
      exit (EXIT_FAILURE);
    }
  }
  
  if (opts.debug_level == 3) {
    cdio_loglevel_default = CDIO_LOG_INFO;
  } else if (opts.debug_level >= 4) {
    cdio_loglevel_default = CDIO_LOG_DEBUG;
  }

  if (opts.read_mode == READ_MODE_UNINIT) {
    report( stderr, 
	    "%s: Need to give a read mode "
	    "(audio, m1f1, m1f2, m2f1, m2f2, or auto)\n",
	    program_name );
    free(program_name);
    exit(10);
  }

  /* Check consistency between start_lsn, end_lsn and num_sectors. */

  if (opts.nohexdump && opts.hexdump != 2) {
    report( stderr, 
	    "%s: don't give both --hexdump and --no-hexdump together\n",
	    program_name );
    exit(13);
  }

  if (opts.nohexdump) opts.hexdump = 0;
  
  if (opts.start_lsn == CDIO_INVALID_LSN) {
    /* Maybe we derive the start from the end and num sectors. */
    if (opts.end_lsn == CDIO_INVALID_LSN) {
      /* No start or end LSN, so use 0 for the start */
      opts.start_lsn = 0;
      if (opts.num_sectors == 0) opts.num_sectors = 1;
    } else if (opts.num_sectors != 0) {
      if (opts.end_lsn <= opts.num_sectors) {
	report( stderr, "%s: end LSN (%lu) needs to be greater than "
		" the sector to read (%lu)\n",
		program_name, (unsigned long) opts.end_lsn, 
		(unsigned long) opts.num_sectors );
	exit(12);
      }
      opts.start_lsn = opts.end_lsn - opts.num_sectors + 1;
    }
  }

  /* opts.start_lsn has been set somehow or we've aborted. */

  if (opts.end_lsn == CDIO_INVALID_LSN) {
    if (0 == opts.num_sectors) opts.num_sectors = 1;
    opts.end_lsn = opts.start_lsn + opts.num_sectors - 1;
  } else {
    /* We were given an end lsn. */
    if (opts.end_lsn < opts.start_lsn) {
      report( stderr, 
	      "%s: end LSN (%lu) needs to be less than start LSN (%lu)\n",
	      program_name, (unsigned long) opts.start_lsn, 
	      (unsigned long) opts.end_lsn );
      free(program_name);
      exit(13);
    }
    if (opts.num_sectors != opts.end_lsn - opts.start_lsn + 1)
      if (opts.num_sectors != 0) {
	 report( stderr, 
		 "%s: inconsistency between start LSN (%lu), end (%lu), "
		 "and count (%d)\n",
		 program_name, (unsigned long) opts.start_lsn, 
		 (unsigned long) opts.end_lsn, opts.num_sectors );
	 free(program_name);
	 exit(14);
	}
    opts.num_sectors = opts.end_lsn - opts.start_lsn + 1;
  }
  
  return true;
}
Beispiel #13
0
Datei: main.cpp Projekt: ysei/cpu
int main(int argc, char **argv)
{
    int err;

    // read in any overriding configuration from the command line
    for(;;) {
        int c;
        int option_index = 0;

        static struct option long_options[] = {
            {"output", 1, 0, 'o'},
            {0, 0, 0, 0},
        };
        
        c = getopt_long(argc, argv, "o:", long_options, &option_index);
        if(c == -1)
            break;

        switch(c) {
            case 'o':
                output_filename = optarg;
                break;
            default:
                usage(argc, argv);
                break;
        }
    }

    if (argc - optind < 1) {
        usage(argc, argv);
        return 1;
    }

    argc -= optind;
    argv += optind;

    // start preprocessor
    int preprocess_out = preprocess(argv[0]);
    if (preprocess_out < 0) {
        fprintf(stderr, "error starting preprocessor\n");
        return 1;
    }

    if (open_input(preprocess_out, argv[0]) < 0) {
        fprintf(stderr, "error opening input file\n");
        return 1;
    }

    if (output_filename == "") {
        // build one out of the input file
        output_filename = std::string(argv[0]) + ".bin";
        printf("output file %s\n", output_filename.c_str());
    }

    OutputFile *f = new OutputFile();
    if (f->OpenFile(output_filename) < 0) {
        fprintf(stderr, "error opening output file\n");
        return 1;
    }

    gSymtab = new Symtab();
    gCodegen = new Codegen();
    gCodegen->InitSymtab(gSymtab);
    gCodegen->SetOutput(f);

    err = parse_source();
    if (err < 0)
        goto err;
    
    gCodegen->FixupPass();

err:
    close(preprocess_out);
    delete gCodegen;
    delete gSymtab;
    delete f;

    return err;
}
Beispiel #14
0
/* Parse all options. */
static bool
parse_options (int argc, char *argv[])
{
  int opt; /* used for argument parsing */

  static const char helpText[] =
    "Usage: %s [OPTION...]\n"
    "  -a, --access-mode=STRING        Set CD access method\n"
    "  -d, --debug=INT                 Set debugging to LEVEL\n"
    "  -T, --no-tracks                 Don't show track information\n"
    "  -A, --no-analyze                Don't show filesystem analysis\n"
#ifdef HAVE_CDDB
    "  --no-cddb                       Don't look up audio CDDB information\n"
    "                                  or print it\n"
    "  -P, --cddb-port=INT             CDDB port number to use (default 8880)\n"
    "  -H, --cddb-http                 Lookup CDDB via HTTP proxy (default no\n"
    "                                  proxy)\n"
    "  --cddb-server=STRING            CDDB server to contact for information\n"
    "                                  (default: freedb.freedb.org)\n"
    "  --cddb-cache=STRING             Location of CDDB cache directory\n"
    "                                  (default ~/.cddbclient)\n"
    "  --cddb-email=STRING             Email address to give CDDB server\n"
    "                                  (default me@home)\n"
    "  --no-cddb-cache                 Disable caching of CDDB entries\n"
    "                                  locally (default caches)\n"
    "  --cddb-timeout=INT              CDDB timeout value in seconds\n"
    "                                  (default 10 seconds)\n"
#else
    "  --no-cddb                       Does nothing since this program is not\n"
    "  -P, --cddb-port=INT             CDDB-enabled\n"
    "  -H, --cddb-http\n"
    "  --cddb-server=STRING\n"
    "  --cddb-cache=STRING\n"
    "  --cddb-email=STRING\n"
    "  --no-cddb-cache\n"
    "  --cddb-timeout=INT\n"
#endif
    "  --no-device-info                Don't show device info, just CD info\n"
    "  --no-disc-mode                  Don't show disc-mode info\n"
    "  --dvd                           Attempt to give DVD information if a DVD is\n"
    "                                  found.\n"
#ifdef HAVE_VCDINFO
    "  -v, --no-vcd                    Don't look up Video CD information\n"
#else
    "  -v, --no-vcd                    Don't look up Video CD information - for\n"
    "                                  this build, this is always set\n"
#endif
    "  -I, --no-ioctl                  Don't show ioctl() information\n"
    "  -b, --bin-file[=FILE]           set \"bin\" CD-ROM disk image file as source\n"
    "  -c, --cue-file[=FILE]           set \"cue\" CD-ROM disk image file as source\n"
    "  -N, --nrg-file[=FILE]           set Nero CD-ROM disk image file as source\n"
    "  -t, --toc-file[=FILE]           set cdrdao CD-ROM disk image file as source\n"
    "  -i, --input[=FILE]              set source and determine if \"bin\" image or\n"
    "                                  device\n"
    "  --iso9660                       print directory contents of any ISO-9660\n"
    "                                  filesystems\n"
    "  -C, --cdrom-device[=DEVICE]     set CD-ROM device as source\n"
    "  -l, --list-drives               Give a list of CD-drives\n"
    "  --no-header                     Don't display header and copyright (for\n"
    "                                  regression testing)\n"
#ifdef HAVE_JOLIET
    "  --no-joliet                     Don't use Joliet extensions\n"
#endif
    "  --no-rock-ridge                 Don't use Rock-Ridge-extension information\n"
    "  --no-xa                         Don't use XA-extension information\n"
    "  -q, --quiet                     Don't produce warning output\n"
    "  -V, --version                   display version and copyright information\n"
    "                                  and exit\n"
    "\n"
    "Help options:\n"
    "  -?, --help                      Show this help message\n"
    "  --usage                         Display brief usage message\n";
  
  static const char usageText[] = 
    "Usage: %s [-a|--access-mode STRING] [-d|--debug INT] [-T|--no-tracks]\n"
    "        [-A|--no-analyze] [--no-cddb] [-P|--cddb-port INT] [-H|--cddb-http]\n"
    "        [--cddb-server=STRING] [--cddb-cache=STRING] [--cddb-email=STRING]\n"
    "        [--no-cddb-cache] [--cddb-timeout=INT] [--no-device-info]\n"
    "        [--no-disc-mode] [--dvd] [-v|--no-vcd] [-I|--no-ioctl]\n"
    "        [-b|--bin-file FILE] [-c|--cue-file FILE] [-N|--nrg-file FILE]\n"
    "        [-t|--toc-file FILE] [-i|--input FILE] [--iso9660]\n"
    "        [-C|--cdrom-device DEVICE] [-l|--list-drives] [--no-header]\n"
    "        [--no-joliet] [--no-rock-ridge] [--no-xa] [-q|--quiet] [-V|--version]\n"
    "        [-?|--help] [--usage]\n";

  static const char optionsString[] = "a:d:TAP:HvIb::c::N::t::i::C::lqV?";
  static const struct option optionsTable[] = {
    {"access-mode", required_argument, NULL, 'a'},
    {"debug", required_argument, NULL, 'd' },
    {"no-tracks", no_argument, NULL, 'T' },
    {"no-analyze", no_argument, NULL, 'A' },
    {"no-cddb", no_argument, &opts.no_cddb, 1 },
    {"cddb-port", required_argument, NULL, 'P' },
    {"cddb-http", no_argument, NULL, 'H' },
    {"cddb-server", required_argument, NULL, OP_CDDB_SERVER },
    {"cddb-cache", required_argument, NULL, OP_CDDB_CACHE },
    {"cddb-email", required_argument, NULL, OP_CDDB_EMAIL },
    {"no-cddb-cache", no_argument, NULL, OP_CDDB_NOCACHE },
    {"cddb-timeout", required_argument, NULL, OP_CDDB_TIMEOUT },
    {"no-device-info", no_argument, &opts.no_device, 1 },
    {"no-disc-mode", no_argument, &opts.no_disc_mode, 1 },
    {"dvd", no_argument, &opts.show_dvd, 1 },
    {"no-vcd", no_argument, NULL, 'v' },
    {"no-ioctl", no_argument, NULL, 'I' },
    {"bin-file", optional_argument, NULL, 'b' },
    {"cue-file", optional_argument, NULL, 'c' },
    {"nrg-file", optional_argument, NULL, 'N' },
    {"toc-file", optional_argument, NULL, 't' },
    {"input", optional_argument, NULL, 'i' },
    {"iso9660", no_argument, &opts.print_iso9660, 1 },
    {"cdrom-device", optional_argument, NULL, 'C' },
    {"list-drives", no_argument, NULL, 'l' },
    {"no-header", no_argument, &opts.no_header, 1 }, 
#ifdef HAVE_JOLIET    
    {"no-joliet", no_argument, &opts.no_joliet, 1 },
#endif /*HAVE_JOLIET*/
    {"no-rock-ridge", no_argument, &opts.no_rock_ridge, 1 },
    {"no-xa", no_argument, &opts.no_xa, 1 },
    {"quiet", no_argument, NULL, 'q' },
    {"version", no_argument, NULL, 'V' },

    {"help", no_argument, NULL, '?' },
    {"usage", no_argument, NULL, OP_USAGE },
    { NULL, 0, NULL, 0 }
  };

  program_name = strrchr(argv[0],'/');
  program_name = program_name ? strdup(program_name+1) : strdup(argv[0]);

  while ((opt = getopt_long(argc, argv, optionsString, optionsTable, NULL)) >= 0) {
    switch (opt) {
    case 'a': opts.access_mode = strdup(optarg); break;
    case 'd': opts.debug_level = atoi(optarg); break;
    case 'T': opts.no_tracks = 1; break;
    case 'A': opts.no_analysis = 1; break;
#ifdef HAVE_CDDB
    case 'P': cddb_opts.port = atoi(optarg); break;
    case 'H': cddb_opts.http = 1; break;
    case OP_CDDB_SERVER: cddb_opts.server = strdup(optarg); break;
    case OP_CDDB_CACHE: cddb_opts.cachedir = strdup(optarg); break;
    case OP_CDDB_EMAIL: cddb_opts.email = strdup(optarg); break;
    case OP_CDDB_NOCACHE: cddb_opts.disable_cache = 1; break;
    case OP_CDDB_TIMEOUT: cddb_opts.timeout = atoi(optarg); break;
#endif
    case 'v': opts.no_vcd = 1; break;
    case 'I': opts.no_ioctl = 1; break;
    case 'b': parse_source(OP_SOURCE_BIN); break;
    case 'c': parse_source(OP_SOURCE_CUE); break;
    case 'N': parse_source(OP_SOURCE_NRG); break;
    case 't': parse_source(OP_SOURCE_CDRDAO); break;
    case 'i': parse_source(OP_SOURCE_AUTO); break;
    case 'C': parse_source(OP_SOURCE_DEVICE); break;
    case 'l': opts.list_drives = 1; break;
    case 'q': opts.silent = 1; break;
    case 'V': opts.version_only = 1; break;

    case '?':
      fprintf(stdout, helpText, program_name);
      free(program_name);
      exit(EXIT_INFO);
      break;

    case OP_USAGE:
      fprintf(stderr, usageText, program_name);
      free(program_name);
      exit(EXIT_FAILURE);
      break;

    case OP_HANDLED:
      break;
    }
  }

  if (optind < argc) {
    const char *remaining_arg = argv[optind++];

    if (source_name != NULL) {
      report(stderr, "%s: Source '%s' given as an argument of an option and as "
             "unnamed option '%s'\n", 
             program_name, source_name, remaining_arg);
      free(program_name);
      exit (EXIT_FAILURE);
    }

    if (opts.source_image == INPUT_DEVICE)
      source_name = fillout_device_name(remaining_arg);
    else 
      source_name = strdup(remaining_arg);

    if (optind < argc) {
      report(stderr, "%s: Source specified in previously %s and %s\n", 
             program_name, source_name, remaining_arg);
      free(program_name);
      exit (EXIT_FAILURE);
    }
  }

  return true;
}
void CSSParserBorderImage::parse(const std::string &name, const std::vector<CSSToken> &tokens, std::vector<std::unique_ptr<CSSPropertyValue> > &inout_values)
{
    std::unique_ptr<CSSValueBorderImageSource> border_image_source(new CSSValueBorderImageSource());
    std::unique_ptr<CSSValueBorderImageSlice> border_image_slice(new CSSValueBorderImageSlice());
    std::unique_ptr<CSSValueBorderImageWidth> border_image_width(new CSSValueBorderImageWidth());
    std::unique_ptr<CSSValueBorderImageOutset> border_image_outset(new CSSValueBorderImageOutset());
    std::unique_ptr<CSSValueBorderImageRepeat> border_image_repeat(new CSSValueBorderImageRepeat());

    if (tokens.size() == 1 && tokens[0].type == CSSToken::type_ident && equals(tokens[0].value, "inherit"))
    {
        border_image_source->type = CSSValueBorderImageSource::type_inherit;
        border_image_slice->type = CSSValueBorderImageSlice::type_inherit;
        border_image_width->type = CSSValueBorderImageWidth::type_inherit;
        border_image_outset->type = CSSValueBorderImageOutset::type_inherit;
        border_image_repeat->type = CSSValueBorderImageRepeat::type_inherit;

        inout_values.push_back(std::move(border_image_source));
        inout_values.push_back(std::move(border_image_slice));
        inout_values.push_back(std::move(border_image_width));
        inout_values.push_back(std::move(border_image_outset));
        inout_values.push_back(std::move(border_image_repeat));

        return;
    }

    bool source_specified = false;
    bool slice_specified = false;
    bool repeat_specified = false;

    size_t pos = 0;
    do
    {
        if (!source_specified && parse_source(*border_image_source.get(), pos, tokens))
        {
            source_specified = true;
        }
        else if (!slice_specified && parse_slice(*border_image_slice.get(), pos, tokens))
        {
            slice_specified = true;

            size_t next_pos = pos;
            CSSToken token = next_token(next_pos, tokens);
            if (token.type == CSSToken::type_delim && token.value == "/")
            {
                pos = next_pos;
                if (parse_width(*border_image_width.get(), pos, tokens))
                {
                    next_pos = pos;
                    CSSToken token = next_token(next_pos, tokens);
                    if (token.type == CSSToken::type_delim && token.value == "/")
                    {
                        pos = next_pos;
                        if (!parse_outset(*border_image_outset.get(), pos, tokens))
                        {
                            return;
                        }
                    }
                }
                else if (!parse_outset(*border_image_outset.get(), pos, tokens))
                {
                    return;
                }
            }
        }
        else if (!repeat_specified && parse_repeat(*border_image_repeat.get(), pos, tokens))
        {
            repeat_specified = true;
        }
        else
        {
            return;
        }
    } while (pos != tokens.size());

    inout_values.push_back(std::move(border_image_source));
    inout_values.push_back(std::move(border_image_slice));
    inout_values.push_back(std::move(border_image_width));
    inout_values.push_back(std::move(border_image_outset));
    inout_values.push_back(std::move(border_image_repeat));
}