aboutsummaryrefslogtreecommitdiffstats
path: root/build_tools
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2006-05-07 12:00:55 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2006-05-07 12:00:55 +0000
commit43ffeb8506b9a38e5258143e57c138d28f27677e (patch)
tree45789f831fdf7ad378c450e6470e1dc5aba30ec9 /build_tools
parent8fcbc77f1f71d40ef2a88c8ec204d1df39ae3388 (diff)
various menuselect fixes as a result of boredom during a 9 hour flight and
now a 9 hour layover ... - If a module is disabled from being built because of failed dependencies or a conflict, automatically re-enable the module if the issues are later resolved. - If a module has been disabled by default, only set this value if there is not an existing menuselect.makeopts file. Previously, this value would get reset every time you ran menuselect. - staticize a bunch of functions and variables that aren't public git-svn-id: http://svn.digium.com/svn/asterisk/trunk@25287 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'build_tools')
-rw-r--r--build_tools/menuselect.c247
-rw-r--r--build_tools/menuselect.h4
2 files changed, 155 insertions, 96 deletions
diff --git a/build_tools/menuselect.c b/build_tools/menuselect.c
index 2f23d96e8..16570d867 100644
--- a/build_tools/menuselect.c
+++ b/build_tools/menuselect.c
@@ -72,46 +72,34 @@ struct tree {
};
/*! The list of trees from makeopts.xml files */
-AST_LIST_HEAD_NOLOCK_STATIC(trees, tree);
+static AST_LIST_HEAD_NOLOCK_STATIC(trees, tree);
-const char * const makeopts_files[] = {
+static const char * const makeopts_files[] = {
"makeopts.xml"
};
-char *output_makeopts = OUTPUT_MAKEOPTS_DEFAULT;
+static char *output_makeopts = OUTPUT_MAKEOPTS_DEFAULT;
/*! This is set to 1 if menuselect.makeopts pre-existed the execution of this app */
-int existing_config = 0;
+static int existing_config = 0;
/*! This is set when the --check-deps argument is provided. */
-int check_deps = 0;
+static int check_deps = 0;
/*! Force a clean of the source tree */
-int force_clean = 0;
-
-int add_category(struct category *cat);
-int add_member(struct member *mem, struct category *cat);
-int parse_makeopts_xml(const char *makeopts_xml);
-int process_deps(void);
-int build_member_list(void);
-void mark_as_present(const char *member, const char *category);
-int parse_existing_config(const char *infile);
-int generate_makeopts_file(void);
-void free_member_list(void);
-void free_trees(void);
-
-/*! \brief a wrapper for calloc() that generates an error message if the allocation fails */
-static inline void *my_calloc(size_t num, size_t len)
-{
- void *tmp;
-
- tmp = calloc(num, len);
-
- if (!tmp)
- fprintf(stderr, "Memory allocation error!\n");
-
- return tmp;
-}
+static int force_clean = 0;
+
+static int add_category(struct category *cat);
+static int add_member(struct member *mem, struct category *cat);
+static int parse_makeopts_xml(const char *makeopts_xml);
+static int process_deps(void);
+static int build_member_list(void);
+static void mark_as_present(const char *member, const char *category);
+static void process_prev_failed_deps(char *buf);
+static int parse_existing_config(const char *infile);
+static int generate_makeopts_file(void);
+static void free_member_list(void);
+static void free_trees(void);
/*! \brief return a pointer to the first non-whitespace character */
static inline char *skip_blanks(char *str)
@@ -126,7 +114,7 @@ static inline char *skip_blanks(char *str)
}
/*! \brief Add a category to the category list, ensuring that there are no duplicates */
-int add_category(struct category *cat)
+static int add_category(struct category *cat)
{
struct category *tmp;
@@ -142,7 +130,7 @@ int add_category(struct category *cat)
}
/*! \brief Add a member to the member list of a category, ensuring that there are no duplicates */
-int add_member(struct member *mem, struct category *cat)
+static int add_member(struct member *mem, struct category *cat)
{
struct member *tmp;
@@ -158,7 +146,7 @@ int add_member(struct member *mem, struct category *cat)
}
/*! \brief Parse an input makeopts file */
-int parse_makeopts_xml(const char *makeopts_xml)
+static int parse_makeopts_xml(const char *makeopts_xml)
{
FILE *f;
struct category *cat;
@@ -177,7 +165,7 @@ int parse_makeopts_xml(const char *makeopts_xml)
return -1;
}
- if (!(tree = my_calloc(1, sizeof(*tree)))) {
+ if (!(tree = calloc(1, sizeof(*tree)))) {
fclose(f);
return -1;
}
@@ -195,7 +183,7 @@ int parse_makeopts_xml(const char *makeopts_xml)
cur;
cur = mxmlFindElement(cur, menu, "category", NULL, NULL, MXML_DESCEND))
{
- if (!(cat = my_calloc(1, sizeof(*cat))))
+ if (!(cat = calloc(1, sizeof(*cat))))
return -1;
cat->name = mxmlElementGetAttr(cur, "name");
@@ -214,29 +202,23 @@ int parse_makeopts_xml(const char *makeopts_xml)
cur2;
cur2 = mxmlFindElement(cur2, cur, "member", NULL, NULL, MXML_DESCEND))
{
- if (!(mem = my_calloc(1, sizeof(*mem))))
+ if (!(mem = calloc(1, sizeof(*mem))))
return -1;
- if (!cat->positive_output)
- mem->enabled = 1; /* Enabled by default */
-
mem->name = mxmlElementGetAttr(cur2, "name");
-
+
+ if (!cat->positive_output)
+ mem->enabled = 1;
+
cur3 = mxmlFindElement(cur2, cur2, "defaultenabled", NULL, NULL, MXML_DESCEND);
- if (cur3 && cur3->child) {
- if (!strcasecmp("no", cur3->child->value.opaque))
- mem->enabled = 0;
- else if (!strcasecmp("yes", cur3->child->value.opaque))
- mem->enabled = 1;
- else
- fprintf(stderr, "Invalid value '%s' for <defaultenabled> !\n", cur3->child->value.opaque);
- }
+ if (cur3 && cur3->child)
+ mem->defaultenabled = cur3->child->value.opaque;
for (cur3 = mxmlFindElement(cur2, cur2, "depend", NULL, NULL, MXML_DESCEND);
cur3 && cur3->child;
cur3 = mxmlFindElement(cur3, cur2, "depend", NULL, NULL, MXML_DESCEND))
{
- if (!(dep = my_calloc(1, sizeof(*dep))))
+ if (!(dep = calloc(1, sizeof(*dep))))
return -1;
if (!strlen_zero(cur3->child->value.opaque)) {
dep->name = cur3->child->value.opaque;
@@ -249,7 +231,7 @@ int parse_makeopts_xml(const char *makeopts_xml)
cur3 && cur3->child;
cur3 = mxmlFindElement(cur3, cur2, "conflict", NULL, NULL, MXML_DESCEND))
{
- if (!(cnf = my_calloc(1, sizeof(*cnf))))
+ if (!(cnf = calloc(1, sizeof(*cnf))))
return -1;
if (!strlen_zero(cur3->child->value.opaque)) {
cnf->name = cur3->child->value.opaque;
@@ -269,7 +251,7 @@ int parse_makeopts_xml(const char *makeopts_xml)
}
/*! \brief Process dependencies against the input dependencies file */
-int process_deps(void)
+static int process_deps(void)
{
struct category *cat;
struct member *mem;
@@ -297,7 +279,7 @@ int process_deps(void)
strsep(&p, "=");
if (!p)
continue;
- if (!(dep_file = my_calloc(1, sizeof(*dep_file))))
+ if (!(dep_file = calloc(1, sizeof(*dep_file))))
break;
strncpy(dep_file->name, buf, sizeof(dep_file->name) - 1);
dep_file->met = atoi(p);
@@ -321,20 +303,6 @@ int process_deps(void)
if (mem->depsfailed)
break; /* This dependency is not met, so we can stop now */
}
- if (mem->depsfailed) {
- if (check_deps && existing_config && mem->enabled) {
- /* Config already existed, but this module was not disabled.
- * However, according to our current list of dependencies that
- * have been met, this can not be built. */
- res = -1;
- fprintf(stderr, "\nThe existing menuselect.makeopts did not specify that %s should not be built\n", mem->name);
- fprintf(stderr, "However, menuselect-deps indicates that dependencies for this module have not\n");
- fprintf(stderr, "been met. So, either remove the existing menuselect.makeopts file, or run\n");
- fprintf(stderr, "'make menuselect' to generate a file that is correct.\n\n");
- goto deps_file_free;
- }
- mem->enabled = 0; /* Automatically disable it if dependencies not met */
- }
}
}
@@ -353,25 +321,9 @@ int process_deps(void)
if (mem->conflictsfailed)
break; /* This conflict was found, so we can stop now */
}
- if (mem->conflictsfailed) {
- if (check_deps && existing_config && mem->enabled) {
- /* Config already existed, but this module was not disabled.
- * However, according to our current list of conflicts that
- * exist, this can not be built. */
- res = -1;
- fprintf(stderr, "\nThe existing menuselect.makeopts did not specify that %s should not be built\n", mem->name);
- fprintf(stderr, "However, menuselect-deps indicates that conflicts for this module exist.\n");
- fprintf(stderr, "So, either remove the existing menuselect.makeopts file, or run\n");
- fprintf(stderr, "'make menuselect' to generate a file that is correct.\n\n");
- goto deps_file_free;
- }
- mem->enabled = 0; /* Automatically disable it if conflicts exist */
- }
}
}
-deps_file_free:
-
/* Free the dependency list we built from the file */
while ((dep_file = AST_LIST_REMOVE_HEAD(&deps_file, list)))
free(dep_file);
@@ -380,7 +332,7 @@ deps_file_free:
}
/*! \brief Iterate through all of the input makeopts files and call the parse function on them */
-int build_member_list(void)
+static int build_member_list(void)
{
int i;
int res = -1;
@@ -396,7 +348,7 @@ int build_member_list(void)
}
/*! \brief Given the string representation of a member and category, mark it as present in a given input file */
-void mark_as_present(const char *member, const char *category)
+static void mark_as_present(const char *member, const char *category)
{
struct category *cat;
struct member *mem;
@@ -437,8 +389,45 @@ void toggle_enabled(struct category *cat, int index)
}
}
+/*! \brief Process a previously failed dependency
+ *
+ * If a module was previously disabled because of a failed dependency
+ * or a conflict, and not because the user selected it to be that way,
+ * then it needs to be re-enabled by default if the problem is no longer present.
+ */
+static void process_prev_failed_deps(char *buf)
+{
+ const char *cat_name, *mem_name;
+ struct category *cat;
+ struct member *mem;
+
+ cat_name = strsep(&buf, "=");
+ mem_name = strsep(&buf, "\n");
+
+ if (!cat_name || !mem_name)
+ return;
+
+ AST_LIST_TRAVERSE(&categories, cat, list) {
+ if (strcasecmp(cat->name, cat_name))
+ continue;
+ AST_LIST_TRAVERSE(&cat->members, mem, list) {
+ if (strcasecmp(mem->name, mem_name))
+ continue;
+
+ if (!mem->depsfailed && !mem->conflictsfailed)
+ mem->enabled = 1;
+
+ break;
+ }
+ break;
+ }
+
+ if (!cat || !mem)
+ fprintf(stderr, "Unable to find '%s' in category '%s'\n", mem_name, cat_name);
+}
+
/*! \brief Parse an existing output makeopts file and enable members previously selected */
-int parse_existing_config(const char *infile)
+static int parse_existing_config(const char *infile)
{
FILE *f;
char buf[2048];
@@ -474,13 +463,18 @@ int parse_existing_config(const char *infile)
fprintf(stderr, "Invalid string in '%s' at line '%d'!\n", output_makeopts, lineno);
continue;
}
-
+
parse = skip_blanks(parse);
+
+ if (!strcasecmp(category, "MENUSELECT_DEPSFAILED")) {
+ process_prev_failed_deps(parse);
+ continue;
+ }
+
while ((member = strsep(&parse, " \n"))) {
member = skip_blanks(member);
if (strlen_zero(member))
continue;
-
mark_as_present(member, category);
}
}
@@ -491,7 +485,7 @@ int parse_existing_config(const char *infile)
}
/*! \brief Create the output makeopts file that results from the user's selections */
-int generate_makeopts_file(void)
+static int generate_makeopts_file(void)
{
FILE *f;
struct category *cat;
@@ -513,6 +507,14 @@ int generate_makeopts_file(void)
fprintf(f, "\n");
}
+ /* Output which members were disabled because of failed dependencies or conflicts */
+ AST_LIST_TRAVERSE(&categories, cat, list) {
+ AST_LIST_TRAVERSE(&cat->members, mem, list) {
+ if (mem->depsfailed || mem->conflictsfailed)
+ fprintf(f, "MENUSELECT_DEPSFAILED=%s=%s\n", cat->name, mem->name);
+ }
+ }
+
fclose(f);
return 0;
@@ -520,7 +522,7 @@ int generate_makeopts_file(void)
#ifdef MENUSELECT_DEBUG
/*! \brief Print out all of the information contained in our tree */
-void dump_member_list(void)
+static void dump_member_list(void)
{
struct category *cat;
struct member *mem;
@@ -545,7 +547,7 @@ void dump_member_list(void)
#endif
/*! \brief Free all categories and their members */
-void free_member_list(void)
+static void free_member_list(void)
{
struct category *cat;
struct member *mem;
@@ -565,7 +567,7 @@ void free_member_list(void)
}
/*! \brief Free all of the XML trees */
-void free_trees(void)
+static void free_trees(void)
{
struct tree *tree;
@@ -608,6 +610,52 @@ int count_members(struct category *cat)
return count;
}
+/*! \brief Make sure an existing menuselect.makeopts disabled everything it should have */
+static int sanity_check(void)
+{
+ struct category *cat;
+ struct member *mem;
+
+ AST_LIST_TRAVERSE(&categories, cat, list) {
+ AST_LIST_TRAVERSE(&cat->members, mem, list) {
+ if ((mem->depsfailed || mem->conflictsfailed) && mem->enabled) {
+ fprintf(stderr, "\n***********************************************************\n"
+ " The existing menuselect.makeopts file did not specify \n"
+ " that '%s' should not be included. However, either some \n"
+ " dependencies for this module were not found or a \n"
+ " conflict exists. \n"
+ " \n"
+ " Either run 'make menuselect' or remove the existing \n"
+ " menuselect.makeopts file to resolve this issue. \n"
+ "***********************************************************\n\n", mem->name);
+ return -1;
+ }
+ }
+ }
+}
+
+/* \brief Set the forced default values if they exist */
+static void process_defaults(void)
+{
+ struct category *cat;
+ struct member *mem;
+
+ AST_LIST_TRAVERSE(&categories, cat, list) {
+ AST_LIST_TRAVERSE(&cat->members, mem, list) {
+ if (!mem->defaultenabled)
+ continue;
+
+ if (!strcasecmp(mem->defaultenabled, "yes"))
+ mem->enabled = 1;
+ else if (!strcasecmp(mem->defaultenabled, "no"))
+ mem->enabled = 0;
+ else
+ fprintf(stderr, "Invalid defaultenabled value for '%s' in category '%s'\n", mem->name, cat->name);
+ }
+ }
+
+}
+
int main(int argc, char *argv[])
{
int res = 0;
@@ -616,7 +664,10 @@ int main(int argc, char *argv[])
/* Parse the input XML files to build the list of available options */
if ((res = build_member_list()))
exit(res);
-
+
+ /* Process module dependencies */
+ res = process_deps();
+
/* The --check-deps option is used to ask this application to check to
* see if that an existing menuselect.makeopts file contails all of the
* modules that have dependencies that have not been met. If this
@@ -629,17 +680,20 @@ int main(int argc, char *argv[])
res = parse_existing_config(argv[x]);
if (!res && !strcasecmp(argv[x], OUTPUT_MAKEOPTS_DEFAULT))
existing_config = 1;
+ res = 0;
}
}
- /* Process module dependencies */
- res = process_deps();
-
#ifdef MENUSELECT_DEBUG
/* Dump the list produced by parsing the various input files */
dump_member_list();
#endif
+ if (!existing_config)
+ process_defaults();
+ else if (check_deps)
+ res = sanity_check();
+
/* Run the menu to let the user enable/disable options */
if (!check_deps && !res)
res = run_menu();
@@ -664,6 +718,9 @@ int main(int argc, char *argv[])
res = -1;
}
+ /* In some cases, such as modifying the CFLAGS for the build,
+ * a "make clean" needs to be forced. Removing the .lastclean
+ * file does this. */
if (force_clean)
unlink(".lastclean");
diff --git a/build_tools/menuselect.h b/build_tools/menuselect.h
index 3bd344cc2..4db045da1 100644
--- a/build_tools/menuselect.h
+++ b/build_tools/menuselect.h
@@ -19,7 +19,7 @@
/*!
* \file
*
- * \brief defaults for menuselect
+ * \brief public data structures and defaults for menuselect
*
*/
@@ -37,6 +37,8 @@ struct conflict;
struct member {
/*! What will be sent to the makeopts file */
const char *name;
+ /*! Default setting */
+ const char *defaultenabled;
/*! This module is currently selected */
int enabled;
/*! This module has failed dependencies */