Пример #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
/** 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;
}
Пример #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
/** Parse member property getter.
 *
 * @param parse		Parser object.
 * @param prop		Property containing this declaration.
 */
static void parse_prop_get(parse_t *parse, stree_prop_t *prop)
{
	cspan_t *cspan;
	stree_block_t *block;
	stree_proc_t *getter;
	bool_t body_expected;

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

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

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

	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("' getter 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("' getter declaration should "
			    "not have a body.\n");
			parse_note_error(parse);

			/* XXX Free block */
			block = NULL;
		}
	}

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

	/* Store getter in property. */
	prop->getter = getter;
}
Пример #5
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;
}
Пример #6
0
/** Parse @c break statement.
 *
 * @param parse		Parser object.
 * @return		New syntax tree node.
 */
static stree_break_t *parse_break(parse_t *parse)
{
	stree_break_t *break_s;

#ifdef DEBUG_PARSE_TRACE
	printf("Parse 'break' statement.\n");
#endif
	break_s = stree_break_new();

	lmatch(parse, lc_break);
	lmatch(parse, lc_scolon);

	return break_s;
}
Пример #7
0
/** Parse @c raise statement.
 *
 * @param parse		Parser object.
 */
static stree_raise_t *parse_raise(parse_t *parse)
{
	stree_raise_t *raise_s;

#ifdef DEBUG_PARSE_TRACE
	printf("Parse 'raise' statement.\n");
#endif
	raise_s = stree_raise_new();
	lmatch(parse, lc_raise);
	raise_s->expr = parse_expr(parse);
	lmatch(parse, lc_scolon);

	return raise_s;
}
Пример #8
0
/** Parse @c switch statement.
 *
 * @param parse		Parser object.
 * @return		New syntax tree node.
 */
static stree_switch_t *parse_switch(parse_t *parse)
{
	stree_switch_t *switch_s;
	stree_when_t *when_c;
	stree_expr_t *expr;

#ifdef DEBUG_PARSE_TRACE
	printf("Parse 'switch' statement.\n");
#endif
	lmatch(parse, lc_switch);

	switch_s = stree_switch_new();
	list_init(&switch_s->when_clauses);

	switch_s->expr = parse_expr(parse);
	lmatch(parse, lc_is);

	/* Parse @c when clauses. */
	while (lcur_lc(parse) == lc_when) {
		lskip(parse);
		when_c = stree_when_new();
		list_init(&when_c->exprs);
		while (b_true) {
			expr = parse_expr(parse);
			list_append(&when_c->exprs, expr);
			if (lcur_lc(parse) != lc_comma)
				break;
			lskip(parse);
		}

		lmatch(parse, lc_do);
		when_c->block = parse_block(parse);

		list_append(&switch_s->when_clauses, when_c);
	}

	/* Parse @c else clause. */
	if (lcur_lc(parse) == lc_else) {
		lskip(parse);
		lmatch(parse, lc_do);
		switch_s->else_block = parse_block(parse);
	} else {
		switch_s->else_block = NULL;
	}

	lmatch(parse, lc_end);
	return switch_s;
}
Пример #9
0
/** Parse @c while statement.
 *
 * @param parse		Parser object.
 */
static stree_while_t *parse_while(parse_t *parse)
{
	stree_while_t *while_s;

#ifdef DEBUG_PARSE_TRACE
	printf("Parse 'while' statement.\n");
#endif
	while_s = stree_while_new();

	lmatch(parse, lc_while);
	while_s->cond = parse_expr(parse);
	lmatch(parse, lc_do);
	while_s->body = parse_block(parse);
	lmatch(parse, lc_end);

	return while_s;
}
Пример #10
0
/** Parse function signature.
 *
 * @param parse		Parser object.
 * @return		New syntax tree node.
 */
