예제 #1
0
/** Parse member function.
 *
 * @param parse		Parser object.
 * @param outer_csi	CSI containing this declaration or @c NULL if global.
 * @return		New syntax tree node.
 */
static stree_fun_t *parse_fun(parse_t *parse, stree_csi_t *outer_csi)
{
	stree_fun_t *fun;
	stree_symbol_t *symbol;
	bool_t body_expected;

	fun = stree_fun_new();
	symbol = stree_symbol_new(sc_fun);

	symbol->u.fun = fun;
	symbol->outer_csi = outer_csi;
	fun->symbol = symbol;

	lmatch(parse, lc_fun);
	fun->name = parse_ident(parse);

#ifdef DEBUG_PARSE_TRACE
	printf("Parsing function '%s'.\n", strtab_get_str(fun->name->sid));
#endif
	fun->sig = parse_fun_sig(parse);

	/* Parse attributes. */
	parse_symbol_attrs(parse, symbol);

	body_expected = !stree_symbol_has_attr(symbol, sac_builtin) &&
	    (outer_csi->cc != csi_interface);

	fun->proc = stree_proc_new();
	fun->proc->outer_symbol = symbol;

	if (lcur_lc(parse) == lc_scolon) {
		lskip(parse);

		/* Body not present */
		if (body_expected) {
			cspan_print(fun->name->cspan);
			printf(" Error: Function '");
			symbol_print_fqn(symbol);
			printf("' should have a body.\n");
			parse_note_error(parse);
		}

		fun->proc->body = NULL;
	} else {
		lmatch(parse, lc_is);
		fun->proc->body = parse_block(parse);
		lmatch(parse, lc_end);

		/* Body present */
		if (!body_expected) {
			cspan_print(fun->name->cspan);
			printf(" Error: Function declaration '");
			symbol_print_fqn(symbol);
			printf("' should not have a body.\n");
			parse_note_error(parse);
		}
	}

	return fun;
}
예제 #2
0
파일: parsecfg.c 프로젝트: NUOG/ejudge
static int
parse_primary_expr(int need_eval, cfg_cond_value_t *prv)
{
  int r;

  while (parsecfg_state.raw.s[parsecfg_state.raw_i] > 0 && parsecfg_state.raw.s[parsecfg_state.raw_i] <= ' ') parsecfg_state.raw_i++;
  if (parsecfg_state.raw.s[parsecfg_state.raw_i] == '(') {
    parsecfg_state.raw_i++;
    if ((r = parse_conditional_expr(need_eval, prv)) < 0) return -1;
    while (parsecfg_state.raw.s[parsecfg_state.raw_i] > 0 && parsecfg_state.raw.s[parsecfg_state.raw_i] <= ' ') parsecfg_state.raw_i++;
    if (parsecfg_state.raw.s[parsecfg_state.raw_i] != ')') {
      fprintf(stderr, "%d: ')' expected\n", parsecfg_state.lineno);
      if (need_eval) free_value(prv);
      return -1;
    }
    parsecfg_state.raw_i++;
    return r;
  } else if (parsecfg_state.raw.s[parsecfg_state.raw_i] == '\"') {
    return parse_string(need_eval, prv);
  } else if (isalpha(parsecfg_state.raw.s[parsecfg_state.raw_i]) || parsecfg_state.raw.s[parsecfg_state.raw_i] == '_') {
    return parse_ident(need_eval, prv);
  } else if (isdigit(parsecfg_state.raw.s[parsecfg_state.raw_i])) {
    return parse_number(need_eval, prv);
  }
  fprintf(stderr, "%d: primary expression expected\n", parsecfg_state.lineno);
  return -1;
}
예제 #3
0
/** Parse member variable.
 *
 * @param parse		Parser object.
 * @param outer_csi	CSI containing this declaration or @c NULL if global.
 * @return		New syntax tree node.
 */
static stree_var_t *parse_var(parse_t *parse, stree_csi_t *outer_csi)
{
	stree_var_t *var;
	stree_symbol_t *symbol;

	var = stree_var_new();
	symbol = stree_symbol_new(sc_var);
	symbol->u.var = var;
	symbol->outer_csi = outer_csi;
	var->symbol = symbol;

	lmatch(parse, lc_var);
	var->name = parse_ident(parse);
	lmatch(parse, lc_colon);
	var->type =  parse_texpr(parse);

	parse_symbol_attrs(parse, symbol);

	lmatch(parse, lc_scolon);

	switch (outer_csi->cc) {
	case csi_class:
	case csi_struct:
		break;
	case csi_interface:
		cspan_print(var->name->cspan);
		printf(" Error: Variable declared inside interface.\n");
		parse_note_error(parse);
		/* XXX Free var */
		return NULL;
	}

	return var;
}
예제 #4
0
static int parse_html_tag (char **start, char *end)
{
  int result = -1;
  char *token = NULL;
  int closing = 0;
  skip_white(start, end);
  if (*start < end) {
    if (**start == '/') {
      (*start)++;
      closing = 1;
    }
    if (*start < end && (token = parse_ident (start, end))) {
      downcase (token);
      {
	int i;
	for (i=0; i<sizeof(tags)/sizeof(tags[0]); i++) {
	  if (!strcmp (token, tags[i])) {
	    result = i;
	    if (closing) 
	      result += sizeof(tags)/sizeof(tags[0]);
	  }
	  break;
	}
	if (i>=sizeof(tags)/sizeof(tags[0]))
	  result = -1;
      }
      RELEASE (token);
    }
  }
  return result;
}
예제 #5
0
/** Parse variable declaration statement.
 *
 * @param parse		Parser object.
 * @return		New syntax tree node.
 */
static stree_vdecl_t *parse_vdecl(parse_t *parse)
{
	stree_vdecl_t *vdecl;

	vdecl = stree_vdecl_new();

	lmatch(parse, lc_var);
	vdecl->name = parse_ident(parse);
	lmatch(parse, lc_colon);
	vdecl->type = parse_texpr(parse);

	if (lcur_lc(parse) == lc_assign) {
		lskip(parse);
		(void) parse_expr(parse);
	}

	lmatch(parse, lc_scolon);

#ifdef DEBUG_PARSE_TRACE
	printf("Parsed vdecl for '%s'\n", strtab_get_str(vdecl->name->sid));
	printf("vdecl = %p, vdecl->name = %p, sid=%d\n",
	    vdecl, vdecl->name, vdecl->name->sid);
#endif
	return vdecl;
}
예제 #6
0
/** Parse @c enum declaration.
 *
 * @param parse		Parser object.
 * @param outer_csi	CSI containing this declaration or @c NULL if global.
 * @return		New syntax tree node.
 */
static stree_enum_t *parse_enum(parse_t *parse, stree_csi_t *outer_csi)
{
	stree_enum_t *enum_d;
	stree_symbol_t *symbol;
	stree_embr_t *embr;

	enum_d = stree_enum_new();
	symbol = stree_symbol_new(sc_enum);

	symbol->u.enum_d = enum_d;
	symbol->outer_csi = outer_csi;
	enum_d->symbol = symbol;

	lmatch(parse, lc_enum);
	enum_d->name = parse_ident(parse);
	list_init(&enum_d->members);

#ifdef DEBUG_PARSE_TRACE
	printf("Parse enum '%s'.\n", strtab_get_str(enum_d->name->sid));
#endif
	lmatch(parse, lc_is);

	/* Parse enum members. */
	while (lcur_lc(parse) != lc_end && !parse_is_error(parse)) {
		embr = parse_embr(parse, enum_d);
		if (embr == NULL)
			break;

		list_append(&enum_d->members, embr);
	}

	if (list_is_empty(&enum_d->members)) {
		cspan_print(enum_d->name->cspan);
		printf("Error: Enum type '%s' has no members.\n",
		    strtab_get_str(enum_d->name->sid));
		parse_note_error(parse);
	}

	lmatch(parse, lc_end);

	if (outer_csi != NULL) {
		switch (outer_csi->cc) {
		case csi_class:
		case csi_struct:
			break;
		case csi_interface:
			cspan_print(enum_d->name->cspan);
			printf(" Error: Enum declared inside interface.\n");
			parse_note_error(parse);
			/* XXX Free enum */
			return NULL;
		}
	}

	return enum_d;
}
예제 #7
0
/** Parse enum member.
 *
 * @param parse		Parser object.
 * @param outer_enum	Enum containing this declaration.
 * @return		New syntax tree node. In case of parse error,
 *			@c NULL may (but need not) be returned.
 */
