1/* 2 * Automated Testing Framework (atf) 3 * 4 * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 17 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#include <ctype.h> 31#include <stdbool.h> 32#include <stdlib.h> 33#include <string.h> 34 35#include "atf-c/config.h" 36 37#include "detail/env.h" 38#include "detail/sanity.h" 39 40static bool initialized = false; 41 42static struct var { 43 const char *name; 44 const char *default_value; 45 const char *value; 46 bool can_be_empty; 47} vars[] = { 48 { "atf_arch", ATF_ARCH, NULL, false, }, 49 { "atf_build_cc", ATF_BUILD_CC, NULL, false, }, 50 { "atf_build_cflags", ATF_BUILD_CFLAGS, NULL, true, }, 51 { "atf_build_cpp", ATF_BUILD_CPP, NULL, false, }, 52 { "atf_build_cppflags", ATF_BUILD_CPPFLAGS, NULL, true, }, 53 { "atf_build_cxx", ATF_BUILD_CXX, NULL, false, }, 54 { "atf_build_cxxflags", ATF_BUILD_CXXFLAGS, NULL, true, }, 55 { "atf_confdir", ATF_CONFDIR, NULL, false, }, 56 { "atf_includedir", ATF_INCLUDEDIR, NULL, false, }, 57 { "atf_libdir", ATF_LIBDIR, NULL, false, }, 58 { "atf_libexecdir", ATF_LIBEXECDIR, NULL, false, }, 59 { "atf_machine", ATF_MACHINE, NULL, false, }, 60 { "atf_pkgdatadir", ATF_PKGDATADIR, NULL, false, }, 61 { "atf_shell", ATF_SHELL, NULL, false, }, 62 { "atf_workdir", ATF_WORKDIR, NULL, false, }, 63 { NULL, NULL, NULL, false, }, 64}; 65 66/* Only used for unit testing, so this prototype is private. */ 67void __atf_config_reinit(void); 68 69/* --------------------------------------------------------------------- 70 * Auxiliary functions. 71 * --------------------------------------------------------------------- */ 72 73static 74char * 75string_to_upper(const char *str) 76{ 77 char *uc; 78 79 uc = (char *)malloc(strlen(str) + 1); 80 if (uc != NULL) { 81 char *ucptr = uc; 82 while (*str != '\0') { 83 *ucptr = toupper((int)*str); 84 85 str++; 86 ucptr++; 87 } 88 *ucptr = '\0'; 89 } 90 91 return uc; 92} 93 94static 95void 96initialize_var(struct var *var, const char *envname) 97{ 98 PRE(var->value == NULL); 99 100 if (atf_env_has(envname)) { 101 const char *val = atf_env_get(envname); 102 if (strlen(val) > 0 || var->can_be_empty) 103 var->value = val; 104 else 105 var->value = var->default_value; 106 } else 107 var->value = var->default_value; 108 109 POST(var->value != NULL); 110} 111 112static 113void 114initialize(void) 115{ 116 struct var *var; 117 118 PRE(!initialized); 119 120 for (var = vars; var->name != NULL; var++) { 121 char *envname; 122 123 envname = string_to_upper(var->name); 124 initialize_var(var, envname); 125 free(envname); 126 } 127 128 initialized = true; 129} 130 131/* --------------------------------------------------------------------- 132 * Free functions. 133 * --------------------------------------------------------------------- */ 134 135const char * 136atf_config_get(const char *name) 137{ 138 const struct var *var; 139 const char *value; 140 141 if (!initialized) { 142 initialize(); 143 INV(initialized); 144 } 145 146 value = NULL; 147 for (var = vars; value == NULL && var->name != NULL; var++) 148 if (strcmp(var->name, name) == 0) 149 value = var->value; 150 INV(value != NULL); 151 152 return value; 153} 154 155void 156__atf_config_reinit(void) 157{ 158 struct var *var; 159 160 initialized = false; 161 162 for (var = vars; var->name != NULL; var++) 163 var->value = NULL; 164} 165