static stree_fun_sig_t *parse_fun_sig(parse_t *parse)
{
	stree_fun_sig_t *sig;
	stree_proc_arg_t *arg;

	sig = stree_fun_sig_new();

	lmatch(parse, lc_lparen);

#ifdef DEBUG_PARSE_TRACE
	printf("Parsing function signature.\n");
#endif

	list_init(&sig->args);

	if (lcur_lc(parse) != lc_rparen) {

		/* Parse formal parameters. */
		while (!parse_is_error(parse)) {
			arg = parse_proc_arg(parse);

			if (stree_arg_has_attr(arg, aac_packed)) {
				sig->varg = arg;
				break;
			} else {
				list_append(&sig->args, arg);
			}

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

			lmatch(parse, lc_scolon);
		}
	}

	lmatch(parse, lc_rparen);

	if (lcur_lc(parse) == lc_colon) {
	    	lskip(parse);
		sig->rtype = parse_texpr(parse);
	} else {
		sig->rtype = NULL;
	}

	return sig;
}
Пример #11
0
/** Parse @c return statement.
 *
 * @param parse		Parser object.
 * @return		New syntax tree node.
 */
static stree_return_t *parse_return(parse_t *parse)
{
	stree_return_t *return_s;

#ifdef DEBUG_PARSE_TRACE
	printf("Parse 'return' statement.\n");
#endif
	return_s = stree_return_new();

	lmatch(parse, lc_return);

	if (lcur_lc(parse) != lc_scolon)
		return_s->expr = parse_expr(parse);

	lmatch(parse, lc_scolon);

	return return_s;
}
Пример #12
0
/*
** Set a group's rotate setting.
*/
int group_rotate(const char *argv[])
	{
	const char *group = argv[0];
	int newstate;

	if( ! am_administrator() )
		return EXIT_DENIED;

	if(! group || ! argv[1] || ((newstate=gu_torf(argv[1]))==ANSWER_UNKNOWN) )
		{
		fputs(_("You must supply the name of a group and \"true\" or \"false\".\n"), errors);
		return EXIT_SYNTAX;
		}

	/* make sure the group exists */
	if(grpopen(group, TRUE, FALSE))
		{
		fprintf(errors, _("The group \"%s\" does not exist.\n"),group);
		return EXIT_BADDEST;
		}

	/* Modify the group's configuration file. */
	while(confread())
		{
		if(lmatch(confline, "Rotate:"))
			break;
		else
			conf_printf("%s\n", confline);
		}

	conf_printf("Rotate: %s\n", newstate ? "True" : "False");

	while(confread())							/* copy rest of file, */
		{
		if(lmatch(confline, "Rotate:"))			/* discard */
			continue;
		else									/* copy */
			conf_printf("%s\n", confline);
		}
	confclose();

	reread_group(group);						/* pprd must know the rotate setting */
	return EXIT_OK;
	} /* end of group_rotate() */
Пример #13
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;
}
Пример #14
0
/** Parse @c if statement.
 *
 * @param parse		Parser object.
 * @return		New syntax tree node.
 */
static stree_if_t *parse_if(parse_t *parse)
{
	stree_if_t *if_s;
	stree_if_clause_t *if_c;

#ifdef DEBUG_PARSE_TRACE
	printf("Parse 'if' statement.\n");
#endif
	if_s = stree_if_new();
	list_init(&if_s->if_clauses);

	/* Parse @c if clause. */
	lmatch(parse, lc_if);

	if_c = stree_if_clause_new();
	if_c->cond = parse_expr(parse);
	lmatch(parse, lc_then);
	if_c->block = parse_block(parse);

	list_append(&if_s->if_clauses, if_c);

	/* Parse @c elif clauses. */
	while (lcur_lc(parse) == lc_elif) {
		lskip(parse);
		if_c = stree_if_clause_new();
		if_c->cond = parse_expr(parse);
		lmatch(parse, lc_then);
		if_c->block = parse_block(parse);

		list_append(&if_s->if_clauses, if_c);
	}

	/* Parse @c else clause. */
	if (lcur_lc(parse) == lc_else) {
		lskip(parse);
		if_s->else_block = parse_block(parse);
	} else {
		if_s->else_block = NULL;
	}

	lmatch(parse, lc_end);
	return if_s;
}
Пример #15
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;
}
Пример #16
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;
}
Пример #17
0
/* Parse expression statement.
 *
 * @param parse		Parser object.
 * @return		New syntax tree node.
 */