static stree_embr_t *parse_embr(parse_t *parse, stree_enum_t *outer_enum)
{
	stree_embr_t *embr;

	embr = stree_embr_new();
	embr->outer_enum = outer_enum;
	embr->name = parse_ident(parse);

	lmatch(parse, lc_scolon);

	return embr;
}
예제 #8
0
/* Parse @c except clause.
 *
 * @param parse		Parser object.
 * @return		New syntax tree node.
 */
static stree_except_t *parse_except(parse_t *parse)
{
	stree_except_t *except_c;

#ifdef DEBUG_PARSE_TRACE
	printf("Parse 'except' statement.\n");
#endif
	except_c = stree_except_new();

	lmatch(parse, lc_except);
	except_c->evar = parse_ident(parse);
	lmatch(parse, lc_colon);
	except_c->etype = parse_texpr(parse);
	lmatch(parse, lc_do);

	except_c->block = parse_block(parse);

	return except_c;
}
예제 #9
0
파일: syntax.c 프로젝트: hagenkaye/ne
void parse_color_def(struct high_color **color_list, unsigned char *p, unsigned char *name, int line)
{
    unsigned char bf[256];
    if (!parse_tows(&p, bf))
    {
        struct high_color *color, *gcolor;

        /* Find color */
        color = find_color(*color_list, bf, name);

        /* If it doesn't exist, create it */
        if (!color)
        {
            color = joe_malloc(sizeof(struct high_color));
            color->name = zdup(bf);
            color->color = 0;
            color->next = *color_list;
            *color_list = color;
        }
        else
        {
            i_printf_2((char *)joe_gettext(_("%s %d: Class already defined\n")), name, line);
        }

        /* Find it in global list */
        if (color_list != &global_colors && (gcolor = find_color(global_colors, bf, name)))
        {
            color->color = gcolor->color;
        }
        else
        {
            /* Parse color definition */
            while (parse_ws(&p, '#'), !parse_ident(&p, bf, sizeof(bf)))
            {
                color->color |= meta_color(bf);
            }
        }
    }
    else
    {
        i_printf_2((char *)joe_gettext(_("%s %d: Missing class name\n")), name, line);
    }
}
예제 #10
0
/** Parse delegate.
 *
 * @param parse		Parser object.
 * @param outer_csi	CSI containing this declaration or @c NULL if global.
 * @return		New syntax tree node.
 */
static stree_deleg_t *parse_deleg(parse_t *parse, stree_csi_t *outer_csi)
{
	stree_deleg_t *deleg;
	stree_symbol_t *symbol;

	deleg = stree_deleg_new();
	symbol = stree_symbol_new(sc_deleg);

	symbol->u.deleg = deleg;
	symbol->outer_csi = outer_csi;
	deleg->symbol = symbol;

	lmatch(parse, lc_deleg);
	deleg->name = parse_ident(parse);

#ifdef DEBUG_PARSE_TRACE
	printf("Parsing delegate '%s'.\n", strtab_get_str(deleg->name->sid));
#endif

	deleg->sig = parse_fun_sig(parse);

	/* Parse attributes. */
	parse_symbol_attrs(parse, symbol);

	lmatch(parse, lc_scolon);

	switch (outer_csi->cc) {
	case csi_class:
	case csi_struct:
		break;
	case csi_interface:
		cspan_print(deleg->name->cspan);
		printf(" Error: Delegate declared inside interface.\n");
		parse_note_error(parse);
		/* XXX Free deleg */
		return NULL;
	}

	return deleg;
}
예제 #11
0
/** Parse formal function argument.
 *
 * @param parse		Parser object.
 * @return		New syntax tree node.
 */
static stree_proc_arg_t *parse_proc_arg(parse_t *parse)
{
	stree_proc_arg_t *arg;
	stree_arg_attr_t *attr;

	arg = stree_proc_arg_new();
	arg->name = parse_ident(parse);
	lmatch(parse, lc_colon);
	arg->type = parse_texpr(parse);

#ifdef DEBUG_PARSE_TRACE
	printf("Parse procedure argument.\n");
#endif
	list_init(&arg->attr);

	/* Parse attributes. */
	while (lcur_lc(parse) == lc_comma && !parse_is_error(parse)) {
		lskip(parse);
		attr = parse_arg_attr(parse);
		list_append(&arg->attr, attr);
	}

	return arg;
}
예제 #12
0
파일: syntax.c 프로젝트: hagenkaye/ne
struct high_state *load_dfa(struct high_syntax *syntax)
{
    unsigned char name[1024];
    unsigned char buf[1024];
    unsigned char bf[256];
    int clist[256];
    unsigned char *p;
    int c;
    FILE *f = NULL;
    struct ifstack *stack = 0;
    struct high_state *state = 0; /* Current state */
    struct high_state *first = 0; /* First state */
    int line = 0;
    int this_one = 0;
    int inside_subr = 0;

    /* Load it */

    if ((p = (unsigned char *)exists_prefs_dir()) && strlen((const char *)p) + 2 + strlen(SYNTAX_DIR) + strlen(SYNTAX_EXT) + strlen((const char *)syntax->name) < sizeof name)
    {
        strcat(strcat(strcat(strcat(strcpy((char *)name, (const char *)p), SYNTAX_DIR), "/"), (const char *)syntax->name), SYNTAX_EXT);
        f = fopen((char *)name, "r");
    }

    if (!f && (p = (unsigned char *)exists_gprefs_dir()) && strlen((const char *)p) + 2 + strlen(SYNTAX_DIR) + strlen(SYNTAX_EXT) + strlen((const char *)syntax->name) < sizeof name)
    {
        strcat(strcat(strcat(strcat(strcpy((char *)name, (const char *)p), SYNTAX_DIR), "/"), (const char *)syntax->name), SYNTAX_EXT);
        f = fopen((char *)name, "r");
    }

    if (!f)
    {
        return 0;
    }

