cvs commit: ALFS/nALFS/src/handlers conditionals.c

kpfleming at linuxfromscratch.org kpfleming at linuxfromscratch.org
Mon Mar 1 20:06:13 PST 2004


kpfleming    04/03/01 21:06:13

  Modified:    nALFS/src/handlers conditionals.c
  Log:
  convert to new parsing system
  various cleanups
  
  Revision  Changes    Path
  1.11      +240 -120  ALFS/nALFS/src/handlers/conditionals.c
  
  Index: conditionals.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/conditionals.c,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- conditionals.c	24 Feb 2004 06:30:11 -0000	1.10
  +++ conditionals.c	2 Mar 2004 04:06:13 -0000	1.11
  @@ -37,7 +37,6 @@
   #include "parser.h"
   
   
  -#if HANDLER_SYNTAX_3_1 || HANDLER_SYNTAX_3_2
   static int do_shelltest(const element_s * const element, const char * const test,
   			int * const result)
   {
  @@ -45,9 +44,6 @@
   	long num_value;
   	char *temp;
   
  -	if (change_to_base_dir(element, NULL, 1))
  -		return -1;
  -
   	num_value = strtol(test, &temp, 0);
   	if (*temp == '\0') {
   		/* strtol found the test string to be completely numeric */
  @@ -69,6 +65,9 @@
   	} else if (strcasecmp(test, "f") == 0) {
   		*result = 0;
   	} else {
  +		if (change_to_base_dir(element, NULL, 1))
  +			return -1;
  +
   		Nprint_h("    test %s", temp);
   		status = execute_command(element, "test %s", temp);
   		if ((status == 0) || (status == 1)) {
  @@ -80,77 +79,127 @@
   
   	return status;
   }
  -#endif
   
  -#if HANDLER_SYNTAX_3_1
  +/* <if> handler */
   
  -static const struct handler_parameter if_parameters_v3_1[] = {
  -	{ .name = "then" },
  -	{ .name = "else" },
  -	{ .name = NULL }
  +enum {
  +	IF_TEST,
  +	IF_PACKAGE,
  +};
  +
  +struct if_data {
  +	char *test;
  +	char *package;
   };
   
  +static int if_setup(element_s * const element)
  +{
  +	struct if_data *data;
  +
  +	if ((data = xmalloc(sizeof(struct if_data))) == NULL)
  +		return 1;
  +
  +	data->test = NULL;
  +	data->package = NULL;
  +	element->handler_data = data;
  +
  +	return 0;
  +}
  +
  +static void if_free(const element_s * const element)
  +{
  +	struct if_data *data = (struct if_data *) element->handler_data;
  +
  +	xfree(data->test);
  +	xfree(data->package);
  +	xfree(data);
  +}
  +
  +static int if_valid_child(const element_s * const element,
  +			  const element_s * const child)
  +{
  +	(void) element;
  +
  +	return child->handler->type & (HTYPE_TEST |
  +				       HTYPE_TRUE_RESULT |
  +				       HTYPE_FALSE_RESULT);
  +}
  +
  +#if HANDLER_SYNTAX_3_1
  +
   static const struct handler_attribute if_attributes_v3_1[] = {
  -	{ .name = "test" },
  -	{ .name = "package" },
  +	{ .name = "test", .private = IF_TEST },
  +	{ .name = "package", .private = IF_PACKAGE },
   	{ .name = NULL }
   };
   
  -static int if_main_3_1(const element_s * const element)
  +static int if_attribute_v3_1(const element_s * const element,
  +			     const struct handler_attribute * const attr,
  +			     const char * const value)
   {
  -	char *shelltest;
  -	char *packagetest;
  +	struct if_data *data = (struct if_data *) element->handler_data;
  +
  +	switch (attr->private) {
  +	case IF_TEST:
  +		if (data->test) {
  +			Nprint_err("<if>: cannot specify \"test\" more than once.");
  +			return 1;
  +		}
  +		data->test = xstrdup(value);
  +		return 0;
  +	case IF_PACKAGE:
  +		if (data->package) {
  +			Nprint_err("<if>: cannot specify \"package\" more than once.");
  +			return 1;
  +		}
  +		data->package = xstrdup(value);
  +		return 0;
  +	default:
  +		return 1;
  +	}
  +}
  +
  +static int if_valid_data_v3_1(const element_s * const element)
  +{
  +	struct if_data *data = (struct if_data *) element->handler_data;
  +
  +	if (data->test && data->package) {
  +		Nprint_err("<if>: cannot specify both \"test\" and \"package\".");
  +		return 0;
  +	}
  +
  +	if (!(data->test || data->package)) {
  +		Nprint_err("<if>: must specify either \"test\" or \"package\".");
  +		return 0;
  +	}
  +
  +	return 1;
  +}
  +
  +static int if_main_v3_1(const element_s * const element)
  +{
  +	struct if_data *data = (struct if_data *) element->handler_data;
   	int test_result = 1;
   	handler_type_e result_handler_type = HTYPE_TRUE_RESULT;
   	int status;
   
  -	shelltest = attr_value("test", element);
  -	packagetest = attr_value("package", element);
  -	if (shelltest && packagetest) {
  -		Nprint_h_err("Cannot specify both \"test\" and \"package\".");
  -		return -1;
  -	}
  -	if (!shelltest && !packagetest) {
  -		Nprint_h_err("Must specify either \"test\" or \"package\".");
  -		return -1;
  -	}
  -	if (shelltest) {
  -		if ((status = do_shelltest(element, shelltest, &test_result)))
  +	if (data->test) {
  +		if ((status = do_shelltest(element, data->test, &test_result)))
   			return status;
   	} else {
  +		/* TODO: implement package test */
   	}
   	if (!test_result)
   		result_handler_type = HTYPE_FALSE_RESULT;
   
   	return execute_children_filtered(element, result_handler_type);
   }
  +
   #endif
   
   #if HANDLER_SYNTAX_3_2
   
  -static const struct handler_parameter if_parameters_3_2[] = {
  -	{ .name = "then" },
  -	{ .name = "else" },
  -	{ .name = "package-version" },
  -	{ .name = "package-built" },
  -	{ .name = "test" },
  -	{ .name = "and" },
  -	{ .name = "or" },
  -	{ .name = "not" },
  -	{ .name = NULL }
  -};
  -
  -static const struct handler_parameter boolean_parameters_3_2[] = {
  -	{ .name = "package-version" },
  -	{ .name = "package-built" },
  -	{ .name = "test" },
  -	{ .name = "and" },
  -	{ .name = "or" },
  -	{ .name = "not" },
  -	{ .name = NULL }
  -};
  -
  -static int if_main_3_2(const element_s * const element)
  +static int if_main_v3_2(const element_s * const element)
   {
   	int i;
   	element_s *child;
  @@ -158,10 +207,6 @@
   	handler_type_e result_handler_type = HTYPE_TRUE_RESULT;
   
   	for (child = element->children; test_result && child; child = child->next) {
  -		if (!child->handler) {
  -			Nprint_h_err("<%s> element not allowed inside <if>.", child->name);
  -			return -1;
  -		}
   		if ((child->handler->type & HTYPE_TEST) != 0) {
   			i = do_execute_test_element(child, &test_result);
   			if (i != 0)
  @@ -175,101 +220,159 @@
   	return execute_children_filtered(element, result_handler_type);
   }
   
  -static int and_test_3_2(const element_s * const element, int * const result)
  +#endif
  +
  +#if HANDLER_SYNTAX_3_2
  +
  +/* handlers for <and>, <or> and <not> (booleans) */
  +
  +static int boolean_setup(element_s * const element)
  +{
  +	(void) element;
  +
  +	return 0;
  +}
  +
  +static int boolean_valid_child(const element_s * const element,
  +			       const element_s * const child)
  +{
  +	(void) element;
  +
  +	return child->handler->type & HTYPE_TEST;
  +}
  +
  +static int not_valid_child(const element_s * const element,
  +			   const element_s * const child)
  +{
  +	if (element->children) {
  +		Nprint_err("<not>: cannot specify more than one test.");
  +		return 0;
  +	}
  +
  +	if (!(child->handler->type & HTYPE_TEST))
  +		return 0;
  +
  +	return 1;
  +}
  +
  +static int and_test(const element_s * const element, int * const result)
   {
   	int i;
   	element_s *child;
   
   	*result = 1;
   	for (child = element->children; *result && child; child = child->next) {
  -		if (child->handler &&
  -		    ((child->handler->type & HTYPE_TEST) != 0)) {
  -			i = do_execute_test_element(child, result);
  -			if (i != 0)
  -				return i;
  -		} else {
  -			Nprint_h_err("<%s> element not allowed inside <and>.", child->name);
  -			return -1;
  -		}
  +		i = do_execute_test_element(child, result);
  +		if (i != 0)
  +			return i;
   	}
   
   	return 0;
   }
   
  -static int or_test_3_2(const element_s * const element, int * const result)
  +static int or_test(const element_s * const element, int * const result)
   {
   	int i;
   	element_s *child;
   
   	*result = 0;
   	for (child = element->children; !*result && child; child = child->next) {
  -		if (child->handler &&
  -		    ((child->handler->type & HTYPE_TEST) != 0)) {
  -			i = do_execute_test_element(child, result);
  -			if (i != 0)
  -				return i;
  -		} else {
  -			Nprint_h_err("<%s> element not allowed inside <or>.", child->name);
  -			return -1;
  -		}
  +		i = do_execute_test_element(child, result);
  +		if (i != 0)
  +			return i;
   	}
   
   	return 0;
   }
   
  -static int not_test_3_2(const element_s * const element, int * const result)
  +static int not_test(const element_s * const element, int * const result)
   {
   	int i;
   	element_s *child;
   
   	child = element->children;
  -	if (child->next) {
  -		Nprint_h_err("multiple elements not allowed inside <not>.");
  -		return -1;
  -	}
  +	i = do_execute_test_element(child, result);
  +	if (i != 0)
  +		return i;
  +	*result = !*result;
   
  -	if (child->handler &&
  -	    ((child->handler->type & HTYPE_TEST) != 0)) {
  -		i = do_execute_test_element(child, result);
  -		if (i != 0)
  -			return i;
  -		*result = !*result;
  -	} else {
  -		Nprint_h_err("<%s> element not allowed inside <not>.", child->name);
  -		return -1;
  -	}
  +	return 0;
  +}
  +
  +/* <test>, <package-built> and <package-version> handlers */
  +
  +struct test_data {
  +	char *content;
  +};
  +
  +static int test_setup(element_s * const element)
  +{
  +	struct test_data *data;
  +
  +	if ((data = xmalloc(sizeof(struct test_data))) == NULL)
  +		return 1;
  +
  +	data->content = NULL;
  +	element->handler_data = data;
   
   	return 0;
   }
   
  -static int shelltest_test_3_2(const element_s * const element, int * const result)
  +static void test_free(const element_s * const element)
   {
  -	char *test;
  -	int status = -1;
  +	struct test_data *data = (struct test_data *) element->handler_data;
   
  -	if ((test = alloc_trimmed_str(element->content)) == NULL) {
  -		Nprint_h_err("No test content specified.");
  -	} else {
  -		status = do_shelltest(element, test, result);
  -		xfree(test);
  +	xfree(data->content);
  +	xfree(data);
  +}
  +
  +static int test_content(const element_s * const element,
  +			const char * const content)
  +{
  +	struct test_data *data = (struct test_data *) element->handler_data;
  +
  +	if (strlen(content))
  +		data->content = xstrdup(content);
  +
  +	return 0;
  +}
  +
  +static int test_valid_data(const element_s * const element)
  +{
  +	struct test_data *data = (struct test_data *) element->handler_data;
  +
  +	if (!data->content) {
  +		Nprint_err("<%s>: content cannot be blank.", element->handler->name);
  +		return 0;
   	}
   
  -	return status;
  +	return 1;
  +}
  +
  +static int shelltest_test(const element_s * const element, int * const result)
  +{
  +	struct test_data *data = (struct test_data *) element->handler_data;
  +
  +	return do_shelltest(element, data->content, result);
   }
   
  -static int package_version_test_3_2(const element_s * const element,
  -				    int * const result)
  +static int package_version_test(const element_s * const element, int * const result)
   {
  +	struct test_data *data = (struct test_data *) element->handler_data;
  +
   	(void) element;
   	(void) result;
  +	(void) data;
   	return 0;
   }
   
  -static int package_built_test_3_2(const element_s * const element,
  -				  int * const result)
  +static int package_built_test(const element_s * const element, int * const result)
   {
  +	struct test_data *data = (struct test_data *) element->handler_data;
  +
   	(void) element;
   	(void) result;
  +	(void) data;
   	return 0;
   }
   #endif
  @@ -284,11 +387,15 @@
   		.name = "if",
   		.description = "if",
   		.syntax_version = "3.1",
  -		.parameters = if_parameters_v3_1,
  -		.attributes = if_attributes_v3_1,
  -		.main = if_main_3_1,
   		.type = HTYPE_NORMAL,
   		.is_action = 1,
  +		.main = if_main_v3_1,
  +		.setup = if_setup,
  +		.free = if_free,
  +		.attributes = if_attributes_v3_1,
  +		.attribute = if_attribute_v3_1,
  +		.valid_data = if_valid_data_v3_1,
  +		.valid_child = if_valid_child,
   	},
   #endif
   #if HANDLER_SYNTAX_3_2
  @@ -296,68 +403,81 @@
   		.name = "if",
   		.description = "if",
   		.syntax_version = "3.2",
  -		.parameters = if_parameters_3_2,
  -		.main = if_main_3_2,
   		.type = HTYPE_NORMAL,
   		.is_action = 1,
  -		.alternate_shell = 1,
  +		.main = if_main_v3_2,
  +		.setup = if_setup,
  +		.free = if_free,
  +		.valid_child = if_valid_child,
   	},
   	{
   		.name = "and",
   		.description = "and",
   		.syntax_version = "3.2",
  -		.parameters = boolean_parameters_3_2,
  -		.test = and_test_3_2,
   		.type = HTYPE_TEST,
   		.is_action = 1,
  -		.alternate_shell = 1,
  +		.test = and_test,
  +		.setup = boolean_setup,
  +		.valid_child = boolean_valid_child,
   	},
   	{
   		.name = "or",
   		.description = "or",
   		.syntax_version = "3.2",
  -		.parameters = boolean_parameters_3_2,
  -		.test = or_test_3_2,
   		.type = HTYPE_TEST,
   		.is_action = 1,
  -		.alternate_shell = 1,
  +		.test = or_test,
  +		.setup = boolean_setup,
  +		.valid_child = boolean_valid_child,
   	},
   	{
   		.name = "not",
   		.description = "not",
   		.syntax_version = "3.2",
  -		.parameters = boolean_parameters_3_2,
  -		.test = not_test_3_2,
   		.type = HTYPE_TEST,
   		.is_action = 1,
  -		.alternate_shell = 1,
  +		.test = not_test,
  +		.setup = boolean_setup,
  +		.valid_child = not_valid_child,
   	},
   	{
   		.name = "test",
   		.description = "Shell Test",
   		.syntax_version = "3.2",
  -		.test = shelltest_test_3_2,
   		.type = HTYPE_TEST,
   		.alternate_shell = 1,
   		.is_action = 1,
  +		.test = shelltest_test,
  +		.setup = test_setup,
  +		.free = test_free,
  +		.content = test_content,
  +		.valid_data = test_valid_data,
   	},
   	{
   		.name = "package-built",
   		.description = "Package Built",
   		.syntax_version = "3.2",
  -		.test = package_built_test_3_2,
   		.type = HTYPE_TEST,
   		.is_action = 1,
   		.alternate_shell = 1,
  +		.test = package_built_test,
  +		.setup = test_setup,
  +		.free = test_free,
  +		.content = test_content,
  +		.valid_data = test_valid_data,
   	},
   	{
   		.name = "package-version",
   		.description = "Package Version",
   		.syntax_version = "3.2",
  -		.test = package_version_test_3_2,
   		.type = HTYPE_TEST,
   		.is_action = 1,
   		.alternate_shell = 1,
  +		.test = package_version_test,
  +		.setup = test_setup,
  +		.free = test_free,
  +		.content = test_content,
  +		.valid_data = test_valid_data,
   	},
   #endif
   	{
  
  
  



More information about the alfs-log mailing list