static stree_exps_t *parse_exps(parse_t *parse)
{
	stree_expr_t *expr;
	stree_exps_t *exps;

#ifdef DEBUG_PARSE_TRACE
	printf("Parse expression statement.\n");
#endif
	expr = parse_expr(parse);
	lmatch(parse, lc_scolon);

	exps = stree_exps_new();
	exps->expr = expr;

	return exps;
}
Пример #18
0
/*
** Set the DefFiltOpts: line for a group.
*/
int group_deffiltopts_internal(const char *group)
	{
	if(grpopen(group, TRUE, FALSE))
		{
		fprintf(errors, "The group \"%s\" does not exist.\n", group);
		return EXIT_BADDEST;
		}

	{
	void *qobj = NULL;
	const char *p;
	gu_Try {
		qobj = queueinfo_new(QUEUEINFO_GROUP, group);
		queueinfo_set_warnings_file(qobj, errors);
		queueinfo_set_debug_level(qobj, debug_level);
			
		/* Modify the group's configuration file. */
		while(confread())
			{
			if(lmatch(confline, "DefFiltOpts:"))
				continue;

			if((p = lmatchp(confline, "Printer:")))
				queueinfo_add_printer(qobj, p);
	
			conf_printf("%s\n", confline);
			}
	
		if((p = queueinfo_computedDefaultFilterOptions(qobj)))
			conf_printf("DefFiltOpts: %s\n", p);

		confclose();
		}
	gu_Final {
		if(qobj)
			queueinfo_free(qobj);
		}
	gu_Catch {
		confabort();
		fprintf(errors, "%s: %s\n", myname, gu_exception);
		return exception_to_exitcode(gu_exception_code);
		}
	}

	return EXIT_OK;
	} /* end of group_deffiltopts_internal() */
Пример #19
0
/* Parse @c with-except-finally statement.
 *
 * @param parse		Parser object.
 * @return		New syntax tree node.
 */
static stree_wef_t *parse_wef(parse_t *parse)
{
	stree_wef_t *wef_s;
	stree_except_t *except_c;

#ifdef DEBUG_PARSE_TRACE
	printf("Parse WEF statement.\n");
#endif
	wef_s = stree_wef_new();
	list_init(&wef_s->except_clauses);

	if (lcur_lc(parse) == lc_with) {
		lmatch(parse, lc_with);
		lmatch(parse, lc_ident);
		lmatch(parse, lc_colon);
		(void) parse_texpr(parse);
		lmatch(parse, lc_assign);
		(void) parse_expr(parse);
	}

	lmatch(parse, lc_do);
	wef_s->with_block = parse_block(parse);

	while (lcur_lc(parse) == lc_except && !parse_is_error(parse)) {
		except_c = parse_except(parse);
		list_append(&wef_s->except_clauses, except_c);
	}

	if (lcur_lc(parse) == lc_finally) {
		lmatch(parse, lc_finally);
		lmatch(parse, lc_do);
		wef_s->finally_block = parse_block(parse);
	} else {
		wef_s->finally_block = NULL;
	}

	lmatch(parse, lc_end);

	return wef_s;
}
Пример #20
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;
}
Пример #21
0
/** Parse @c for statement.
 *
 * @param parse		Parser object.
 * @return		New syntax tree node.
 */
static stree_for_t *parse_for(parse_t *parse)
{
	stree_for_t *for_s;

#ifdef DEBUG_PARSE_TRACE
	printf("Parse 'for' statement.\n");
#endif
	for_s = stree_for_new();

	lmatch(parse, lc_for);
	lmatch(parse, lc_ident);
	lmatch(parse, lc_colon);
	(void) parse_texpr(parse);
	lmatch(parse, lc_in);
	(void) parse_expr(parse);
	lmatch(parse, lc_do);
	for_s->body = parse_block(parse);
	lmatch(parse, lc_end);

	return for_s;
}
Пример #22
0
/*
** Remove a member from a group.  This is a separate function because
** it is called from ppad_printer.c when a printer is deleted and
** it is the member of a group.
**
** sucess:		EXIT_OK
** bad group:	EXIT_BADDEST
** bad member:	EXIT_NOTFOUND
*/
int group_remove_internal(const char *group, const char *member)
	{
	char *ptr;
	int found = FALSE;
	void *qobj = NULL;

	if(grpopen(group, TRUE, FALSE))
		return EXIT_BADDEST;

	gu_Try
		{
		qobj = queueinfo_new(QUEUEINFO_GROUP, group);
		queueinfo_set_warnings_file(qobj, errors);
		queueinfo_set_debug_level(qobj, debug_level);

		/*
		** Copy the configuration file.
		*/
		while(confread())
			{
			if(lmatch(confline, "DefFiltOpts:"))		/* delete old lines */
				continue;
	
			if(lmatch(confline, "Printer:"))			/* if member name, */
				{
				ptr = &confline[8];
				ptr += strspn(ptr, " \t");
	
				if(strcmp(ptr,member)==0)				/* If it is the one we */
					{									/* are deleting, */
					found=TRUE;							/* set a flag */
					continue;							/* and don't copy. */
					}
	
				queueinfo_add_printer(qobj, ptr);		/* Otherwise, add its PPD file, */
				}
	
			conf_printf("%s\n",confline);
			}

		/* Emmit the new "DefFiltOpts:" line. */
		{
		const char *cp = queueinfo_computedDefaultFilterOptions(qobj);
		if(cp)
			conf_printf("DefFiltOpts: %s\n", cp);
		}

		confclose();
		}
	gu_Final
		{
		if(qobj)
			queueinfo_free(qobj);
		}
	gu_Catch
		{
		confabort();
		fprintf(errors, "%s: %s\n", myname, gu_exception);
		return exception_to_exitcode(gu_exception_code);
		}

	if(found)
		{
		reread_group(group);
		return EXIT_OK;
		}
	else
		{
		return EXIT_NOTFOUND;
		}
	} /* end of _group_remove() */