    /* Parse file */
    while (fgets((char *)buf, 1023, f))
    {
        ++line;
        p = buf;
        c = parse_ws(&p, '#');
        if (!parse_char(&p, '.'))
        {
            if (!parse_ident(&p, bf, sizeof(bf)))
            {
                if (!zcmp(bf, USTR "ifdef"))
                {
                    struct ifstack *st = joe_malloc(sizeof(struct ifstack));
                    st->next = stack;
                    st->else_part = 0;
                    st->ignore = 1;
                    st->skip = 1;
                    st->line = line;
                    if (!stack || !stack->ignore)
                    {
                        parse_ws(&p, '#');
                        if (!parse_ident(&p, bf, sizeof(bf)))
                        {
                            struct high_param *param;
                            for (param = syntax->params; param; param = param->next)
                                if (!zcmp(param->name, bf))
                                {
                                    st->ignore = 0;
                                    break;
                                }
                            st->skip = 0;
                        }
                        else
                        {
                            i_printf_2((char *)joe_gettext(_("%s %d: missing parameter for ifdef\n")), name, line);
                        }
                    }
                    stack = st;
                }
                else if (!zcmp(bf, USTR "else"))
                {
                    if (stack && !stack->else_part)
                    {
                        stack->else_part = 1;
                        if (!stack->skip)
                        {
                            stack->ignore = !stack->ignore;
                        }
                    }
                    else
                    {
                        i_printf_2((char *)joe_gettext(_("%s %d: else with no matching if\n")), name, line);
                    }
                }
                else if (!zcmp(bf, USTR "endif"))
                {
                    if (stack)
                    {
                        struct ifstack *st = stack;
                        stack = st->next;
                        joe_free(st);
                    }
                    else
                    {
                        i_printf_2((char *)joe_gettext(_("%s %d: endif with no matching if\n")), name, line);
                    }
                }
                else if (!zcmp(bf, USTR "subr"))
                {
                    parse_ws(&p, '#');
                    if (parse_ident(&p, bf, sizeof(bf)))
                    {
                        i_printf_2((char *)joe_gettext(_("%s %d: Missing subroutine name\n")), name, line);
                    }
                    else
                    {
                        if (!stack || !stack->ignore)
                        {
                            inside_subr = 1;
                            this_one = 0;
                            if (syntax->subr && !zcmp(bf, syntax->subr))
                            {
                                this_one = 1;
                            }
                        }
                    }
                }
                else if (!zcmp(bf, USTR "end"))
                {
                    if (!stack || !stack->ignore)
                    {
                        this_one = 0;
                        inside_subr = 0;
                    }
                }
                else
                {
                    i_printf_2((char *)joe_gettext(_("%s %d: Unknown control statement\n")), name, line);
                }
            }
            else
            {
                i_printf_2((char *)joe_gettext(_("%s %d: Missing control statement name\n")), name, line);
            }
        }
        else if (stack && stack->ignore)
        {
            /* Ignore this line because of ifdef */
        }
        else if (!parse_char(&p, '='))
        {
            /* Parse color */
            parse_color_def(&syntax->color, p, name, line);
        }
        else if ((syntax->subr && !this_one) || (!syntax->subr && inside_subr))
        {
            /* Ignore this line because it's not the code we want */
        }
        else if (!parse_char(&p, ':'))
        {
            if (!parse_ident(&p, bf, sizeof(bf)))
            {

                state = find_state(syntax, bf);

                if (!first)
                {
                    first = state;
                }

                parse_ws(&p, '#');
                if (!parse_tows(&p, bf))
                {
                    struct high_color *color;
                    for (color = syntax->color; color; color = color->next)
                        if (!zcmp(color->name, bf))
                        {
                            break;
                        }
                    if (color)
                    {
                        state->color = color->color;
                    }
                    else
                    {
                        state->color = 0;
                        i_printf_2((char *)joe_gettext(_("%s %d: Unknown class\n")), name, line);
                    }
                }
                else
                {
                    i_printf_2((char *)joe_gettext(_("%s %d: Missing color for state definition\n")), name, line);
                }
            }
            else
            {
                i_printf_2((char *)joe_gettext(_("%s %d: Missing state name\n")), name, line);
            }
        }
        else if (!parse_char(&p, '-'))
        {
            /* No. sync lines ignored */
        }
        else
        {
            c = parse_ws(&p, '#');

            if (!c)
            {
            }
            else if (c == '"' || c == '*' || c == '&')
            {
                if (state)
                {
                    struct high_cmd *cmd;
                    int delim = 0;
                    if (!parse_field(&p, USTR "*"))
                    {
                        int z;
                        for (z = 0; z != 256; ++z)
                        {
                            clist[z] = 1;
                        }
                    }
                    else if (!parse_field(&p, USTR "&"))
                    {
                        delim = 1;
                    }
                    else
                    {
                        c = parse_string(&p, bf, sizeof(bf));
                        if (c < 0)
                        {
                            i_printf_2((char *)joe_gettext(_("%s %d: Bad string\n")), name, line);
                        }
                        else
                        {
                            int z;
                            int first, second;
                            unsigned char *t = bf;
                            for (z = 0; z != 256; ++z)
                            {
                                clist[z] = 0;
                            }
                            while (!parse_range(&t, &first, &second))
                            {
                                if (first > second)
                                {
                                    second = first;
                                }
                                while (first <= second)
                                {
                                    clist[first++] = 1;
                                }
                            }
                        }
                    }
                    /* Create command */
                    cmd = mkcmd();
                    parse_ws(&p, '#');
                    if (!parse_ident(&p, bf, sizeof(bf)))
                    {
                        int z;
                        cmd->new_state = find_state(syntax, bf);
                        parse_options(syntax, cmd, f, p, 0, name, line);

                        /* Install command */
                        if (delim)
                        {
                            state->delim = cmd;
                        }
                        else for (z = 0; z != 256; ++z)
                                if (clist[z])
                                {
                                    state->cmd[z] = cmd;
                                }
                    }
                    else
                    {
                        i_printf_2((char *)joe_gettext(_("%s %d: Missing jump\n")), name, line);
                    }
                }
                else
                {
                    i_printf_2((char *)joe_gettext(_("%s %d: No state\n")), name, line);
                }
            }
            else
            {
                i_printf_2((char *)joe_gettext(_("%s %d: Unknown character\n")), name, line);
            }
        }
    }

    while (stack)
    {
        struct ifstack *st = stack;
        stack = st->next;
        i_printf_2((char *)joe_gettext(_("%s %d: ifdef with no matching endif\n")), name, st->line);
        joe_free(st);
    }

    fclose(f);

    return first;
}
예제 #13
0
파일: syntax.c 프로젝트: hagenkaye/ne
void parse_options(struct high_syntax *syntax, struct high_cmd *cmd, FILE *f, unsigned char *p, int parsing_strings, unsigned char *name, int line)
{
    unsigned char buf[1024];
    unsigned char bf[256];
    unsigned char bf1[256];

    while (parse_ws(&p, '#'), !parse_ident(&p, bf, sizeof(bf)))
    {
        if (!zcmp(bf, USTR "buffer"))
        {
            cmd->start_buffering = 1;
        }
        else if (!zcmp(bf, USTR "hold"))
        {
            cmd->stop_buffering = 1;
        }
        else if (!zcmp(bf, USTR "save_c"))
        {
            cmd->save_c = 1;
        }
        else if (!zcmp(bf, USTR "save_s"))
        {
            cmd->save_s = 1;
        }
        else if (!zcmp(bf, USTR "recolor"))
        {
            parse_ws(&p, '#');
            if (!parse_char(&p, '='))
            {
                parse_ws(&p, '#');
                if (parse_int(&p, &cmd->recolor))
                {
                    i_printf_2((char *)joe_gettext(_("%s %d: Missing value for option\n")), name, line);
                }
            }
            else
            {
                i_printf_2((char *)joe_gettext(_("%s %d: Missing value for option\n")), name, line);
            }
        }
        else if (!zcmp(bf, USTR "call"))
        {
            parse_ws(&p, '#');
            if (!parse_char(&p, '='))
            {
                parse_ws(&p, '#');
                if (!parse_char(&p, '.'))
                {
                    zcpy(bf, syntax->name);
                    goto subr;
                }
                else if (parse_ident(&p, bf, sizeof(bf)))
                {
                    i_printf_2((char *)joe_gettext(_("%s %d: Missing value for option\n")), name, line);
                }
                else
                {
                    if (!parse_char(&p, '.'))
                    {
subr:
                        if (parse_ident(&p, bf1, sizeof(bf1)))
                        {
                            i_printf_2((char *)joe_gettext(_("%s %d: Missing subroutine name\n")), name, line);
                        }
                        cmd->call = load_syntax_subr(bf, bf1, parse_params(syntax->params, &p, name, line));
                    }
                    else
                    {
                        cmd->call = load_syntax_subr(bf, 0, parse_params(syntax->params, &p, name, line));
                    }
                }
            }
            else
            {
                i_printf_2((char *)joe_gettext(_("%s %d: Missing value for option\n")), name, line);
            }
        }
        else if (!zcmp(bf, USTR "return"))
        {
            cmd->rtn = 1;
        }
        else if (!zcmp(bf, USTR "reset"))
        {
            cmd->reset = 1;
        }
        else if (!parsing_strings && (!zcmp(bf, USTR "strings") || !zcmp(bf, USTR "istrings")))
        {
            if (bf[0] == 'i')
            {
                cmd->ignore = 1;
            }
            while (fgets((char *)buf, 1023, f))
            {
                ++line;
                p = buf;
                parse_ws(&p, '#');
                if (*p)
                {
                    if (!parse_field(&p, USTR "done"))
                    {
                        break;
                    }
                    if (parse_string(&p, bf, sizeof(bf)) >= 0)
                    {
                        parse_ws(&p, '#');
                        if (cmd->ignore)
                        {
                            lowerize(bf);
                        }
                        if (!parse_ident(&p, bf1, sizeof(bf1)))
                        {
                            struct high_cmd *kw_cmd = mkcmd();
                            kw_cmd->noeat = 1;
                            kw_cmd->new_state = find_state(syntax, bf1);
                            if (!zcmp(bf, USTR "&"))
                            {
                                cmd->delim = kw_cmd;
                            }
                            else
                            {
                                if (!cmd->keywords)
                                {
                                    cmd->keywords = htmk(64);
                                }
                                htadd(cmd->keywords, zdup(bf), kw_cmd);
                            }
                            parse_options(syntax, kw_cmd, f, p, 1, name, line);
                        }
                        else
                        {
                            i_printf_2((char *)joe_gettext(_("%s %d: Missing state name\n")), name, line);
                        }
                    }
                    else
                    {
                        i_printf_2((char *)joe_gettext(_("%s %d: Missing string\n")), name, line);
                    }
                }
            }
        }
        else if (!zcmp(bf, USTR "noeat"))
        {
            cmd->noeat = 1;
        }
        else if (!zcmp(bf, USTR "mark"))
        {
            cmd->start_mark = 1;
        }
        else if (!zcmp(bf, USTR "markend"))
        {
            cmd->stop_mark = 1;
        }
        else if (!zcmp(bf, USTR "recolormark"))
        {
            cmd->recolor_mark = 1;
        }
        else
        {
            i_printf_2((char *)joe_gettext(_("%s %d: Unknown option\n")), name, line);
        }
    }
}
예제 #14
0
파일: syntax.c 프로젝트: hagenkaye/ne
struct high_param *parse_params(struct high_param *current_params, unsigned char **ptr, unsigned char *name, int line)
{
    unsigned char *p = *ptr;
    unsigned char bf[256];
    struct high_param *params;
    struct high_param **param_ptr;

