Example #1
0
/* Parse the options strings in ARGC & ARGV according to the argp in ARGP.
   FLAGS is one of the ARGP_ flags above.  If END_INDEX is non-NULL, the
   index in ARGV of the first unparsed option is returned in it.  If an
   unknown option is present, EINVAL is returned; if some parser routine
   returned a non-zero value, it is returned; otherwise 0 is returned.  */
error_t
__argp_parse(const struct argp *argp, int argc, char **argv, unsigned flags,
	     int *end_index, void *input)
{
  error_t err;
  struct parser parser;

  /* If true, then err == EBADKEY is a result of a non-option argument
   * failing to be parsed (which in some cases is actually a non-error): */
  int arg_ebadkey = 0;

  if (! (flags & ARGP_NO_HELP)) {
    /* Add our own options: */
    struct argp_child *child;
    struct argp *top_argp;

    child = (struct argp_child *)alloca(4 * sizeof(struct argp_child));
    top_argp = (struct argp *)alloca(sizeof(struct argp));
    /* TOP_ARGP has no options, it just serves to group the user & default
     * argps: */
    memset(top_argp, 0, sizeof(*top_argp));
    top_argp->children = child;

    memset(child, 0, (4 * sizeof(struct argp_child)));

    if (argp)
      (child++)->argp = argp;
    (child++)->argp = &argp_default_argp;
    if (argp_program_version || argp_program_version_hook)
      (child++)->argp = &argp_version_argp;
    child->argp = 0;

    argp = top_argp;
  }

  /* Construct a parser for these arguments: */
  err = parser_init(&parser, argp, argc, argv, (int)flags, input);

  if (! err) {
    /* Parse! */
    while (! err) {
      err = parser_parse_next(&parser, &arg_ebadkey);
    }
    err = parser_finalize(&parser, err, arg_ebadkey, end_index);
  }

  return err;
}
Example #2
0
int
server_config_parse_string(const struct config_parser *parser,
			   const char *file,
			   uint32_t length, const uint8_t *data,
			   void *input)
{
  struct config_tokenizer tokenizer;
  struct parser_state state;

  int err;

  config_tokenizer_init(&tokenizer, file, length, data);
  
  err = parser_init(&state, parser, input);
  if (err)
    return err;

  while (!err)
    {
      enum config_token_type type = config_tokenizer_next(&tokenizer);
      switch (type)
	{
	default:
	  err = EINVAL;
	  break;
	case TOK_STRING:
	  err = parser_parse_option(&state, &tokenizer);
	  break;
	case TOK_EOF:
	  goto done;
	}
      /* FIXME: Require newline or separator between options? */
    }  
 done:
  
  parser_finalize(&state);
  return err;
}
Example #3
0
/**
 * Helper, called whenever a full response line is collected.
 */
static void parser_handle_line(struct at_parser *parser)
{
    /* Skip empty lines. */
    if (parser->buf_used == parser->buf_current)
        return;

    /* NULL-terminate the response .*/
    parser->buf[parser->buf_used] = '\0';

    /* Extract line address & length for later use. */
    const char *line = parser->buf + parser->buf_current;
    size_t len = parser->buf_used - parser->buf_current;

    /* Log the received line. */
    printf("< '%.*s'\n", (int) len, line);

    /* Determine response type. */
    enum at_response_type type = AT_RESPONSE_UNKNOWN;
    if (parser->cbs->scan_line)
        type = parser->cbs->scan_line(line, len, parser->priv);
    if (!type)
        type = generic_line_scanner(line, len, parser);

    /* Expected URCs and all unexpected lines are sent to URC handler. */
    if (type == AT_RESPONSE_URC || parser->state == STATE_IDLE)
    {
        /* Fire the callback on the URC line. */
        parser->cbs->handle_urc(parser->buf + parser->buf_current,
                                parser->buf_used - parser->buf_current,
                                parser->priv);

        /* Discard the URC line from the buffer. */
        parser_discard_line(parser);

        return;
    }

    /* Accumulate everything that's not a final OK. */
    if (type != AT_RESPONSE_FINAL_OK) {
        /* Include the line in the buffer. */
        parser_include_line(parser);
    } else {
        /* Discard the line from the buffer. */
        parser_discard_line(parser);
    }

    /* Act on the response type. */
    switch (type & _AT_RESPONSE_TYPE_MASK) {
        case AT_RESPONSE_FINAL_OK:
        case AT_RESPONSE_FINAL:
        {
            /* Fire the response callback. */
            parser_finalize(parser);
            parser->cbs->handle_response(parser->buf, parser->buf_used, parser->priv);

            /* Go back to idle state. */
            at_parser_reset(parser);
        }
        break;

        case _AT_RESPONSE_RAWDATA_FOLLOWS:
        {
            /* Switch parser state to rawdata mode. */
            parser->data_left = (int)type >> 8;
            parser->state = STATE_RAWDATA;
        }
        break;

        case _AT_RESPONSE_HEXDATA_FOLLOWS:
        {
            /* Switch parser state to hexdata mode. */
            parser->data_left = (int)type >> 8;
            parser->nibble = -1;
            parser->state = STATE_HEXDATA;
        }
        break;

        default:
        {
            /* Keep calm and carry on. */
        }
        break;
    }
}
Example #4
0
int
server_config_parse_example(const struct config_parser *parser,
			    void *input)
{
  struct parser_state state;
  struct group *group;
  int err;

  err = parser_init(&state, parser, input);
  if (err)
    return err;

  for (group = state.egroup - 1; group >= state.groups; group--)
    {
      const struct config_parser *parser= group->parser; 
      const struct config_option *option;

      for (option = parser->options; option->type != CONFIG_TYPE_NONE; option++)
	if (option->example)
	  {
	    uint32_t value = 0;
	    const uint8_t *data = NULL;

	    unsigned length = strlen(option->example);

	    switch (option->type)
	      {
	      default:
		fatal("Internal error.\n");

	      case CONFIG_TYPE_LIST:
		{
		  struct config_tokenizer tokenizer;
		  uint8_t *list;
		  
		  config_tokenizer_init(&tokenizer, "example fragment",
					length, option->example);

		  err = parse_value_list(&value, &list, &tokenizer);
		  data = list;
		  break;
		}
	      case CONFIG_TYPE_BOOL:
		err = parse_value_bool(&value, length, option->example);
		break;

	      case CONFIG_TYPE_NUMBER:
		err = parse_value_unsigned(&value, length, option->example);
		break;

	      case CONFIG_TYPE_STRING:
		value = length;
		data = option->example;
		break;
	      }
	  
	    if (err)
	      fatal("Bad example value for configuration option `%z'\n",
		    option->name);
	    else
	      err = group->parser->handler(option->key, value, data, &group->state);

	  }
    }
  parser_finalize(&state);
  return err;
}