Пример #23
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;
}
Пример #24
0
/*
** Show a groups members, its rotate setting, and its comment.
*/
int group_show(const char *argv[])
	{
	const char *function = "group_show";
	const char *group = argv[0];		/* The name of the group to show is the argument. */

	int x;
	char *ptr;

	int rotate = TRUE;					/* Is rotate set for this group? */
	char *comment = (char*)NULL;		/* Group comment. */
	int member_count = 0;				/* Keep count of members. */
	char *members[MAX_GROUPSIZE];		/* The names of the members. */
	char *deffiltopts = (char*)NULL;	/* The default filter options string. */
	char *switchset = (char*)NULL;		/* The compressed switchset string. */
	char *passthru = (char*)NULL;
	char *acls = (char*)NULL;
	#define MAX_ADDONS 32
	char *addon[MAX_ADDONS];
	int addon_count = 0;

	if(! group)
		{
		fputs(_("You must supply the name of a group to show.\n"), errors);
		return EXIT_SYNTAX;
		}

	if(grpopen(group, FALSE, FALSE))	/* Open the configuration file. */
		{
		fprintf(errors, _("The group \"%s\" does not exist.\n"), group);
		return EXIT_BADDEST;
		}

	while(confread())			/* Read all the lines in the config file. */
		{
		if(lmatch(confline, "Rotate:"))
			{
			rotate = gu_torf(&confline[7]);
			continue;
			}
		if(gu_sscanf(confline, "Comment: %A", &ptr) == 1)
			{
			if(comment) gu_free(comment);
			comment = ptr;
			continue;
			}
		if(gu_sscanf(confline, "Printer: %S", &ptr) == 1)
			{
			if(member_count < MAX_GROUPSIZE)
				{
				members[member_count++] = ptr;
				}
			else
				{
				fprintf(errors, "%s(): too many members: %s\n", function, ptr);
				gu_free(ptr);
				}
			continue;
			}
		if(gu_sscanf(confline, "Switchset: %Z", &ptr) == 1)
			{
			if(switchset) gu_free(switchset);
			switchset = ptr;
			continue;
			}
		if(gu_sscanf(confline, "DefFiltOpts: %Z", &ptr) == 1)
			{
			if(deffiltopts) gu_free(deffiltopts);
			deffiltopts = ptr;
			continue;
			}
		if(gu_sscanf(confline, "PassThru: %Z", &ptr) == 1)
			{
			if(passthru) gu_free(passthru);
			passthru = ptr;
			continue;
			}
		if(gu_sscanf(confline, "ACLs: %Z", &ptr) == 1)
			{
			if(acls) gu_free(acls);
			acls = ptr;
			continue;
			}
		if(confline[0] >= 'a' && confline[0] <= 'z')	/* if in addon name space */
			{
			if(addon_count >= MAX_ADDONS)
				{
				fprintf(errors, "%s(): addon[] overflow\n", function);
				}
			else
				{
				addon[addon_count++] = gu_strdup(confline);
				}
			continue;
			}


		} /* end of line reading while() loop */

	confclose();		/* We are done with the configuration file. */

	if(!machine_readable)
		{
		printf(_("Group name: %s\n"), group);

		printf(_("Comment: %s\n"), comment ? comment : "");

		PUTS(_("Members:"));
		for(x=0;x<member_count;x++)		/* Show what printers are members. */
			{
			if(x==0)
				printf(" %s", members[x]);
			else
				printf(", %s", members[x]);
			}
		putchar('\n');					/* End group members line. */

		printf(_("Rotate: %s\n"), rotate ? _("True") : _("False"));

		{
		const char *s = _("Default Filter Options: ");
		PUTS(s);
		if(deffiltopts)
			print_wrapped(deffiltopts, strlen(s));
		putchar('\n');
		}

		PUTS(_("Switchset: "));
		if(switchset)
			print_switchset(switchset);
		putchar('\n');

		/* This rare parameter is shown only when it has a value. */
		if(passthru)
			printf(_("PassThru types: %s\n"), passthru);

		/* Only displayed if set. */
		if(acls)
			printf(_("ACLs: %s\n"), acls);

		/* Print the assembed addon settings. */
		if(addon_count > 0)
			{
			int x;
			PUTS(_("Addon:"));
			for(x = 0; x < addon_count; x++)
				{
				printf("\t%s\n", addon[x]);
				gu_free(addon[x]);
				}
			}

		}
	else
		{
		printf("name\t%s\n", group);
		printf("comment\t%s\n", comment ? comment : "");
		PUTS("members\t");
		for(x=0; x < member_count; x++)
			printf("%s%s", x > 0 ? " " : "", members[x]);
		PUTS("\n");
		printf("rotate\t%s\n", rotate ? "yes" : "no");
		printf("deffiltopts\t%s\n", deffiltopts ? deffiltopts : "");
		PUTS("switchset\t"); if(switchset) print_switchset(switchset); putchar('\n');
		printf("passthru\t%s\n", passthru ? passthru : "");
		printf("acls\t%s\n", acls ? acls : "");

		/* Addon lines */
		if(addon_count > 0)
			{
			int x;
			char *p;
			for(x = 0; x < addon_count; x++)
				{
				if((p = strchr(addon[x], ':')))
					{
					*p = '\0';
					p++;
					p += strspn(p, " \t");
					printf("addon %s\t%s\n", addon[x], p);
					}
				else
					{
					printf("addon\t%s\n", addon[x]);
					}
				gu_free(addon[x]);
				}
			}

		}

	if(comment)
		gu_free(comment);
	for(x=0;x<member_count;x++)
		gu_free(members[x]);
	if(deffiltopts)
		gu_free(deffiltopts);
	if(switchset)
		gu_free(switchset);
	if(passthru)
		gu_free(passthru);
	if(acls)
		gu_free(acls);

	return EXIT_OK;
	} /* end of group_show() */