    /* Propagate currently defined parameters */
    param_ptr = &params;
    while (current_params)
    {
        *param_ptr = joe_malloc(sizeof(struct high_param));
        (*param_ptr)->name = zdup(current_params->name);
        param_ptr = &(*param_ptr)->next;
        current_params = current_params->next;
    }
    *param_ptr = 0;

    parse_ws(&p, '#');
    if (!parse_char(&p, '('))
    {
        for (;;)
        {
            parse_ws(&p, '#');
            if (!parse_char(&p, ')'))
            {
                break;
            }
            else if (!parse_char(&p, '-'))
            {
                if (!parse_ident(&p, bf, sizeof(bf)))
                {
                    int cmp = 0;
                    param_ptr = &params;
                    /* Parameters are sorted */
                    while (*param_ptr && (cmp = zcmp(bf, (*param_ptr)->name)) > 0)
                    {
                        param_ptr = &(*param_ptr)->next;
                    }
                    if (*param_ptr && !cmp)
                    {
                        /* Remove this parameter */
                        struct high_param *param = *param_ptr;
                        *param_ptr = param->next;
                        joe_free(param);
                    }
                }
                else
                {
                    i_printf_2((char *)joe_gettext(_("%s %d: Missing parameter name\n")), name, line);
                }
            }
            else if (!parse_ident(&p, bf, sizeof(bf)))
            {
                int cmp = 0;
                param_ptr = &params;
                /* Keep parameters sorted */
                while (*param_ptr && (cmp = zcmp(bf, (*param_ptr)->name)) > 0)
                {
                    param_ptr = &(*param_ptr)->next;
                }
                /* Discard duplicates */
                if (!*param_ptr || cmp)
                {
                    struct high_param *param = joe_malloc(sizeof(struct high_param));
                    param->name = zdup(bf);
                    param->next = *param_ptr;
                    *param_ptr = param;
                }
            }
            else
            {
                i_printf_2((char *)joe_gettext(_("%s %d: Missing )\n")), name, line);
                break;
            }
        }
    }

    *ptr = p;
    return params;
}
예제 #15
0
/** Parse member property setter.
 *
 * @param parse		Parser object.
 * @param prop		Property containing this declaration.
 */
static void parse_prop_set(parse_t *parse, stree_prop_t *prop)
{
	cspan_t *cspan;
	stree_block_t *block;
	stree_proc_t *setter;
	bool_t body_expected;

	body_expected = (prop->symbol->outer_csi->cc != csi_interface);

	lskip(parse);
	cspan = lprev_span(parse);

	if (prop->setter != NULL) {
		cspan_print(cspan);
		printf(" Error: Duplicate setter.\n");
		parse_note_error(parse);
		return;
	}

	prop->setter_arg = stree_proc_arg_new();
	prop->setter_arg->name = parse_ident(parse);
	prop->setter_arg->type = prop->type;

	if (lcur_lc(parse) == lc_scolon) {
		/* Body not present */
		lskip(parse);

		block = NULL;

		if (body_expected) {
			cspan_print(prop->name->cspan);
			printf(" Error: Property '");
			symbol_print_fqn(prop->symbol);
			printf("' setter should have "
			    "a body.\n");
			parse_note_error(parse);
		}
	} else {
		/* Body present */
		lmatch(parse, lc_is);
		block = parse_block(parse);
		lmatch(parse, lc_end);

		if (!body_expected) {
			cspan_print(prop->name->cspan);
			printf(" Error: Property '");
			symbol_print_fqn(prop->symbol);
			printf("' setter declaration should "
			    "not have a body.\n");
			parse_note_error(parse);
		}
	}


	/* Create setter procedure */
	setter = stree_proc_new();
	setter->body = block;
	setter->outer_symbol = prop->symbol;

	/* Store setter in property. */
	prop->setter = setter;
}
예제 #16
0
/** Parse member property.
 *
 * @param parse		Parser object.
 * @param outer_csi	CSI containing this declaration or @c NULL if global.
 * @return		New syntax tree node.
 */
static stree_prop_t *parse_prop(parse_t *parse, stree_csi_t *outer_csi)
{
	stree_prop_t *prop;
	stree_symbol_t *symbol;

	stree_ident_t *ident;
	stree_proc_arg_t *arg;

	prop = stree_prop_new();
	list_init(&prop->args);

	symbol = stree_symbol_new(sc_prop);
	symbol->u.prop = prop;
	symbol->outer_csi = outer_csi;
	prop->symbol = symbol;

	lmatch(parse, lc_prop);

	if (lcur_lc(parse) == lc_self) {
		/* Indexed property set */

		/* Use some name that is impossible as identifier. */
		ident = stree_ident_new();
		ident->sid = strtab_get_sid(INDEXER_IDENT);
		prop->name = ident;

		lskip(parse);
		lmatch(parse, lc_lsbr);

		/* Parse formal parameters. */
		while (!parse_is_error(parse)) {
			arg = parse_proc_arg(parse);
			if (stree_arg_has_attr(arg, aac_packed)) {
				prop->varg = arg;
				break;
			} else {
				list_append(&prop->args, arg);
			}

			if (lcur_lc(parse) == lc_rsbr)
				break;

			lmatch(parse, lc_scolon);
		}

		lmatch(parse, lc_rsbr);
	} else {
		/* Named property */
		prop->name = parse_ident(parse);
	}

	lmatch(parse, lc_colon);
	prop->type = parse_texpr(parse);

	/* Parse attributes. */
	parse_symbol_attrs(parse, symbol);

	lmatch(parse, lc_is);

	while (lcur_lc(parse) != lc_end && !parse_is_error(parse)) {
		switch (lcur_lc(parse)) {
		case lc_get:
			parse_prop_get(parse, prop);
			break;
		case lc_set:
			parse_prop_set(parse, prop);
			break;
		default:
			lunexpected_error(parse);
		}
	}

	lmatch(parse, lc_end);

	return prop;
}
예제 #17
0
/*
 * CREATE LDAP TABLE <table name> BASE='base_dn' FILTER='filter' ATTRIBUTES='attributes' SCOPE='scope'
 * DROP LDAP TABLE <table name>
 * ALTER LDAP TABLE <table name>
 * ALTER LDAP TABLE <table name> BASE='base_dn' FILTER='filter' ATTRIBUTES='attributes' SCOPE='scope'
 *
 * Returns: a #ExtraSqlCommand pointer, or %NULL, or NOT_AN_EXTRA_SQL_COMMAND (if not "CREATE LDAP...")
 */
