#include "pconf.h" static int PConfEnableFeature( pconf_core_struct *core_ptr, platform_struct *platform_ptr, const char *name ); static int PConfDisableFeature( pconf_core_struct *core_ptr, platform_struct *platform_ptr, const char *name ); void PConfApplyArgsToPlatform( pconf_core_struct *core_ptr, platform_struct *platform_ptr, int argc, char *argv[] ); static int PConfScanFileString( const char *filename, const char *s ); static char *PConfDependMatchFile( platform_struct *platform_ptr, int type, const char *path, struct stat *stat_buf ); static int PConfDependCheck( pconf_core_struct *core_ptr, platform_struct *platform_ptr, depend_struct *depend_ptr, const char *feature_name, int dep_cur, int dep_total ); int PConfCheckDepends( pconf_core_struct *core_ptr, platform_struct *platform_ptr ); /* * Enables the feature on the given platform specified by name, * marking its must_exist value to PCONF_MUST_EXIST_YES. * * Returns 0 on success, -1 on error, -2 no such feature. */ static int PConfEnableFeature( pconf_core_struct *core_ptr, platform_struct *platform_ptr, const char *name ) { int feature_num; feature_struct *feature_ptr; if((core_ptr == NULL) || (platform_ptr == NULL) || (name == NULL)) return(-1); feature_ptr = PConfMatchFeatureByName( platform_ptr, name, &feature_num ); if(feature_ptr == NULL) return(-2); feature_ptr->must_exist = PCONF_MUST_EXIST_YES; return(0); } /* * Disables the feature on the given platform specified by name, * marking its must_exist value to PCONF_MUST_EXIST_NO. * * Returns 0 on success, -1 on error, -2 no such feature, -3 * if the feature's must_exist was initially PCONF_MUST_EXIST_YES. */ static int PConfDisableFeature( pconf_core_struct *core_ptr, platform_struct *platform_ptr, const char *name ) { int feature_num; feature_struct *feature_ptr; if((core_ptr == NULL) || (platform_ptr == NULL) || (name == NULL)) return(-1); feature_ptr = PConfMatchFeatureByName( platform_ptr, name, &feature_num ); if(feature_ptr == NULL) return(-2); /* Cannot disable this? */ if(feature_ptr->must_exist == PCONF_MUST_EXIST_YES) return(-3); feature_ptr->must_exist = PCONF_MUST_EXIST_NO; return(0); } /* * Applies environments and given arguments to the given platform's * values. */ void PConfApplyArgsToPlatform( pconf_core_struct *core_ptr, platform_struct *platform_ptr, int argc, char *argv[] ) { int i, status; const char *arg_ptr; if((core_ptr == NULL) || (platform_ptr == NULL)) return; /* Can we initially get values from environment variables? */ if(!core_ptr->ignore_environments) { const char *cstrptr; /* Prefix. */ cstrptr = GETENV("PREFIX"); if(cstrptr != NULL) { FREE(platform_ptr->prefix); platform_ptr->prefix = STRDUP(cstrptr); } /* Compiler flags. */ cstrptr = GETENV("CFLAGS"); if(cstrptr != NULL) { FREE(platform_ptr->cflags); platform_ptr->cflags = STRDUP(cstrptr); } /* Include directories. */ cstrptr = GETENV("INC_DIRS"); if(cstrptr != NULL) { FREE(platform_ptr->inc_dirs); platform_ptr->inc_dirs = STRDUP(cstrptr); } /* Libraries. */ cstrptr = GETENV("LIBS"); if(cstrptr != NULL) { FREE(platform_ptr->libs); platform_ptr->libs = STRDUP(cstrptr); } /* Library directories. */ cstrptr = GETENV("LIB_DIRS"); if(cstrptr != NULL) { FREE(platform_ptr->lib_dirs); platform_ptr->lib_dirs = STRDUP(cstrptr); } /* C compiler. */ cstrptr = GETENV("CC"); if(cstrptr != NULL) { FREE(platform_ptr->cc); platform_ptr->cc = STRDUP(cstrptr); } /* C++ compiler. */ cstrptr = GETENV("CPP"); if(cstrptr != NULL) { FREE(platform_ptr->cpp); platform_ptr->cpp = STRDUP(cstrptr); } /* Parse LD library paths. */ cstrptr = GETENV("LD_LIBRARY_PATH"); if(cstrptr != NULL) { char *new_path, *strptr2; /* Itterate through value string. */ while((*cstrptr) != '\0') { /* Seek past ' ' and ':' characters. */ while(ISBLANK(*cstrptr) || ((*cstrptr) == ':')) cstrptr++; /* Skip "-L" prefixes. */ if(STRPFX(cstrptr, "-L")) { cstrptr += STRLEN("-L"); } /* Copy string at position of cstrptr. */ new_path = STRDUP(cstrptr); if(new_path != NULL) { /* Deliminate at next ' ' or ':' if any. */ strptr2 = (char *)STRCHR((char *)new_path, ':'); if(strptr2 != NULL) (*strptr2) = '\0'; strptr2 = (char *)STRCHR((char *)new_path, ' '); if(strptr2 != NULL) (*strptr2) = '\0'; /* Add this to the library path. */ STRLISTAPPEND( &platform_ptr->path_library, &platform_ptr->total_path_libraries, new_path ); if(core_ptr->verbose) printf( "Adding platform's library path: %s\n", new_path ); FREE(new_path); new_path = NULL; } /* Seek cstrptr to next argument, seeking to * next ' ' or ':' character. */ while(!ISBLANK(*cstrptr) && ((*cstrptr) != ':') && ((*cstrptr) != '\0') ) cstrptr++; } } } /* Itterate through each argument. */ for(i = 0; i < argc; i++) { arg_ptr = (const char *)argv[i]; if(arg_ptr == NULL) continue; /* Skip any args that don't begin with - or --. */ if((*arg_ptr) != '-') continue; /* Seek past '-' characters. */ while((*arg_ptr) == '-') arg_ptr++; /* Enable or with? */ if(STRCASEPFX(arg_ptr, "enable") || STRCASEPFX(arg_ptr, "with") ) { /* Enable what? */ const char *cstrptr = STRCHR(arg_ptr, '='); if(cstrptr == NULL) cstrptr = STRCHR(arg_ptr, '-'); if(cstrptr != NULL) { cstrptr++; while(ISBLANK(*cstrptr)) cstrptr++; status = PConfEnableFeature( core_ptr, platform_ptr, cstrptr ); switch(status) { case -2: if(core_ptr->warnings) { fprintf(stderr, "%s: ", cstrptr); PConfSetColor(core_ptr, stderr, PCONF_COLOR_WARNING ); fprintf(stderr, "No such feature to enable.\n" ); } break; case -1: if(core_ptr->warnings) { fprintf(stderr, "%s: ", cstrptr); PConfSetColor(core_ptr, stderr, PCONF_COLOR_FAILURE ); fprintf(stderr, "Error enabling this feature.\n" ); } break; } PConfSetColor(core_ptr, stderr, PCONF_COLOR_DEFAULT ); } else { if(core_ptr->warnings) fprintf( stderr, "--%s: Argument must have a value separated by a '='.\n", arg_ptr ); } } /* Disable or without? */ else if(STRCASEPFX(arg_ptr, "disable") || STRCASEPFX(arg_ptr, "without") || STRCASEPFX(arg_ptr, "with-out") || STRCASEPFX(arg_ptr, "with_out") ) { /* Disable what? */ const char *cstrptr = STRCHR(arg_ptr, '='); if(cstrptr == NULL) cstrptr = STRCHR(arg_ptr, '-'); if(cstrptr != NULL) { cstrptr++; while(ISBLANK(*cstrptr)) cstrptr++; status = PConfDisableFeature( core_ptr, platform_ptr, cstrptr ); switch(status) { case -3: if(core_ptr->warnings) { fprintf(stderr, "%s: ", cstrptr); PConfSetColor(core_ptr, stderr, PCONF_COLOR_FAILURE ); fprintf( stderr, "This feature is not allowed to be disabled.\n" ); } break; case -2: if(core_ptr->warnings) { fprintf(stderr, "%s: ", cstrptr); PConfSetColor(core_ptr, stderr, PCONF_COLOR_WARNING ); fprintf( stderr, "No such feature to disable.\n" ); } break; case -1: fprintf(stderr, "%s: ", cstrptr); PConfSetColor(core_ptr, stderr, PCONF_COLOR_FAILURE ); fprintf( stderr, "Error encountered while attempting to disable feature.\n" ); break; } PConfSetColor(core_ptr, stderr, PCONF_COLOR_DEFAULT ); } else { if(core_ptr->warnings) fprintf( stderr, "--%s: Argument must have a value separated by a '=' or '-' character.\n", arg_ptr ); } } /* Platform PREFIX? */ else if(STRCASEPFX(arg_ptr, "PREFIX") || STRCASEPFX(arg_ptr, "PlatformPREFIX") ) { const char *cstrptr = STRCHR(arg_ptr, '='); if(cstrptr != NULL) { cstrptr++; while(ISBLANK(*cstrptr)) cstrptr++; FREE(platform_ptr->prefix); platform_ptr->prefix = STRDUP(cstrptr); } else { if(core_ptr->warnings) fprintf( stderr, "--%s: Argument must have a value separated by a '='.\n", arg_ptr ); } } /* Platform CFLAGS? */ else if(STRCASEPFX(arg_ptr, "CFLAGS") || STRCASEPFX(arg_ptr, "PlatformCFLAGS") ) { const char *cstrptr = STRCHR(arg_ptr, '='); if(cstrptr != NULL) { cstrptr++; while(ISBLANK(*cstrptr)) cstrptr++; FREE(platform_ptr->cflags); platform_ptr->cflags = STRDUP(cstrptr); } else { if(core_ptr->warnings) fprintf( stderr, "--%s: Argument must have a value separated by a '='.\n", arg_ptr ); } } /* Platform INC_DIRS? */ else if(STRCASEPFX(arg_ptr, "INC_DIRS") || STRCASEPFX(arg_ptr, "PlatformINC_DIRS") || STRCASEPFX(arg_ptr, "INCDIRS") || STRCASEPFX(arg_ptr, "PlatformINCDIRS") || STRCASEPFX(arg_ptr, "INC_DIR") || STRCASEPFX(arg_ptr, "PlatformINC_DIR") || STRCASEPFX(arg_ptr, "INCDIR") || STRCASEPFX(arg_ptr, "PlatformINCDIR") ) { const char *cstrptr = STRCHR(arg_ptr, '='); if(cstrptr != NULL) { cstrptr++; while(ISBLANK(*cstrptr)) cstrptr++; FREE(platform_ptr->inc_dirs); platform_ptr->inc_dirs = STRDUP(cstrptr); } else { if(core_ptr->warnings) fprintf( stderr, "--%s: Argument must have a value separated by a '='.\n", arg_ptr ); } } /* Platform LIBS? */ else if(STRCASEPFX(arg_ptr, "LIBS") || STRCASEPFX(arg_ptr, "PlatformLIBS") ) { const char *cstrptr = STRCHR(arg_ptr, '='); if(cstrptr != NULL) { cstrptr++; while(ISBLANK(*cstrptr)) cstrptr++; FREE(platform_ptr->libs); platform_ptr->libs = STRDUP(cstrptr); } else { if(core_ptr->warnings) fprintf( stderr, "--%s: Argument must have a value separated by a '='.\n", arg_ptr ); } } /* Platform LIB_DIRS? */ else if(STRCASEPFX(arg_ptr, "LIB_DIRS") || STRCASEPFX(arg_ptr, "PlatformLIB_DIRS") || STRCASEPFX(arg_ptr, "LIBDIRS") || STRCASEPFX(arg_ptr, "PlatformLIBDIRS") || STRCASEPFX(arg_ptr, "LIB_DIR") || STRCASEPFX(arg_ptr, "PlatformLIB_DIR") || STRCASEPFX(arg_ptr, "LIBDIR") || STRCASEPFX(arg_ptr, "PlatformLIBDIR") ) { const char *cstrptr = STRCHR(arg_ptr, '='); if(cstrptr != NULL) { cstrptr++; while(ISBLANK(*cstrptr)) cstrptr++; FREE(platform_ptr->lib_dirs); platform_ptr->lib_dirs = STRDUP(cstrptr); } else { if(core_ptr->warnings) fprintf( stderr, "--%s: Argument must have a value separated by a '='.\n", arg_ptr ); } } } return; } /* * Opens the file for reading and returns the number of occurances of * s found in the file. File must be a regular file. */ static int PConfScanFileString( const char *filename, const char *s ) { int c, matches = 0; FILE *fp; if((filename == NULL) || (s == NULL)) return(matches); if((*s) == '\0') return(matches); fp = FOPEN(filename, "rb"); if(fp == NULL) return(matches); do { c = FGETC(fp); if(c == EOF) break; /* Got start of matching string? */ if(c == (*s)) { /* Get next character and match string position. */ const char *sp = s + 1; c = FGETC(fp); /* Itterate sp. */ while((*sp) != '\0') { if(((*sp) != c) || (c == EOF)) break; sp++; c = FGETC(fp); } /* Got a match if sp itterated to end. */ if((*sp) == '\0') matches++; } } while(1); FCLOSE(fp); return(matches); } /* * Itterates through a list of paths on the given platform * structure and matches each one with the given path. * * Type specifies the depend type, one of PCONF_DEP_TYPE_*. * * On success, returns a dynamically allocated full path with * must be deallocated by the calling function. Can return NULL on * error. */ static char *PConfDependMatchFile( platform_struct *platform_ptr, int type, const char *path, struct stat *stat_buf ) { int i, len1, len2; char *base_path, *new_path; char **path_list = NULL; int total_paths = 0; if((platform_ptr == NULL) || (path == NULL)) return(NULL); switch(type) { case PCONF_DEP_TYPE_PROGRAM: path_list = platform_ptr->path_program; total_paths = platform_ptr->total_path_programs; break; case PCONF_DEP_TYPE_HEADER: path_list = platform_ptr->path_header; total_paths = platform_ptr->total_path_headers; break; case PCONF_DEP_TYPE_LIBRARY: path_list = platform_ptr->path_library; total_paths = platform_ptr->total_path_libraries; break; case PCONF_DEP_TYPE_CONFIG: path_list = platform_ptr->path_config; total_paths = platform_ptr->total_path_configs; break; case PCONF_DEP_TYPE_OS: case PCONF_DEP_TYPE_MACHINE: /* Should not call this function for checking these * dependencies. */ fprintf( stderr, "PConfDependMatchFile(): Internal error, dependency is not looking for a file.\n" ); return(NULL); break; default: /* PCONF_DEP_TYPE_DATA or PCONF_DEP_TYPE_OTHER. */ path_list = platform_ptr->path_data; total_paths = platform_ptr->total_path_datas; break; } /* Empty path list? */ if((path_list == NULL) || (total_paths < 1)) return(NULL); /* Itterate through search paths. */ new_path = NULL; len2 = STRLEN(path); for(i = 0; i < total_paths; i++) { base_path = path_list[i]; if(base_path == NULL) continue; /* Deallocate previous new path and get new one. */ FREE(new_path); new_path = NULL; /* Prefix paths and allocate new path. */ len1 = STRLEN(base_path); new_path = (char *)malloc((len1 + len2 + 10) * sizeof(char)); if(new_path != NULL) { if((len1 > 0) ? (base_path[len1 - 1] != DIR_DELIMINATOR) : 1 ) sprintf(new_path, "%s%c%s", base_path, DIR_DELIMINATOR, path ); else sprintf(new_path, "%s%s", base_path, path ); /* Exists? */ if(!stat(new_path, stat_buf)) return(new_path); } } /* Deallocate failed matched new path. */ FREE(new_path); new_path = NULL; return(NULL); } /* * Checks dependency on the given depend structure. * * Returns false on failure and true on success. */ static int PConfDependCheck( pconf_core_struct *core_ptr, platform_struct *platform_ptr, depend_struct *depend_ptr, const char *feature_name, int dep_cur, int dep_total ) { int i, found, missing_depend = 0; const char *path_ptr; char *new_path; const char *cstrptr; struct stat stat_buf; if((core_ptr == NULL) || (platform_ptr == NULL) || (depend_ptr == NULL)) return(0); if(core_ptr->verbose) printf("Feature: %s (%i of %i) Dependency: %s...\n", feature_name, dep_cur + 1, dep_total, depend_ptr->name ); else printf("Checking Dependency: %s...\n", depend_ptr->name); /* Special case handling for dependencies that do not look for * files. */ switch(depend_ptr->type) { case PCONF_DEP_TYPE_OS: /* Match operating system name. */ cstrptr = (const char *)depend_ptr->os_name; if((cstrptr == NULL) ? 1 : ((*cstrptr) == '\0')) { /* No name so impossible to match, return false. */ return(0); } else { if(core_ptr->os_name != NULL) { if(!STRCASECMP(core_ptr->os_name, cstrptr)) return(1); else return(0); } else { return(0); } } break; case PCONF_DEP_TYPE_MACHINE: /* Match machine name. */ cstrptr = (const char *)depend_ptr->machine_name; if((cstrptr == NULL) ? 1 : ((*cstrptr) == '\0')) { /* No name so impossible to match, return false. */ return(0); } else { if(core_ptr->machine_name != NULL) { if(!STRCASECMP(core_ptr->machine_name, cstrptr)) return(1); else return(0); } else { return(0); } } break; default: /* All other dependency checks, keep going. */ break; } /* Begin handling all other dependencies that look for files here. */ /* Itterate through dependency paths. */ new_path = NULL; for(i = 0; i < depend_ptr->total_paths; i++) { path_ptr = (const char *)depend_ptr->path[i]; if(path_ptr == NULL) continue; /* If we're not forcing, then stop checking dependencies * on just one failed dependency. */ if(!core_ptr->force && (missing_depend > 0)) break; /* Deallocate previous new path. */ FREE(new_path); new_path = NULL; /* Reset found marker. */ found = 0; /* Check if the path exists on this platform. */ new_path = PConfDependMatchFile( platform_ptr, depend_ptr->type, path_ptr, &stat_buf ); if(new_path != NULL) { if(core_ptr->verbose) { printf(" Scanning: %s...", new_path); fflush(stdout); } /* Is it a directory? */ #ifdef S_ISDIR if(S_ISDIR(stat_buf.st_mode)) #else if(0) #endif { /* Accept this as is even if there are * strings to be greped. */ if(core_ptr->verbose) { PConfSetColor(core_ptr, stdout, PCONF_COLOR_SUCCESS ); printf(" OK "); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); printf("(Directory)\n"); } found = 1; } /* Is it a character device? */ #ifdef S_ISCHR if(S_ISCHR(stat_buf.st_mode)) #else if(0) #endif { /* Accept this as is even if there are * strings to be greped. */ if(core_ptr->verbose) { PConfSetColor(core_ptr, stdout, PCONF_COLOR_SUCCESS ); printf(" OK "); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); printf("(Character Device)\n"); } found = 1; } /* Is it a block device? */ #ifdef S_ISBLK if(S_ISBLK(stat_buf.st_mode)) #else if(0) #endif { /* Accept this as is even if there are * strings to be greped. */ if(core_ptr->verbose) { PConfSetColor(core_ptr, stdout, PCONF_COLOR_SUCCESS ); printf(" OK "); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); printf("(Block Device)\n"); } found = 1; } /* Is it a FIFO pipe? */ #ifdef S_ISFIFO if(S_ISFIFO(stat_buf.st_mode)) #else if(0) #endif { /* Accept this as is even if there are * strings to be greped. */ if(core_ptr->verbose) { PConfSetColor(core_ptr, stdout, PCONF_COLOR_SUCCESS ); printf(" OK "); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); printf("(FIFO Pipe)\n"); } found = 1; } /* Is it a socket? */ #ifdef S_ISSOCK if(S_ISSOCK(stat_buf.st_mode)) #else if(0) #endif { /* Accept this as is even if there are * strings to be greped. */ if(core_ptr->verbose) { PConfSetColor(core_ptr, stdout, PCONF_COLOR_SUCCESS ); printf(" OK "); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); printf("(Socket)\n"); } found = 1; } /* Is it a regular file? */ #ifdef S_ISREG if(S_ISREG(stat_buf.st_mode)) #else if(1) #endif { /* Check for corresponding string for grepping on * this dependency structure. If there is one, then * grep for it. */ if((i >= 0) && (i < depend_ptr->total_grep_strings)) { const char *grep_string = depend_ptr->grep_string[i]; /* Grep string not NULL and not empty? */ if((grep_string == NULL) ? 0 : ((*grep_string) != '\0')) { if(PConfScanFileString( new_path, grep_string ) > 0) { if(core_ptr->verbose) { PConfSetColor(core_ptr, stdout, PCONF_COLOR_SUCCESS ); printf(" OK\n"); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); } found = 1; } else { if(core_ptr->verbose) { PConfSetColor(core_ptr, stdout, PCONF_COLOR_FAILURE ); printf(" Failed\n"); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); } if(core_ptr->warnings) { PConfSetColor(core_ptr, stderr, PCONF_COLOR_DEFAULT ); fprintf(stderr, " *** "); PConfSetColor(core_ptr, stderr, PCONF_COLOR_FAILURE ); fprintf( stderr, "Could not find `%s' in file %s!", grep_string, new_path ); PConfSetColor(core_ptr, stderr, PCONF_COLOR_DEFAULT ); fprintf(stderr, " ***\n"); } } } else { /* Grep string is empty, imply always match. */ found = 1; if(core_ptr->verbose) { PConfSetColor(core_ptr, stdout, PCONF_COLOR_SUCCESS ); printf(" OK\n"); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); } } } else { /* No grep string, so imply always match. */ if(core_ptr->verbose) { PConfSetColor(core_ptr, stdout, PCONF_COLOR_SUCCESS ); printf(" OK\n"); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); } /* Mark this dependency as found. */ found = 1; } } /* Not found? */ if(!found) { /* Increment missing dependencies count. */ missing_depend++; } } else { /* Object does not exist. */ if(core_ptr->warnings) { PConfSetColor(core_ptr, stderr, PCONF_COLOR_DEFAULT ); fprintf(stderr, " *** "); PConfSetColor(core_ptr, stderr, PCONF_COLOR_WARNING ); fprintf( stderr, "Object `%s' not found in defined platform paths!", path_ptr ); PConfSetColor(core_ptr, stderr, PCONF_COLOR_DEFAULT ); fprintf(stderr, " ***\n"); } /* Increment missing dependency count. */ missing_depend++; } } /* Itterate through dependency paths. */ /* Deallocate new path just in case. */ FREE(new_path); new_path = NULL; /* All depends met? */ if(missing_depend <= 0) return(1); else return(0); } /* * Checks for dependencies on all enabled features. * * Any feature's must_exist marked as PCONF_MUST_EXIST_PREFERRED will * be set to PCONF_MUST_EXIST_YES if they exist or set to * PCONF_MUST_EXIST_NO if they do not exist. * * Returns the number of failed dependencies who's must_exist * is set to PCONF_MUST_EXIST_YES. */ int PConfCheckDepends( pconf_core_struct *core_ptr, platform_struct *platform_ptr ) { int i, failed_depends = 0; int depend_progress_ratio = 0; /* In percent. */ feature_struct *feature_ptr; if((core_ptr == NULL) || (platform_ptr == NULL)) return(failed_depends); /* Itterate through each feature. */ for(i = 0; i < platform_ptr->total_features; i++) { feature_ptr = platform_ptr->feature[i]; if(feature_ptr == NULL) continue; /* Update progress ratio. */ if(platform_ptr->total_features > 0) depend_progress_ratio = (i + 1) * 100 / platform_ptr->total_features; /* Do not want this feature? */ if(feature_ptr->must_exist == PCONF_MUST_EXIST_NO) continue; /* Would like to have this feature (preffered)? */ if(feature_ptr->must_exist == PCONF_MUST_EXIST_PREFERRED) { int n, k = 0; depend_struct *depend_ptr; /* Check if we have dependencies. */ for(n = 0; n < feature_ptr->total_depends; n++) { depend_ptr = feature_ptr->depend[n]; if(depend_ptr == NULL) continue; if(depend_ptr->must_exist == PCONF_MUST_EXIST_YES) { /* Dependency found? */ if(!PConfDependCheck( core_ptr, platform_ptr, depend_ptr, feature_ptr->name, i, platform_ptr->total_features )) { k++; /* Do not count this as a failed dependency. */ } } } /* No failed dependencies? */ if(k == 0) { if(core_ptr->warnings) { printf( " Preferred feature `%s' ", feature_ptr->name ); PConfSetColor(core_ptr, stdout, PCONF_COLOR_SUCCESS ); printf("detected and enabled"); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); printf(".\n"); } /* No failed dependencies, so mark this as enabled. */ feature_ptr->must_exist = PCONF_MUST_EXIST_YES; } else { /* Got one or more failed dependency. */ if(core_ptr->warnings) { printf(" Preferred ("); PConfSetColor(core_ptr, stdout, PCONF_COLOR_SUCCESS ); printf("not required"); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); printf(") feature `%s' ", feature_ptr->name ); PConfSetColor(core_ptr, stdout, PCONF_COLOR_WARNING ); printf("not detected and disabled"); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); printf(".\n"); } /* Got failed dependencies, so mark this as disabled. */ feature_ptr->must_exist = PCONF_MUST_EXIST_NO; } } /* Must have this feature? */ else if(feature_ptr->must_exist == PCONF_MUST_EXIST_YES) { int n, k = 0; depend_struct *depend_ptr; /* Check if we have dependencies. */ for(n = 0; n < feature_ptr->total_depends; n++) { depend_ptr = feature_ptr->depend[n]; if(depend_ptr == NULL) continue; /* If not forcing and we got one or more failed * dependencies then we should give up immediatly. */ if(!core_ptr->force && (failed_depends > 0)) break; /* Check for dependency of feature only if feature * says the dependency must exist. */ if(depend_ptr->must_exist == PCONF_MUST_EXIST_YES) { /* Dependency found? */ if(!PConfDependCheck( core_ptr, platform_ptr, depend_ptr, feature_ptr->name, i, platform_ptr->total_features )) { k++; failed_depends++; } } } /* Got more than one failed dependency? */ if(k > 0) { PConfSetColor(core_ptr, stderr, PCONF_COLOR_DEFAULT ); fprintf(stderr, " *** "); PConfSetColor(core_ptr, stderr, PCONF_COLOR_FAILURE ); fprintf( stderr, "Could not find all dependencies for required feature `%s'!", feature_ptr->name ); PConfSetColor(core_ptr, stderr, PCONF_COLOR_DEFAULT ); fprintf(stderr, " ***\n"); /* Got failed dependencies so mark this as disabled * if we are not forcing. */ if(!core_ptr->force) feature_ptr->must_exist = PCONF_MUST_EXIST_NO; /* This is a halting error, halt if not forcing. */ if(core_ptr->force) { if(core_ptr->verbose && core_ptr->warnings) fprintf( stderr, "*** Force enabled, continuing dependency check... ***\n" ); } else { break; } } } } /* Itterate through each feature. */ return(failed_depends); }