Пример #25
0
extern bool walk(Node *n, bool parent) {
top:	sigchk();
	if (n == NULL) {
		if (!parent)
			exit(0);
		set(TRUE);
		return TRUE;
	}
	switch (n->type) {
	case nArgs: case nBackq: case nConcat: case nCount:
	case nFlat: case nLappend: case nRedir: case nVar:
	case nVarsub: case nWord:
		exec(glob(glom(n)), parent);	/* simple command */
		break;
	case nBody:
		walk(n->u[0].p, TRUE);
		WALK(n->u[1].p, parent);
		/* WALK doesn't fall through */
	case nNowait: {
		int pid;
		if ((pid = rc_fork()) == 0) {
#if defined(RC_JOB) && defined(SIGTTOU) && defined(SIGTTIN) && defined(SIGTSTP)
			setsigdefaults(FALSE);
			rc_signal(SIGTTOU, SIG_IGN);	/* Berkeleyized version: put it in a new pgroup. */
			rc_signal(SIGTTIN, SIG_IGN);
			rc_signal(SIGTSTP, SIG_IGN);
			setpgid(0, getpid());
#else
			setsigdefaults(TRUE);		/* ignore SIGINT, SIGQUIT, SIGTERM */
#endif
			mvfd(rc_open("/dev/null", rFrom), 0);
			walk(n->u[0].p, FALSE);
			exit(getstatus());
		}
		if (interactive)
			fprint(2, "%d\n", pid);
		varassign("apid", word(nprint("%d", pid), NULL), FALSE);
		redirq = NULL; /* kill pre-redir queue */
		break;
	}
	case nAndalso: {
		bool oldcond = cond;
		cond = TRUE;
		if (walk(n->u[0].p, TRUE)) {
			cond = oldcond;
			WALK(n->u[1].p, parent);
		} else
			cond = oldcond;
		break;
	}
	case nOrelse: {
		bool oldcond = cond;
		cond = TRUE;
		if (!walk(n->u[0].p, TRUE)) {
			cond = oldcond;
			WALK(n->u[1].p, parent);
		} else
			cond = oldcond;
		break;
	}
	case nBang:
		set(!walk(n->u[0].p, TRUE));
		break;
	case nIf: {
		bool oldcond = cond;
		Node *true_cmd = n->u[1].p, *false_cmd = NULL;
		if (true_cmd != NULL && true_cmd->type == nElse) {
			false_cmd = true_cmd->u[1].p;
			true_cmd = true_cmd->u[0].p;
		}
		cond = TRUE;
		if (!walk(n->u[0].p, TRUE))
			true_cmd = false_cmd; /* run the else clause */
		cond = oldcond;
		WALK(true_cmd, parent);
	}
	case nWhile: {
		Jbwrap j;
		Edata jbreak;
		Estack e1, e2;
		bool testtrue, oldcond = cond;
		cond = TRUE;
		if (!walk(n->u[0].p, TRUE)) { /* prevent spurious breaks inside test */
			cond = oldcond;
			break;
		}
		if (sigsetjmp(j.j, 1))
			break;
		jbreak.jb = &j;
		except(eBreak, jbreak, &e1);
		do {
			Edata block;
			block.b = newblock();
			cond = oldcond;
			except(eArena, block, &e2);
			walk(n->u[1].p, TRUE);
			testtrue = walk(n->u[0].p, TRUE);
			unexcept(); /* eArena */
			cond = TRUE;
		} while (testtrue);
		cond = oldcond;
		unexcept(); /* eBreak */
		break;
	}
	case nForin: {
		List *l, *var = glom(n->u[0].p);
		Jbwrap j;
		Estack e1, e2;
		Edata jbreak;
		if (sigsetjmp(j.j, 1))
			break;
		jbreak.jb = &j;
		except(eBreak, jbreak, &e1);
		for (l = listcpy(glob(glom(n->u[1].p)), nalloc); l != NULL; l = l->n) {
			Edata block;
			assign(var, word(l->w, NULL), FALSE);
			block.b = newblock();
			except(eArena, block, &e2);
			walk(n->u[2].p, TRUE);
			unexcept(); /* eArena */
		}
		unexcept(); /* eBreak */
		break;
	}
	case nSubshell:
		if (dofork(TRUE)) {
			setsigdefaults(FALSE);
			walk(n->u[0].p, FALSE);
			rc_exit(getstatus());
		}
		break;
	case nAssign:
		if (n->u[0].p == NULL)
			rc_error("null variable name");
		assign(glom(n->u[0].p), glob(glom(n->u[1].p)), FALSE);
		set(TRUE);
		break;
	case nPipe:
		dopipe(n);
		break;
	case nNewfn: {
		List *l = glom(n->u[0].p);
		if (l == NULL)
			rc_error("null function name");
		while (l != NULL) {
			if (dashex)
				prettyprint_fn(2, l->w, n->u[1].p);
			fnassign(l->w, n->u[1].p);
			l = l->n;
		}
		set(TRUE);
		break;
	}
	case nRmfn: {
		List *l = glom(n->u[0].p);
		while (l != NULL) {
			if (dashex)
				fprint(2, "fn %S\n", l->w);
			fnrm(l->w);
			l = l->n;
		}
		set(TRUE);
		break;
	}
	case nDup:
		redirq = NULL;
		break; /* Null command */
	case nMatch: {
		List *a = glob(glom(n->u[0].p)), *b = glom(n->u[1].p);
		if (dashex)
			fprint(2, (a != NULL && a->n != NULL) ? "~ (%L) %L\n" : "~ %L %L\n", a, " ", b, " ");
		set(lmatch(a, b));
		break;
	}
	case nSwitch: {
		List *v = glom(n->u[0].p);
		while (1) {
			do {
				n = n->u[1].p;
				if (n == NULL)
					return istrue();
			} while (n->u[0].p == NULL || n->u[0].p->type != nCase);
			if (lmatch(v, glom(n->u[0].p->u[0].p))) {
				for (n = n->u[1].p; n != NULL && (n->u[0].p == NULL || n->u[0].p->type != nCase); n = n->u[1].p)
					walk(n->u[0].p, TRUE);
				break;
			}
		}
		break;
	}
	case nPre: {
		List *v;
		if (n->u[0].p->type == nRedir || n->u[0].p->type == nDup) {
			if (redirq == NULL && !dofork(parent)) /* subshell on first preredir */
				break;
			setsigdefaults(FALSE);
			qredir(n->u[0].p);
			if (!haspreredir(n->u[1].p))
				doredirs(); /* no more preredirs, empty queue */
			walk(n->u[1].p, FALSE);
			rc_exit(getstatus());
			/* NOTREACHED */
		} else if (n->u[0].p->type == nAssign) {
			if (isallpre(n->u[1].p)) {
				walk(n->u[0].p, TRUE);
				WALK(n->u[1].p, parent);
			} else {
				Estack e;
				Edata var;
				v = glom(n->u[0].p->u[0].p);
				assign(v, glob(glom(n->u[0].p->u[1].p)), TRUE);
				var.name = v->w;
				except(eVarstack, var, &e);
				walk(n->u[1].p, parent);
				varrm(v->w, TRUE);
				unexcept(); /* eVarstack */
			}
		} else
			panic("unexpected node in preredir section of walk");
		break;
	}
	case nBrace:
		if (n->u[1].p == NULL) {
			WALK(n->u[0].p, parent);
		} else if (dofork(parent)) {
			setsigdefaults(FALSE);
			walk(n->u[1].p, TRUE); /* Do redirections */
			redirq = NULL;   /* Reset redirection queue */
			walk(n->u[0].p, FALSE); /* Do commands */
			rc_exit(getstatus());
			/* NOTREACHED */
		}
		break;
	case nEpilog:
		qredir(n->u[0].p);
		if (n->u[1].p != NULL) {
			WALK(n->u[1].p, parent); /* Do more redirections. */
		} else {
			doredirs();	/* Okay, we hit the bottom. */
		}
		break;
	case nNmpipe:
		rc_error("named pipes cannot be executed as commands");
		/* NOTREACHED */
	default:
		panic("unknown node in walk");
		/* NOTREACHED */
	}
	return istrue();
}
Пример #26
0
/** Parse constructor.
 *
 * @param parse		Parser object.
 * @param outer_csi	CSI containing this declaration or @c NULL if global.
 * @return		New syntax tree node.
 */