static ExtraSqlCommand *
parse_extra_sql_command (gchar *cmd, const gchar *cmde_name, GError **error)
{
	ExtraSqlCommand *args;
	gchar *ptr, *errptr, *part, *tmp;
	args = g_new0 (ExtraSqlCommand, 1);
	args->other_args = FALSE;
	
	ptr = cmd + strlen (cmde_name);
	
	/* make sure about complete command */
	errptr = ptr;
	if (! (ptr = parse_ident (ptr, &part)))
		return NOT_AN_EXTRA_SQL_COMMAND;
	if (!part || g_ascii_strncasecmp (part, "ldap", 4))
		return NOT_AN_EXTRA_SQL_COMMAND;

	errptr = ptr;
	if (! (ptr = parse_ident (ptr, &part)))
		goto onerror;
	if (!part || g_ascii_strncasecmp (part, "table", 5))
		goto onerror;

	/* table name */
	SKIP_SPACES (ptr);
	errptr = ptr;
	if (! (ptr = parse_ident (ptr, &part)))
		goto onerror;
	tmp = g_strndup (part, ptr-part);
	args->table_name = g_ascii_strdown (tmp, -1);
	g_free (tmp);

	/* key=value arguments */
	while (TRUE) {
		errptr = ptr;
		SKIP_SPACES (ptr);
		if (! (ptr = parse_ident (ptr, &part))) {
			ptr = errptr;
			break;
		}
		if (part) {
			gchar **where = NULL;
			if (!g_ascii_strncasecmp (part, "base", 4))
				where = &(args->base_dn);
			else if (!g_ascii_strncasecmp (part, "filter", 6))
				where = &(args->filter);
			else if (!g_ascii_strncasecmp (part, "attributes", 10))
				where = &(args->attributes);
			else if (!g_ascii_strncasecmp (part, "scope", 5))
				where = NULL;
			else
				goto onerror;
			
			/* = */
			errptr = ptr;
			SKIP_SPACES (ptr);
			if (*ptr != '=')
				goto onerror;
			ptr++;
			
			/* value */
			errptr = ptr;
			SKIP_SPACES (ptr);
			if (! (ptr = parse_string (ptr, &part)))
				goto onerror;
			if (part) {
				if (where)
					*where = g_strdup (part);
				else {
					if (!g_ascii_strcasecmp (part, "base"))
						args->scope = GDA_LDAP_SEARCH_BASE;
					else if (!g_ascii_strcasecmp (part, "onelevel"))
						args->scope = GDA_LDAP_SEARCH_ONELEVEL;
					else if (!g_ascii_strcasecmp (part, "subtree"))
						args->scope = GDA_LDAP_SEARCH_SUBTREE;
					else
						goto onerror;
				}
				args->other_args = TRUE;
			}
			else
				goto onerror;
		}
		else
			break;
	}

	/* end */
	SKIP_SPACES (ptr);
	if (*ptr && (*ptr != ';'))
		goto onerror;
#ifdef GDA_DEBUG_NO
	g_print ("TABLE=>%s, BASE=>%s, FILTER=>%s, ATTRIBUTES=>%s, SCOPE=>%d\n", args->table_name,
		 args->base_dn, args->filter,
		 args->attributes, args->scope);
#endif

	return args;

 onerror:
	SKIP_SPACES (errptr);
	g_set_error (error, GDA_SQL_PARSER_ERROR, GDA_SQL_PARSER_SYNTAX_ERROR,
		     _("near \"%s\": syntax error"), errptr);
	extra_sql_command_free (args);
	return NULL;
}
/*
 * Input:
 *  argN   : The value of argument #N, counting from 1
 *  eltN   : The value of element #N of the containing structure
 *  retval : The return value
 *  N      : The numeric value N
 */
static struct expr_node *
parse_argnum(struct locus *loc, char **str, int *ownp, int zero)
{
	struct expr_node *expr = malloc(sizeof(*expr));
	if (expr == NULL)
		return NULL;

	if (isdigit(CTYPE_CONV(**str))) {
		long l;
		if (parse_int(loc, str, &l) < 0
		    || check_nonnegative(loc, l) < 0
		    || check_int(loc, l) < 0)
			goto fail;

		expr_init_const_word(expr, l, type_get_simple(ARGTYPE_LONG), 0);

		if (zero && wrap_in_zero(&expr) < 0)
			goto fail;

		*ownp = 1;
		return expr;

	} else {
		char *const name = parse_ident(loc, str);
		if (name == NULL) {
		fail_ident:
			free(name);
			goto fail;
		}

		int is_arg = strncmp(name, "arg", 3) == 0;
		if (is_arg || strncmp(name, "elt", 3) == 0) {
			long l;
			char *num = name + 3;
			if (parse_int(loc, &num, &l) < 0
			    || check_int(loc, l) < 0)
				goto fail_ident;

			if (is_arg) {
				if (l == 0)
					expr_init_named(expr, "retval", 0);
				else
					expr_init_argno(expr, l - 1);
			} else {
				struct expr_node *e_up = malloc(sizeof(*e_up));
				struct expr_node *e_ix = malloc(sizeof(*e_ix));
				if (e_up == NULL || e_ix == NULL) {
					free(e_up);
					free(e_ix);
					goto fail_ident;
				}

				expr_init_up(e_up, expr_self(), 0);
				struct arg_type_info *ti
					= type_get_simple(ARGTYPE_LONG);
				expr_init_const_word(e_ix, l - 1, ti, 0);
				expr_init_index(expr, e_up, 1, e_ix, 1);
			}

		} else if (strcmp(name, "retval") == 0) {
			expr_init_named(expr, "retval", 0);

		} else if (strcmp(name, "zero") == 0) {
			struct expr_node *ret
				= parse_zero(loc, str, ownp);
			if (ret == NULL)
				goto fail_ident;
			free(expr);
			free(name);
			return ret;

		} else {
			report_error(loc->filename, loc->line_no,
				     "Unknown length specifier: '%s'", name);
			goto fail_ident;
		}

		if (zero && wrap_in_zero(&expr) < 0)
			goto fail_ident;

		free(name);
		*ownp = 1;
		return expr;
	}

fail:
	free(expr);
	return NULL;
}
예제 #19
0
bool LVCssSelector::parse( const char * &str, lxmlDocBase * doc )
{
    if (!str || !*str)
        return false;
    for (;;)
    {
        skip_spaces( str );
        if ( *str == '*' ) // universal selector
        {
            str++;
            skip_spaces( str );
            _id = 0;
        } 
        else if ( *str == '.' ) // classname follows
        {
            _id = 0;
        }
        else if ( css_is_alpha( *str ) )
        {
            // ident
            char ident[64];
            if (!parse_ident( str, ident ))
                return false;
            _id = doc->getElementNameIndex( lString16(ident).c_str() );
            skip_spaces( str );
        }
        else
        {
            return false;
        }
        if ( *str == ',' || *str == '{' )
            return true;
        // one or more attribute rules
        bool attr_rule = false;
        while ( *str == '[' || *str=='.' || *str=='#' )
        {
            LVCssSelectorRule * rule = parse_attr( str, doc );
            if (!rule)
                return false;
            insertRuleStart( rule ); //insertRuleAfterStart
            //insertRuleAfterStart( rule ); //insertRuleAfterStart

            /*
            if ( _id!=0 ) {
                LVCssSelectorRule * rule = new LVCssSelectorRule(cssrt_parent);
                rule->setId(_id);
                insertRuleStart( rule );
                _id=0;
            }
            */

            skip_spaces( str );
            attr_rule = true;
            //continue;
        }
        // element relation
        if (*str == '>')
        {
            str++;
            LVCssSelectorRule * rule = new LVCssSelectorRule(cssrt_parent);
            rule->setId(_id);
            insertRuleStart( rule );
            _id=0;
            continue;
        }
        else if (*str == '+')
        {
            str++;
            LVCssSelectorRule * rule = new LVCssSelectorRule(cssrt_predecessor);
            rule->setId(_id);
            insertRuleStart( rule );
            _id=0;
            continue;
        }
        else if (css_is_alpha( *str ))
        {
            LVCssSelectorRule * rule = new LVCssSelectorRule(cssrt_ancessor);
            rule->setId(_id);
            insertRuleStart( rule );
            _id=0;
            continue;
        }
        if ( !attr_rule )
            return false;
        else if ( *str == ',' || *str == '{' )
            return true;
    }
}
예제 #20
0
파일: csslex.c 프로젝트: erkyrath/mincss
/* Grab the next token. Returns the tokentype. The token's text is available
   at context->token, length context->tokenlen.
*/
tokentype mincss_next_token(mincss_context *context)
{
    /* Discard all text in the buffer from the previous token. But if
       any characters were pushed back, keep those. */
    if (context->tokenlen) {
        int extra = context->tokenmark - context->tokenlen;
        if (extra > 0) {
            memmove(context->token, context->token+context->tokenlen, extra*sizeof(int32_t));
        }
        context->tokenlen = 0;
        context->tokenmark = extra;
    }

    context->tokendiv = 0;

    int32_t ch = next_char(context);
    if (ch == -1) {
        return tok_EOF;
    }

    /* Simple one-character tokens. */
    switch (ch) {
    case '(':
        return tok_LParen;
    case ')':
        return tok_RParen;
    case '[':
        return tok_LBracket;
    case ']':
        return tok_RBracket;
    case '{':
        return tok_LBrace;
    case '}':
        return tok_RBrace;
    case ':':
        return tok_Colon;
    case ';':
        return tok_Semicolon;

    /* Some cases that are more than one character, but still easy to take care of. */

    case '~': {
        ch = next_char(context);
        if (ch == -1) 
            return tok_Delim;
        if (ch == '=')
            return tok_Includes;
        putback_char(context, 1);
        return tok_Delim;
    }

    case '|': {
        ch = next_char(context);
        if (ch == -1) 
            return tok_Delim;
        if (ch == '=')
            return tok_DashMatch;
        putback_char(context, 1);
        return tok_Delim;
    }

    case '@': {
        int len = parse_ident(context, 0);
        if (len == 0) 
            return tok_Delim;
        return tok_AtKeyword;
    }

    case '#': {
        int len = parse_ident(context, 1);
        if (len == 1) 
            return tok_Delim;
        return tok_Hash;
    }

    /* Not proud of this next one. */
    case '<': {
        ch = next_char(context);
        if (ch == -1) 
            return tok_Delim;
        if (ch == '!') {
            ch = next_char(context);
            if (ch == -1) {
                putback_char(context, 1);
                return tok_Delim;
            }
            if (ch == '-') {
                ch = next_char(context);
                if (ch == -1) {
                    putback_char(context, 2);
                    return tok_Delim;
                }
                if (ch == '-') {
                    return tok_CDO;
                }
                putback_char(context, 3);
                return tok_Delim;
            }
            putback_char(context, 2);
            return tok_Delim;
        }
        putback_char(context, 1);
        return tok_Delim;
    }
    }

    if (IS_WHITESPACE(ch)) {
        while (1) {
            ch = next_char(context);
            if (ch == -1) 
                return tok_Space;
            if (!IS_WHITESPACE(ch)) {
                putback_char(context, 1);
                return tok_Space;
            }
            continue;
        }
    }

    if (ch == '"' || ch == '\'') {
        /* Strings begin with a single or double quote. */
        parse_string(context, ch);
        return tok_String;
    }

    if (IS_NUMBER_START(ch)) {
        /* Digits could begin a number, percentage, or dimension, depending
           on what's after them. */
        putback_char(context, 1);
        int numlen = parse_number(context);
        if (numlen == 0) {
            ch = next_char(context);
            return tok_Delim;
        }
        ch = next_char(context);
        if (ch == -1)
            return tok_Number;
        if (ch == '%')
            return tok_Percentage;
        if (ch == '-' || IS_IDENT_START(ch)) {
            /* ### doesn't check for backslash escapes */
            putback_char(context, 1);
            int numlen = context->tokenlen;
            int len = parse_ident(context, 0);
            if (len > 0) {
                context->tokendiv = numlen;
                return tok_Dimension;
            }
            else {
                return tok_Number;
            }
        }
        putback_char(context, 1);
        return tok_Number;
    }

    if (ch == '-' || IS_IDENT_START(ch)) {
        /* Ordinary identifiers. Note that minus signs always indicate
           identifiers, not numbers. (At least in CSS 2.1.) (Except
           that it might be a CDC --> token.) */

        ch = next_char(context);
        if (ch == -1) {
            /* Do nothing */
        }
        else if (ch == '-') {
            ch = next_char(context);
            if (ch == -1) {
                putback_char(context, 1);
            }
            else if (ch == '>') {
                return tok_CDC;
            }
            else {
                putback_char(context, 2);
            }
        }
        else {
            putback_char(context, 1);
        }

        putback_char(context, 1);
        int len = parse_ident(context, 0);
        if (len == 0) {
            ch = next_char(context);
            return tok_Delim;
        }
        if (len == 3 && match_accepted_chars(context, "url")) {
            int sublen = parse_uri_body(context);
            if (sublen > 0)
                return tok_URI;
        }
        /* If the following character is a left-paren, this is a function. */
        ch = next_char(context);
        if (ch == -1) 
            return tok_Ident;
        if (ch == '(')
            return tok_Function;
        putback_char(context, 1);
        return tok_Ident;
    }

    if (ch == '/') {
        ch = next_char(context);
        if (ch == -1) 
            return tok_Delim;
        if (ch != '*') {
            putback_char(context, 1);
            return tok_Delim;
        }
        int gotstar = 0;
        while (1) {
            ch = next_char(context);
            if (ch == -1) {
                mincss_note_error(context, "Unterminated comment");
                return tok_Comment;
            }
            if (ch == '/' && gotstar)
                return tok_Comment;
            gotstar = (ch == '*');
        }
    }

    if (ch == '\\') {
        /* A backslash which forms a hex escape is the start of an
           identifier. (Even if it's not a normal identifier-start
           character.) A backslashed nonwhite character starts an
           identifer as itself. A backslash before whitespace is
           a delimiter. */
        int len = parse_universal_newline(context);
        if (len) {
            /* Backslashed newline: put back the newline, accept the
               backslash. */
            putback_char(context, len);
            return tok_Delim;
        }
        int32_t val = '?';
        len = parse_escaped_hex(context, &val);
        if (len) {
            /* Backslashed hex: drop the hex string... */
            erase_char(context, len);
            /* Replace the backslash itself with the named character. */
            context->token[context->tokenlen-1] = val;
            /* Parse the rest of the identifier. */
            parse_ident(context, 1);
            /* If the following character is a left-paren, this is a function. */
            ch = next_char(context);
            if (ch == -1) 
                return tok_Ident;
            if (ch == '(')
                return tok_Function;
            putback_char(context, 1);
            return tok_Ident;
        }
        ch = next_char(context);
        if (ch == -1) {
            /* If there is no next character, take the backslash as a
               delimiter. */
            return tok_Delim;
        }
        /* Any other character: take the next char literally
           (substitute it for the backslash). */
        erase_char(context, 1);
        context->token[context->tokenlen-1] = ch;
        /* Parse the rest of the identifier. */
        parse_ident(context, 1);
        /* If the following character is a left-paren, this is a function. */
        ch = next_char(context);
        if (ch == -1) 
            return tok_Ident;
        if (ch == '(')
            return tok_Function;
        putback_char(context, 1);
        return tok_Ident;
    }

    /* Anything not captured above is a one-character Delim token. */
    return tok_Delim;
}
예제 #21
0
/** Parse class, struct or interface declaration.
 *
 * @param parse		Parser object.
 * @param dclass	What to parse: @c lc_class, @c lc_struct or @c lc_csi.
 * @param outer_csi	CSI containing this declaration or @c NULL if global.
 * @return		New syntax tree node.
 */