static stree_ctor_t *parse_ctor(parse_t *parse, stree_csi_t *outer_csi)
{
	stree_ctor_t *ctor;
	stree_symbol_t *symbol;
	cspan_t *cspan;

	ctor = stree_ctor_new();
	symbol = stree_symbol_new(sc_ctor);

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

	lmatch(parse, lc_new);
	cspan = lprev_span(parse);

	/* Fake identifier. */
	ctor->name = stree_ident_new();
	ctor->name->sid = strtab_get_sid(CTOR_IDENT);
	ctor->name->cspan = lprev_span(parse);

#ifdef DEBUG_PARSE_TRACE
	printf("Parsing constructor of CSI '");
	symbol_print_fqn(csi_to_symbol(outer_csi));
	printf("'.\n");
#endif
	ctor->sig = parse_fun_sig(parse);
	if (ctor->sig->rtype != NULL) {
		cspan_print(cspan);
		printf(" Error: Constructor of CSI '");
		symbol_print_fqn(csi_to_symbol(outer_csi));
		printf("' has a return type.\n");
		parse_note_error(parse);
	}

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

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

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

		/* This constructor has no body. */
		cspan_print(cspan);
		printf(" Error: Constructor of CSI '");
		symbol_print_fqn(csi_to_symbol(outer_csi));
		printf("' has no body.\n");
		parse_note_error(parse);

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

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

	return ctor;
}
Пример #27
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;
}
Пример #28
0
/*
** Add a member to a group, creating the group if
** it does not already exist.
*/
int group_members_add(const char *argv[], gu_boolean do_add)
	{
	const char *group = argv[0];
	int x;
	char *ptr;
	int count = 0;
	void *qobj = NULL;

	if( ! am_administrator() )
		return EXIT_DENIED;

	if(do_add)
		{
		if(! group || ! argv[1])
			{
			fputs(_("You must specify a new or existing group and one or more printers\n"
				"to add to it.\n"), errors);
			return EXIT_SYNTAX;
			}
		}
	else
		{
		if(!group)
			{
			fputs(_("You must specify a new or existing group and zero or more printers\n"
				"to be its members.\n"), errors);
			return EXIT_SYNTAX;
			}
		}

	if(strlen(group) > MAX_DESTNAME)
		{
		fputs(_("Group name is too long.\n"), errors);
		return EXIT_SYNTAX;
		}

	if(strpbrk(group, DEST_DISALLOWED))
		{
		fputs(_("Group name contains a disallowed character.\n"), errors);
		return EXIT_SYNTAX;
		}

	if(strchr(DEST_DISALLOWED_LEADING, (int)group[0]))
		{
		fputs(_("Group name begins with a disallowed character.\n"), errors);
		return EXIT_SYNTAX;
		}

	/*
	** Make sure the proposed new members really exist.
	** We do this by trying to open their configuration files
	** with prnopen().
	*/
	for(x=1; argv[x]; x++)
		{
		if(prnopen(argv[x], FALSE))
			{
			fprintf(errors, _("The printer \"%s\" does not exist.\n"), argv[x]);
			return EXIT_BADDEST;
			}
		else
			{
			confclose();
			}
		}

	/*
	** If the group to which we are adding a printer
	** does not exist, create it.
	*/
	if(grpopen(group, TRUE, TRUE))
		return EXIT_INTERNAL;

	/* Copy up to but not including the 1st "Printer:" line. */
	while(confread())
		{
		if(lmatch(confline, "DefFiltOpts:"))		/* discard */
			continue;
		if(lmatch(confline, "Printer:"))			/* stop */
			break;
		conf_printf("%s\n", confline);				/* copy */
		}

	gu_Try
		{
		qobj = queueinfo_new(QUEUEINFO_GROUP, group);
		queueinfo_set_warnings_file(qobj, errors);
		queueinfo_set_debug_level(qobj, debug_level);

		/* Copy all the remaining lines. */
		do	{
			if((ptr = lmatchp(confline, "Printer:")))
				{
				if(!do_add)				/* If we are adding, just delete it. */
					continue;

				for(x=1; argv[x]; x++)	/* Is this the same as one we are adding? */
					{
					if(strcmp(ptr, argv[x]) == 0)
						gu_Throw(_("%d Printer \"%s\" is already a member of \"%s\".\n"), EXIT_ALREADY, argv[x], group);
					queueinfo_add_printer(qobj, ptr);
					count++;
					}
				}

			/* Delete old "DefFiltOpts:" lines as we go. */
			else if(lmatch(confline, "DefFiltOpts:"))
				continue;

			/* Other lines we keep. */
			conf_printf("%s\n", confline);
			} while(confread());

		/* Add a "Printer:" line for each new member. */
		for(x=1; argv[x]; x++)
			{
			conf_printf("Printer: %s\n", argv[x]);
			queueinfo_add_printer(qobj, argv[x]);
			count++;
			}

		/* Emmit the new "DefFiltOpts:" line. */
		{
		const char *cp = queueinfo_computedDefaultFilterOptions(qobj);
		if(cp)
			conf_printf("DefFiltOpts: %s\n", cp);
		}

		/* See if adding our printer will make the group too big. */
		if(count > MAX_GROUPSIZE)
			gu_Throw(_("%d Group \"%s\" would have %d members, only %d are allowed.\n"), EXIT_OVERFLOW, group, count, MAX_GROUPSIZE);

		/* Commit the changes. */
		confclose();
		}
	gu_Final
		{
		if(qobj)
			queueinfo_free(qobj);
		}
	gu_Catch
		{
		confabort();		/* roll back the changes */
		fprintf(errors, "%s: %s\n", myname, gu_exception);
		return exception_to_exitcode(gu_exception_code);
		}

	/* necessary because pprd keeps track of mounted media */
	reread_group(group);

	return EXIT_OK;
	} /* end of group_add() */