static stree_csi_t *parse_csi(parse_t *parse, lclass_t dclass,
    stree_csi_t *outer_csi)
{
	stree_csi_t *csi;
	csi_class_t cc;
	stree_csimbr_t *csimbr;
	stree_symbol_t *symbol;
	stree_ident_t *targ_name;
	stree_targ_t *targ;
	stree_texpr_t *pref;

	switch (dclass) {
	case lc_class: cc = csi_class; break;
	case lc_struct: cc = csi_struct; break;
	case lc_interface: cc = csi_interface; break;
	default: assert(b_false);
	}

	lskip(parse);

	csi = stree_csi_new(cc);
	csi->name = parse_ident(parse);

	list_init(&csi->targ);

	while (lcur_lc(parse) == lc_slash) {
		lskip(parse);
		targ_name = parse_ident(parse);

		targ = stree_targ_new();
		targ->name = targ_name;

		list_append(&csi->targ, targ);
	}

	symbol = stree_symbol_new(sc_csi);
	symbol->u.csi = csi;
	symbol->outer_csi = outer_csi;
	csi->symbol = symbol;

#ifdef DEBUG_PARSE_TRACE
	printf("parse_csi: csi=%p, csi->name = %p (%s)\n", csi, csi->name,
	    strtab_get_str(csi->name->sid));
#endif
	if (lcur_lc(parse) == lc_colon) {
		/* Inheritance list */
		lskip(parse);

		while (b_true) {
			pref = parse_texpr(parse);
			if (parse_is_error(parse))
				break;

			list_append(&csi->inherit, pref);
			if (lcur_lc(parse) != lc_plus)
				break;

			lskip(parse);
		}
	}

	lmatch(parse, lc_is);
	list_init(&csi->members);

	/* Parse class, struct or interface members. */
	while (lcur_lc(parse) != lc_end && !parse_is_error(parse)) {
		csimbr = parse_csimbr(parse, csi);
		if (csimbr == NULL)
			continue;

		list_append(&csi->members, csimbr);
	}

	lmatch(parse, lc_end);

	if (outer_csi != NULL) {
		switch (outer_csi->cc) {
		case csi_class:
		case csi_struct:
			break;
		case csi_interface:
			cspan_print(csi->name->cspan);
			printf(" Error: CSI declared inside interface.\n");
			parse_note_error(parse);
			/* XXX Free csi */
			return NULL;
		}
	}

	return csi;
}
static int
parse_typedef(struct protolib *plib, struct locus *loc, char **str)
{
	(*str) += strlen("typedef");
	eat_spaces(str);
	char *name = parse_ident(loc, str);

	/* Look through the typedef list whether we already have a
	 * forward of this type.  If we do, it must be forward
	 * structure.  */
	struct named_type *forward = protolib_lookup_type(plib, name, true);
	if (forward != NULL
	    && (forward->info->type != ARGTYPE_STRUCT
		|| !forward->forward)) {
		report_error(loc->filename, loc->line_no,
			     "Redefinition of typedef '%s'", name);
	err:
		free(name);
		return -1;
	}

	// Skip = sign
	eat_spaces(str);
	if (parse_char(loc, str, '=') < 0)
		goto err;
	eat_spaces(str);

	int fwd = 0;
	int own = 0;
	struct arg_type_info *info
		= parse_lens(plib, loc, str, NULL, 0, &own, &fwd);
	if (info == NULL)
		goto err;

	struct named_type this_nt;
	named_type_init(&this_nt, info, own);
	this_nt.forward = fwd;

	if (forward == NULL) {
		if (protolib_add_named_type(plib, name, 1, &this_nt) < 0) {
			named_type_destroy(&this_nt);
			goto err;
		}
		return 0;
	}

	/* If we are defining a forward, make sure the definition is a
	 * structure as well.  */
	if (this_nt.info->type != ARGTYPE_STRUCT) {
		report_error(loc->filename, loc->line_no,
			     "Definition of forward '%s' must be a structure.",
			     name);
		named_type_destroy(&this_nt);
		goto err;
	}

	/* Now move guts of the actual type over to the forward type.
	 * We can't just move pointers around, because references to
	 * forward must stay intact.  */
	assert(this_nt.own_type);
	type_destroy(forward->info);
	*forward->info = *this_nt.info;
	forward->forward = 0;
	free(this_nt.info);
	free(name);
	return 0;
}
/* Syntax:
 *   enum (keyname[=value],keyname[=value],... )
 *   enum<type> (keyname[=value],keyname[=value],... )
 */
static int
parse_enum(struct protolib *plib, struct locus *loc, char **str,
	   struct arg_type_info **retp, int *ownp)
{
	/* Optional type argument.  */
	eat_spaces(str);
	if (**str == '[') {
		parse_char(loc, str, '[');
		eat_spaces(str);
		*retp = parse_nonpointer_type(plib, loc, str, NULL, 0, ownp, 0);
		if (*retp == NULL)
			return -1;

		if (!type_is_integral((*retp)->type)) {
			report_error(loc->filename, loc->line_no,
				     "integral type required as enum argument");
		fail:
			if (*ownp) {
				/* This also releases associated lens
				 * if any was set so far.  */
				type_destroy(*retp);
				free(*retp);
			}
			return -1;
		}

		eat_spaces(str);
		if (parse_char(loc, str, ']') < 0)
			goto fail;

	} else {
		*retp = type_get_simple(ARGTYPE_INT);
		*ownp = 0;
	}

	/* We'll need to set the lens, so unshare.  */
	if (unshare_type_info(loc, retp, ownp) < 0)
		goto fail;

	eat_spaces(str);
	if (parse_char(loc, str, '(') < 0)
		goto fail;

	struct enum_lens *lens = malloc(sizeof(*lens));
	if (lens == NULL) {
		report_error(loc->filename, loc->line_no,
			     "malloc enum lens: %s", strerror(errno));
		return -1;
	}

	lens_init_enum(lens);
	(*retp)->lens = &lens->super;
	(*retp)->own_lens = 1;

	long last_val = 0;
	while (1) {
		eat_spaces(str);
		if (**str == 0 || **str == ')') {
			parse_char(loc, str, ')');
			return 0;
		}

		/* Field delimiter.  XXX should we support the C
		 * syntax, where the enumeration can end in pending
		 * comma?  */
		if (lens_enum_size(lens) > 0)
			parse_char(loc, str, ',');

		eat_spaces(str);
		char *key = parse_ident(loc, str);
		if (key == NULL) {
		err:
			free(key);
			goto fail;
		}

		if (**str == '=') {
			++*str;
			eat_spaces(str);
			if (parse_int(loc, str, &last_val) < 0)
				goto err;
		}

		struct value *value = malloc(sizeof(*value));
		if (value == NULL)
			goto err;
		value_init_detached(value, NULL, *retp, 0);
		value_set_word(value, last_val);

		if (lens_enum_add(lens, key, 1, value, 1) < 0)
			goto err;

		last_val++;
	}

	return 0;
}
예제 #24
0
파일: epdf.c 프로젝트: clerkma/ptex-ng
int
pdf_copy_clip (FILE *image_file, int pageNo, double x_user, double y_user)
{
  pdf_obj *page_tree, *contents;
  int depth = 0, top = -1;
  const char *clip_path, *end_path;
  char *save_path, *temp;
  pdf_tmatrix M;
  double stack[6];
  pdf_file *pf;
  
  pf = pdf_open(NULL, image_file);
  if (!pf)
    return -1;

  pdf_dev_currentmatrix(&M);
  pdf_invertmatrix(&M);
  M.e += x_user; M.f += y_user;
  page_tree = pdf_get_page_obj (pf, pageNo, NULL, NULL);
  if (!page_tree) {
    pdf_close(pf);
    return -1;
  }

  contents = pdf_get_page_content(page_tree);
  pdf_release_obj(page_tree);
  if (!contents) {
    pdf_close(pf);
    return -1;
  }

  pdf_doc_add_page_content(" ", 1);

  save_path = malloc(pdf_stream_length(contents) + 1);
  strncpy(save_path, (const char *) pdf_stream_dataptr(contents),  pdf_stream_length(contents));
  clip_path = save_path;
  end_path = clip_path + pdf_stream_length(contents);
  depth = 0;

  for (; clip_path < end_path; clip_path++) {
    int color_dimen = 0;	/* silence uninitialized warning */
    char *token;
    skip_white(&clip_path, end_path);
    if (clip_path == end_path)
      break;
    if (depth > 1) {
      if (*clip_path == 'q')
        depth++;
      if (*clip_path == 'Q')
	depth--;
      parse_ident(&clip_path, end_path);
      continue;
    } else if (*clip_path == '-'
	    || *clip_path == '+'
	    || *clip_path == '.'
	    || isdigit((unsigned char)*clip_path)) {
      stack[++top] = strtod(clip_path, &temp);
      clip_path = temp;
    } else if (*clip_path == '[') {
      /* Ignore, but put a dummy value on the stack (in case of d operator) */
      parse_pdf_array(&clip_path, end_path, pf);
      stack[++top] = 0;
    } else if (*clip_path == '/') {
      if  (strncmp("/DeviceGray",	clip_path, 11) == 0
	|| strncmp("/Indexed",		clip_path, 8)  == 0
	|| strncmp("/CalGray",		clip_path, 8)  == 0) {
	color_dimen = 1;
	continue;
      }
      else if  (strncmp("/DeviceRGB",	clip_path, 10) == 0
	|| strncmp("/CalRGB",		clip_path, 7)  == 0
	|| strncmp("/Lab",		clip_path, 4)  == 0) {
	color_dimen = 3;
	continue;
      }
      else if  (strncmp("/DeviceCMYK",	clip_path, 11) == 0) {
	color_dimen = 4;
	continue;
      }
      else {
        clip_path++;
        parse_ident(&clip_path, end_path);
	skip_white(&clip_path, end_path);
	token = parse_ident(&clip_path, end_path);
        if (strcmp(token, "gs") == 0) {
	  continue;
	}
        return -1;
      }
    } else {
      int j;
      pdf_tmatrix T;
      pdf_coord  p0, p1, p2, p3;

      token = parse_ident(&clip_path, end_path);
      for (j = 0; j < sizeof(pdf_operators) / sizeof(pdf_operators[0]); j++)
        if (strcmp(token, pdf_operators[j].token) == 0)
	  break;
      if (j == sizeof(pdf_operators) / sizeof(pdf_operators[0])) {
        return -1;
      }
      switch (pdf_operators[j].opcode) {
	case  0:
	case -1:
	case -2:
	case -3:
	case -4:
	  /* Just pop the stack and do nothing. */
	  top += pdf_operators[j].opcode;
	  if (top < -1)
	    return -1;
	  break;
	case OP_SETCOLOR:
	  top -= color_dimen;
	  if (top < -1)
	    return -1;
	  break;
	case OP_CLOSEandCLIP:
	  pdf_dev_closepath();
	case OP_CLIP:
#if 0
	  pdf_dev_clip();
#else
	  pdf_dev_flushpath('W', PDF_FILL_RULE_NONZERO);
#endif
	  break;
	case OP_CONCATMATRIX:
	  if (top < 5)
	    return -1;
	  T.f = stack[top--];
	  T.e = stack[top--];
	  T.d = stack[top--];
	  T.c = stack[top--];
	  T.b = stack[top--];
	  T.a = stack[top--];
	  pdf_concatmatrix(&M, &T);
	  break;
	case OP_SETCOLORSPACE:
	  /* Do nothing. */
	  break;
	case OP_RECTANGLE:
	  if (top < 3)
	    return -1;
	  p1.y = stack[top--];
	  p1.x = stack[top--];
	  p0.y = stack[top--];
	  p0.x = stack[top--];
	  if (M.b == 0 && M.c == 0) {
	    pdf_tmatrix M0;
	    M0.a = M.a; M0.b = M.b; M0.c = M.c; M0.d = M.d;
	    M0.e = 0; M0.f = 0;
	    pdf_dev_transform(&p0, &M);
	    pdf_dev_transform(&p1, &M0);
	    pdf_dev_rectadd(p0.x, p0.y, p1.x, p1.y);
	  } else {
	    p2.x = p0.x + p1.x; p2.y = p0.y + p1.y;
	    p3.x = p0.x; p3.y = p0.y + p1.y;
	    p1.x += p0.x; p1.y = p0.y;
	    pdf_dev_transform(&p0, &M);
	    pdf_dev_transform(&p1, &M);
	    pdf_dev_transform(&p2, &M);
	    pdf_dev_transform(&p3, &M);
	    pdf_dev_moveto(p0.x, p0.y);
	    pdf_dev_lineto(p1.x, p1.y);
	    pdf_dev_lineto(p2.x, p2.y);
	    pdf_dev_lineto(p3.x, p3.y);
	    pdf_dev_closepath();
	  }
	  break;
	case OP_CURVETO:
	  if (top < 5)
	    return -1;
	  p0.y = stack[top--];
	  p0.x = stack[top--];
	  pdf_dev_transform(&p0, &M);
	  p1.y = stack[top--];
	  p1.x = stack[top--];
	  pdf_dev_transform(&p1, &M);
	  p2.y = stack[top--];
	  p2.x = stack[top--];
	  pdf_dev_transform(&p2, &M);
	  pdf_dev_curveto(p2.x, p2.y, p1.x, p1.y, p0.x, p0.y);
	  break;
	case OP_CLOSEPATH:
	  pdf_dev_closepath();
	  break;
	case OP_LINETO:
	  if (top < 1)
	    return -1;
	  p0.y = stack[top--];
	  p0.x = stack[top--];
	  pdf_dev_transform(&p0, &M);
	  pdf_dev_lineto(p0.x, p0.y);
	  break;
	case OP_MOVETO:
	  if (top < 1)
	    return -1;
	  p0.y = stack[top--];
	  p0.x = stack[top--];
	  pdf_dev_transform(&p0, &M);
	  pdf_dev_moveto(p0.x, p0.y);
	  break;
	case OP_NOOP:
	  pdf_doc_add_page_content(" n", 2);
	  break;
	case OP_GSAVE:
	  depth++;
	  break;
	case OP_GRESTORE:
	  depth--;
	  break;
	case OP_CURVETO1:
	  if (top < 3)
	    return -1;
	  p0.y = stack[top--];
	  p0.x = stack[top--];
	  pdf_dev_transform(&p0, &M);
	  p1.y = stack[top--];
	  p1.x = stack[top--];
	  pdf_dev_transform(&p1, &M);
	  pdf_dev_vcurveto(p1.x, p1.y, p0.x, p0.y);
	  break;
	case OP_CURVETO2:
	  if (top < 3)
	    return -1;
	  p0.y = stack[top--];
	  p0.x = stack[top--];
	  pdf_dev_transform(&p0, &M);
	  p1.y = stack[top--];
	  p1.x = stack[top--];
	  pdf_dev_transform(&p1, &M);
	  pdf_dev_ycurveto(p1.x, p1.y, p0.x, p0.y);
	  break;
	default:
	  return -1;
      }
    }
  }
  free(save_path);

  pdf_release_obj(contents);
  pdf_close(pf);

  return 0;
}
예제 #25
0
LVCssSelectorRule * parse_attr( const char * &str, lxmlDocBase * doc )
{
    char attrname[512];
    char attrvalue[512];
    LVCssSelectorRuleType st = cssrt_universal;
    if (*str=='.') {
        // E.class
        str++;
        skip_spaces( str );
        if (!parse_ident( str, attrvalue ))
            return NULL;
        skip_spaces( str );
        LVCssSelectorRule * rule = new LVCssSelectorRule(cssrt_class);
        lString16 s( attrvalue );
        s.lowercase();
        rule->setAttr(attr_class, s);
        return rule;
    } else if ( *str=='#' ) {
        // E#id
        str++;
        skip_spaces( str );
        if (!parse_ident( str, attrvalue ))
            return NULL;
        skip_spaces( str );
        LVCssSelectorRule * rule = new LVCssSelectorRule(cssrt_id);
        lString16 s( attrvalue );
        rule->setAttr(attr_id, s);
        return rule;
    } else if (*str != '[')
        return NULL;
    str++;
    skip_spaces( str );
    if (!parse_ident( str, attrname ))
        return NULL;
    skip_spaces( str );
    attrvalue[0] = 0;
    if (*str==']')
    {
        st = cssrt_attrset;
        str++;
    }
    else if (*str=='=')
    {
        str++;
        if (!parse_attr_value( str, attrvalue))
            return NULL;
        st = cssrt_attreq;
    }
    else if (*str=='~' && str[1]=='=')
    {
        str+=2;
        if (!parse_attr_value( str, attrvalue))
            return NULL;
        st = cssrt_attrhas;
    }
    else if (*str=='|' && str[1]=='=')
    {
        str+=2;
        if (!parse_attr_value( str, attrvalue))
            return NULL;
        st = cssrt_attrstarts;
    }
    else
    {
        return NULL;
    }
    LVCssSelectorRule * rule = new LVCssSelectorRule(st);
    lString16 s( attrvalue );
    lUInt16 id = doc->getAttrNameIndex( lString16(attrname).c_str() );
    rule->setAttr(id, s);
    return rule;
}