removed some dead code, remove_symbol() can remove i-th symbol, not only last one

This commit is contained in:
schippes 2020-08-10 09:16:11 +02:00
parent a6113f0072
commit 8383bb0e39
231 changed files with 20 additions and 30602 deletions

View File

@ -1 +0,0 @@
12

View File

@ -1 +0,0 @@
12

View File

@ -1,194 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include "log.h"
#include "libs.h"
#include "db.h"
#include "dep.h"
#include "regex.h"
static void zap(char **str)
{
const char *pat = get("/arg/sys/pkg-config-zap");
char *n;
if (pat == NULL)
return;
if (re_comp(pat) != NULL)
return;
while (re_exec(*str)) {
n = re_subs_dup("");
free(*str);
*str = n;
}
}
int run_gen_config(int logdepth, const char *confname, const char *pkgname, char **cflags, char **ldflags)
{
char cmd[256];
if (strlen(confname) + strlen(pkgname) > sizeof(cmd) - 16) {
logprintf(logdepth, "run_gen_config(): confname and/or pkgname too long\n");
return -1;
}
if (cflags != NULL) {
sprintf(cmd, "%s --cflags %s", confname, pkgname);
if (run(logdepth, cmd, cflags) != 0) {
report("not found: %s --cflags failed.", confname);
logprintf(logdepth, "not found: %s --cflags failed.\n", confname);
return -1;
}
if (*cflags != NULL) {
zap(cflags);
strip(*cflags);
}
}
if (ldflags != NULL) {
sprintf(cmd, "%s --libs %s", confname, pkgname);
if (run(logdepth, cmd, ldflags) != 0) {
report("not found: %s --libs failed.", confname);
logprintf(logdepth, "not found: %s --libs failed.\n", confname);
if (cflags != NULL)
free(*cflags);
return -1;
}
if (*ldflags != NULL) {
zap(ldflags);
strip(*ldflags);
}
}
return 0;
}
const char *pkg_config_name()
{
const char *name;
name = get("/arg/sys/pkg-config");
if (name != NULL)
return name;
return "pkg-config"; /* fallback */
}
/** run_pkg_config_modversion:
run `pkg-config` on @pkgname:
- with `--modversion` if @modversion is not NULL, storing the result in @modversion (malloc()'d)
Returns 0 on success.
*/
int run_pkg_config_modversion(int logdepth, const char *pkgname, char **modversion)
{
char cmd[256];
const char *confname = pkg_config_name();
if (strlen(confname) + strlen(pkgname) > sizeof(cmd) - 16) {
logprintf(logdepth, "run_pkg_config_modversion(): confname and/or pkgname too long\n");
return -1;
}
if (modversion != NULL) {
sprintf(cmd, "%s --modversion %s", confname, pkgname);
if (run(logdepth, cmd, modversion) != 0) {
/*report("Module version not found: %s --modversion %s failed.", confname, pkgname);
logprintf(logdepth, "Module version not found: %s --modversion %s failed.\n", confname, pkgname); */
return -1;
}
zap(modversion);
strip(*modversion);
}
return 0;
}
/** run_pkg_config_modversion_db:
run `pkg-config --modversion` on @pkgname to find module (or package) version
and store the result in @node/modversion
Returns 0 on success.
*/
int run_pkg_config_modversion_db(int logdepth, const char *node, const char *pkgname /*, char **modversion */ )
{
char *modversion;
char *tmp;
if (run_pkg_config_modversion(logdepth, pkgname, &modversion) != 0) {
return -1;
}
/* Store the module version in node */
tmp = str_concat("/", node, "modversion", NULL);
put(tmp, modversion);
free(tmp);
free(modversion);
return 0;
}
int run_pkg_config(int logdepth, const char *pkgname, char **cflags, char **ldflags)
{
return run_gen_config(logdepth, pkg_config_name(), pkgname, cflags, ldflags);
}
void run_pkg_config_lst(int logdepth, const char *pkgpat, int *argc, char ***argv)
{
char *end, *s, *next;
int n = 0, a = 0;
char **sf = NULL;
static const char *pkg_cfg_cache = NULL;
static char no_pkg_cfg;
char *list;
if (pkg_cfg_cache == &no_pkg_cfg)
goto error;
if (pkg_cfg_cache == NULL) {
char *cmd = str_concat(" ", pkg_config_name(), "--list-all", NULL);
run(logdepth, cmd, (char **) &pkg_cfg_cache);
free(cmd);
if (pkg_cfg_cache == NULL) {
pkg_cfg_cache = &no_pkg_cfg;
goto error;
}
}
if (re_comp(pkgpat) != NULL)
goto error;
s = list = strclone(pkg_cfg_cache);
for (;;) {
while (isspace(*s))
s++;
if (*s == '\0')
break;
next = strpbrk(s, "\r\n");
if (next != NULL)
*next = '\0';
if (re_exec(s)) {
if ((n + 2) >= a) { /* n+2: make sure there's always room for the NULL at the end */
a += 16;
sf = realloc(sf, sizeof(char *) * a);
}
end = strpbrk(s, " \t");
if (end != NULL)
*end = '\0';
sf[n] = strclone(s);
sf[n + 1] = re_subs_dup("");
/* report("\ns='%s' sf='%s'\n", s, sf[n]);*/
n += 2;
}
s = next + 1;
}
if (sf != NULL)
sf[n] = NULL;
free(list);
error:;
*argc = n;
*argv = sf;
return;
}

View File

@ -1,106 +0,0 @@
/*
scconfig - command line argument processing
Copyright (C) 2009..2012 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <string.h>
#include "db.h"
#include "arg.h"
#include "dep.h"
#include "log.h"
#include "libs.h"
argtbl_t main_argument_table[] = {
{"import", NULL, import_args, "Import saved config (sub)tree"},
{"target", "/arg/sys/target", NULL, "set cross compilation target (prefix)"},
{"target-name", "/arg/sys/target-name", NULL, "set cross compilation target (system name)"},
{"target-shell","/arg/sys/target-shell",NULL, "set the shell on cross compilation target"},
{"emu", "/arg/sys/emu", NULL, "emulator for testing cross compiled executables with"},
{"pkg-config", "/arg/sys/pkg-config", NULL, "path to pkg-config to use"},
{"pkg-config-zap","/arg/sys/pkg-config-zap",NULL, "ignore pkg-config results by this regex pattern"},
/* wildcard rules for icl() control */
{"^ldflags/", NULL, import_icl, NULL},
{"^cflags/", NULL, import_icl, NULL},
{"^includes/", NULL, import_icl, NULL},
{"^prefix/", NULL, import_icl, NULL},
/* the followings are autoconf compatibility translations */
{"CC", "/arg/cc/cc", NULL, "Force using a C compiler (command line)"},
{"CFLAGS", "/arg/cc/cflags", NULL, "Force using a CFLAGS for C compilation"},
{"LDFLAGS", "/arg/cc/ldflags", NULL, "Force using a LDFLAGS for linking"},
{"LDL", "/arg/libs/ldl", NULL, "Force using -ldl string"},
{"gpmi-prefix", "/arg/gpmi/prefix", NULL, NULL},
{NULL, NULL, NULL, NULL}
};
void process_args(int argc, char *argv[])
{
int n;
char *key, *value;
argtbl_t *a;
int found, tainted = 0;
db_mkdir("/arg");
logprintf(0, "CLI arg 0: '%s'\n", argv[0]);
for(n = 1; n < argc; n++) {
key = argv[n];
logprintf(0, "CLI arg %d: '%s'\n", n, key);
while(*key == '-') key++;
value = str_chr(key, '=');
found = 0;
if (value != NULL) {
*value = '\0';
value++;
/* Look in the argument translate table */
for(a = main_argument_table; a->arg != NULL; a++) {
if (((a->arg[0] == '^') && (strncmp(a->arg+1, key, strlen(a->arg+1)) == 0)) || (strcmp(a->arg, key) == 0)) {
found = 1;
if (a->callback != NULL) {
if (a->callback(key, value) != 0) {
error("Processing argument '%s' failed in the callback\n", argv[n]);
abort();
}
}
if (a->path != NULL)
put(a->path, value);
}
}
/* Look in known deps table or /arg */
if (found == 0) {
if ((is_dep_known(key)) || (strncmp(key, "/arg/", 5) == 0)) {
put(key, value);
found = 1;
}
}
}
if (found == 0) {
if (custom_arg(key, value) == 0) {
error("Unknown argument '%s'\n", key);
tainted++;
}
}
}
if (tainted)
exit(1);
}

View File

@ -1,122 +0,0 @@
/*
scconfig - detection of standard library features: strings
Copyright (C) 2017 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
int find_strcasecmp(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <string.h>"
NL "#include <stdio.h>"
NL "int main() {"
NL " if ((strcasecmp(\"foo\", \"FoO\") == 0) && (strcasecmp(\"foo\", \"bar\") != 0))"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for strcasecmp()... ");
logprintf(logdepth, "find_fs_strcasecmp: trying to find strcasecmp...\n");
logdepth++;
if (try_icl(logdepth, "str/strcasecmp", test_c, NULL, NULL, NULL)) return 0;
return try_fail(logdepth, "str/strcasecmp");
}
int find_strncasecmp(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <string.h>"
NL "#include <stdio.h>"
NL "int main() {"
NL " if ((strncasecmp(\"foo1\", \"FoO2\", 3) == 0) && (strncasecmp(\"foo1\", \"bar2\", 3) != 0))"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for strncasecmp()... ");
logprintf(logdepth, "find_fs_strncasecmp: trying to find strncasecmp...\n");
logdepth++;
if (try_icl(logdepth, "str/strncasecmp", test_c, NULL, NULL, NULL)) return 0;
return try_fail(logdepth, "str/strncasecmp");
}
int find_stricmp(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <string.h>"
NL "#include <stdio.h>"
NL "int main() {"
NL " if ((stricmp(\"foo\", \"FoO\") == 0) && (stricmp(\"foo\", \"bar\") != 0))"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for stricmp()... ");
logprintf(logdepth, "find_fs_stricmp: trying to find stricmp...\n");
logdepth++;
if (try_icl(logdepth, "str/stricmp", test_c, NULL, NULL, NULL)) return 0;
return try_fail(logdepth, "str/stricmp");
}
int find_strnicmp(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <string.h>"
NL "#include <stdio.h>"
NL "int main() {"
NL " if ((strnicmp(\"foo1\", \"FoO2\", 3) == 0) && (strnicmp(\"foo1\", \"bar2\", 3) != 0))"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for strnicmp()... ");
logprintf(logdepth, "find_fs_strnicmp: trying to find strnicmp...\n");
logdepth++;
if (try_icl(logdepth, "str/strnicmp", test_c, NULL, NULL, NULL)) return 0;
return try_fail(logdepth, "str/strnicmp");
}

View File

@ -1,203 +0,0 @@
/*
scconfig - detection of standard library features
Copyright (C) 2009 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
static int trydlc(int logdepth, const char *test_c_dlc, const char *cflagsf, const char *ldflagsf, const char *dlc)
{
char *cflags, *ldflags;
cflags = malloc(strlen(dlc) + 64);
ldflags = malloc(strlen(dlc)*2 + 256);
sprintf(cflags, cflagsf, dlc);
sprintf(ldflags, ldflagsf, dlc, dlc);
if (try_icl(logdepth, NULL, test_c_dlc, NULL, cflags, ldflags)) {
*cflags = ' ';
append("cc/cflags", cflags);
put("libs/ldl", ldflags);
put("libs/dl-compat", strue);
report("OK (%s and %s)\n", cflags, ldflags);
free(cflags);
free(ldflags);
return 1;
}
free(cflags);
free(ldflags);
return 0;
}
int find_lib_ldl(const char *name, int logdepth, int fatal)
{
const char *ldl, *dlc;
char *s;
char *test_c =
NL "#include <stdio.h>"
NL "#include <dlfcn.h>"
NL "int main() {"
NL " void *handle;"
NL " handle = dlopen(\"/this file does not exist.\", RTLD_NOW);"
NL " if (handle == NULL) printf(\"OK\\n\");"
NL " return 0;"
NL "}"
NL;
char *test_c_dlc =
NL "#include <stdio.h>"
NL "#include <dl-compat.h>"
NL "int main() {"
NL " void *handle;"
NL " handle = dlopen(\"/this file does not exist.\", RTLD_NOW);"
NL " if (handle == NULL) printf(\"OK\\n\");"
NL " return 0;"
NL "}"
NL;
s = get("libs/ldl/presents");
if (s != NULL)
return !istrue(s);
require("cc/cc", logdepth, fatal);
report("Checking for -ldl... ");
logprintf(logdepth, "find_lib_ldl: trying to find ldl...\n");
logdepth++;
ldl = get("/arg/libs/ldl");
if (ldl == NULL) {
dlc = get("/arg/libs/dl-compat");
if (dlc == NULL) {
/* If dlc is not explicitly requested by the user, try standard
dl (see whether we need -ldl for dlopen()) */
if (try_icl(logdepth, NULL, test_c, NULL, NULL, NULL)) {
put("libs/ldl", "");
put("libs/ldl/includes", "#include <dlfcn.h>\\n");
put("libs/ldl/presents", strue);
report("OK ()\n");
return 0;
}
if (try_icl(logdepth, NULL, test_c, NULL, NULL, "-ldl")) {
put("libs/ldl", "-ldl");
put("libs/ldl/includes", "#include <dlfcn.h>\\n");
put("libs/ldl/presents", strue);
report("OK (-ldl)\n");
return 0;
}
}
/* try dl-compat (dl compatibility lib) */
if (dlc != NULL) {
/* test at user supplied dlc prefix:
- first assume the linker will find it
- next assume gcc and pass rpath to the linker
- finally try static linking */
if (trydlc(logdepth, test_c_dlc, "-I%s/include", "-L%s/lib -ldl-compat\000%s", dlc)) {
put("libs/ldl/includes", "#include <dl-compat.h>\\n");
return 0;
}
if (trydlc(logdepth, test_c_dlc, "-I%s/include", "-L%s/lib -Wl,-rpath=%s/lib -ldl-compat", dlc)) {
put("libs/ldl/includes", "#include <dl-compat.h>\\n");
return 0;
}
if (trydlc(logdepth, test_c_dlc, "-I%s/include", "%s/lib/libdl-compat.a\000%s", dlc)) {
put("libs/ldl/includes", "#include <dl-compat.h>\\n");
return 0;
}
}
else if (try_icl(logdepth, NULL, test_c_dlc, NULL, NULL, "-ldl-compat")) {
/* check at normal system installation */
put("libs/ldl", "-ldl-compat");
put("libs/ldl/includes", "#include <dl-compat.h>\\n");
put("libs/ldl/presents", strue);
report("OK (-ldl-compat)\n");
return 0;
}
}
else {
report("User provided... ");
s = strclone(ldl);
if (try_icl(logdepth, NULL, test_c, NULL, NULL, s)) {
put("libs/ldl", ldl);
put("libs/ldl/includes", "#include <dlfcn.h>\\n");
put("libs/ldl/presents", strue);
report("OK (%s)\n", ldl);
free(s);
return 0;
}
free(s);
}
put("libs/ldl/presents", sfalse);
report("Not found\n");
return 1;
}
int find_lib_LoadLibrary(const char *name, int logdepth, int fatal)
{
/*char *s;*/
char *test_c =
NL "#include <stdio.h>"
NL "int main() {"
NL " void *handle;"
NL " handle = LoadLibrary(\"/this file does not exist.\");"
NL " if (handle == NULL) printf(\"OK\\n\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for LoadLibrary... ");
logprintf(logdepth, "find_lib_LoadLibrary: trying to find LoadLibrary...\n");
logdepth++;
if (try_icl(logdepth, "libs/LoadLibrary", test_c, "#include <windows.h>", NULL, NULL))
return 0;
return try_fail(logdepth, "libs/LoadLibrary");
}
int find_lib_errno(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <errno.h>"
NL "int main() {"
NL " errno = 0;"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL ;
require("cc/cc", logdepth, fatal);
report("Checking for errno.h... ");
logprintf(logdepth, "find_lib_errno: trying to find errno...\n");
logdepth++;
if (try_icl(logdepth, "libs/errno", test_c, NULL, NULL, NULL)) return 0;
return try_fail(logdepth, "libs/errno");
}

View File

@ -1,6 +0,0 @@
#define MAX_CUSTOM_REQS 32
extern char *custom_reqs[MAX_CUSTOM_REQS];
extern int num_custom_reqs;
int custom_arg(const char *key, const char *value);

View File

@ -1,837 +0,0 @@
/*
scconfig - detection of standard library features: file system specific calls
Copyright (C) 2010 Tibor Palinkas
Copyright (C) 2018 Aron Barath
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
int find_fs_realpath(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <limits.h>"
NL "#include <stdlib.h>"
NL "#include <stdio.h>"
NL "#ifdef PATH_MAX"
NL "char out_buf[PATH_MAX];"
NL "#else"
NL "char out_buf[32768];"
NL "#endif"
NL "int main() {"
NL " if (realpath(\".\", out_buf) == out_buf)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for realpath()... ");
logprintf(logdepth, "find_fs_realpath: trying to find realpath...\n");
logdepth++;
if (try_icl(logdepth, "libs/fs/realpath", test_c, NULL, NULL, NULL)) return 0;
if (try_icl(logdepth, "libs/fs/realpath", test_c, "#define _DEFAULT_SOURCE", NULL, NULL)) return 0;
if (try_icl(logdepth, "libs/fs/realpath", test_c, "#define _BSD_SOURCE", NULL, NULL)) return 0;
return try_fail(logdepth, "libs/fs/realpath");
}
int find_fs__fullpath(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <stdio.h>"
NL "#include <conio.h>"
NL "#include <stdlib.h>"
NL "#include <direct.h>"
NL "int main() {"
NL " char full[_MAX_PATH];"
NL " if (_fullpath(full, \".\", _MAX_PATH) != NULL)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for _fullpath()... ");
logprintf(logdepth, "find_fs__fullpath: trying to find _fullpath...\n");
logdepth++;
if (try_icl(logdepth, "libs/fs/_fullpath", test_c, NULL, NULL, NULL)) return 0;
return try_fail(logdepth, "libs/fs/_fullpath");
}
int find_fs_readdir(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <stdlib.h>"
NL "#include <stdio.h>"
NL "int main() {"
NL " DIR *dirp;"
NL " struct dirent *dp;"
NL " int found = 0;"
NL " if ((dirp = opendir(\".\")) == 0)"
NL " return -1;"
NL " while ((dp = readdir(dirp)) != 0)"
NL " if (strcmp(dp->d_name, \"configure\") == 0)"
NL " found++;"
NL " closedir(dirp);"
NL " if (found == 1)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
char *includes[] = {
"#include <dirent.h>",
"#include <sys/dir.h>", /* 4.2BSD */
NULL
};
char **i;
require("cc/cc", logdepth, fatal);
report("Checking for readdir()... ");
logprintf(logdepth, "find_fs_readdir: trying to find readdir...\n");
logdepth++;
for (i = includes; *i != NULL; i++)
if (try_icl(logdepth, "libs/fs/readdir", test_c, *i, NULL, NULL))
return 0;
return try_fail(logdepth, "libs/fs/readdir");
}
int find_fs_findnextfile(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <stdlib.h>"
NL "#include <stdio.h>"
NL "#include <windows.h>"
NL "int main(int argc, char *argv[]) {"
NL " WIN32_FIND_DATA fd;"
NL " HANDLE h;"
NL " int found=0;"
NL " h = FindFirstFile(argv[0], &fd);"
NL " if (h == INVALID_HANDLE_VALUE)"
NL " return -1;"
NL " while (FindNextFile(h, &fd) != 0);"
NL " found++;"
NL " FindClose(h);"
NL " if (found > 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for FindNextFile()... ");
logprintf(logdepth, "find_fs_findnextfile: trying to find FindNextFile...\n");
logdepth++;
if (try_icl(logdepth, "libs/fs/findnextfile", test_c, NULL, NULL, NULL)) return 0;
return try_fail(logdepth, "libs/fs/findnextfile");
}
int find_fs_access(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "int my_test() { return access(\".\", 0); }"
NL "#include <stdio.h>"
NL "int main() {"
NL " if (my_test() == 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char* includes[] = { "#include <unistd.h>", "#include <stdlib.h>\n#include <direct.h>", "#include <stdlib.h>", NULL };
const char** inc;
require("cc/cc", logdepth, fatal);
report("Checking for access()... ");
logprintf(logdepth, "find_fs_access: trying to find access...\n");
logdepth++;
for (inc=includes; *inc; ++inc)
if (try_icl(logdepth, "libs/fs/access", test_c, *inc, NULL, NULL)) return 0;
return try_fail(logdepth, "libs/fs/access");
}
int find_fs_access_macros(const char *rname, int logdepth, int fatal)
{
char *test_c_templ =
NL "%s"
NL "void my_test() { int a = %s; }"
NL "#include <stdio.h>"
NL "int main() {"
NL " my_test();"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
char test_c[256];
char *names[][3] = {
{"F_OK", "F_OK", NULL},
{"R_OK", "R_OK", NULL},
{"W_OK", "W_OK", NULL},
{"X_OK", "X_OK", NULL},
{NULL, NULL, NULL}
};
char **n;
const char* access_includes;
int name, pr;
char nodename[128];
require("cc/cc", logdepth, fatal);
if (require("libs/fs/access/*", logdepth, fatal)!=0 ||
!istrue(get("libs/fs/access/presents"))) {
put("libs/fs/access/macros/presents", sfalse);
return 1;
}
access_includes = get("libs/fs/access/includes");
report("Checking for access macros:\n");
logprintf(logdepth, "find_fs_access_macros: trying to find access macros...\n");
logdepth++;
pr = 0;
for(name = 0; *names[name] != NULL; name++) {
report(" %s...\t", names[name][0]);
for(n = &names[name][0]; *n != NULL; n++) {
sprintf(test_c, test_c_templ, access_includes, *n);
if (try_icl(logdepth, NULL, test_c, NULL, NULL, NULL)) {
sprintf(nodename, "libs/fs/access/macros/%s", names[name][0]);
put(nodename, *n);
report("found as %s\n", *n);
pr++;
goto found;
}
}
report("not found\n");
found:;
}
put("libs/fs/access/macros/presents", ((pr > 0) ? (strue) : (sfalse)));
return (pr == 0);
}
int find_fs_stat_macros(const char *rname, int logdepth, int fatal)
{
char *test_c_templ =
NL "#include <sys/stat.h>"
NL "#include <sys/types.h>"
NL "void my_test() { int a = %s(0); }"
NL "#include <stdio.h>"
NL "int main() {"
NL " my_test();"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
char test_c[256];
char *names[][3] = {
{"S_ISREG", "S_IFREG", NULL},
{"S_ISDIR", "S_IFDIR", NULL},
{"S_ISCHR", "S_IFCHR", NULL},
{"S_ISBLK", "S_IFBLK", NULL},
{"S_ISFIFO", "S_IFFIFO", NULL},
{"S_ISLNK", "S_IFLNK", NULL},
{"S_ISCHR", "S_IFCHR", NULL},
{"S_ISSOCK", "S_IFSOCK", NULL},
{NULL, NULL, NULL}
};
char **n;
int name, pr;
char nodename[128];
require("cc/cc", logdepth, fatal);
report("Checking for stat macros:\n");
logprintf(logdepth, "find_fs_stat_macros: trying to find stat macros...\n");
logdepth++;
pr = 0;
for(name = 0; *names[name] != NULL; name++) {
report(" %s...\t", names[name][0]);
for(n = &names[name][0]; *n != NULL; n++) {
sprintf(test_c, test_c_templ, *n);
if (try_icl(logdepth, NULL, test_c, NULL, NULL, NULL)) {
sprintf(nodename, "libs/fs/stat/macros/%s", names[name][0]);
put(nodename, *n);
report("found as %s\n", *n);
pr++;
goto found;
}
}
report("not found\n");
found:;
}
put("libs/fs/stat/macros/presents", ((pr > 0) ? (strue) : (sfalse)));
return (pr == 0);
}
int find_fs_stat_fields(const char *rname, int logdepth, int fatal)
{
char *test_c_templ =
NL "#include <sys/stat.h>"
NL "#include <sys/types.h>"
NL "#include <stdio.h>"
NL "int main() {"
NL " struct stat st;"
NL " (void)st.%s;"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
char test_c[256];
char *names[] = {"st_blksize", "st_blocks", "st_rdev", "st_mtim", "st_mtime", "st_birthtim", "st_birthtime", NULL };
int name, pr;
char nodename[128];
require("cc/cc", logdepth, fatal);
report("Checking for stat macros:\n");
logprintf(logdepth, "find_fs_stat_fields: trying to find stat macros...\n");
logdepth++;
pr = 0;
for(name = 0; names[name] != NULL; name++) {
report(" %s...\t", names[name]);
sprintf(test_c, test_c_templ, names[name]);
sprintf(nodename, "libs/fs/stat/fields/%s/presents", names[name]);
if (try_icl(logdepth, NULL, test_c, NULL, NULL, NULL)) {
put(nodename, strue);
report("found\n");
pr++;
}
else {
report("not found\n");
put(nodename, sfalse);
}
}
return (pr == 0);
}
static int find_fs_any_lstat(const char *name, int logdepth, int fatal, char *fn)
{
/* make sure <stdio.h> does not affect our lstat() detection */
const char *test_c_in =
NL "void my_puts(const char *s);"
NL "int main() {"
NL " struct stat buf;"
NL " if (%s(\".\", &buf) == 0)"
NL " my_puts(\"OK\");"
NL " return 0;"
NL "}"
NL "#include <stdio.h>"
NL "void my_puts(const char *s)"
NL "{"
NL " puts(s);"
NL "}"
NL;
char test_c[384], node[64];
const char *incs[] = {"#include <sys/stat.h>", "#include <unistd.h>", "#include <sys/types.h>\n#include <sys/stat.h>\n#include <unistd.h>", NULL};
const char **inc;
require("cc/cc", logdepth, fatal);
sprintf(node, "libs/fs/%s", fn);
sprintf(test_c, test_c_in, fn);
report("Checking for %s... ", fn);
logprintf(logdepth, "find_fs_%s: trying to find lstat()...\n", fn);
logdepth++;
for (inc = incs; *inc; ++inc) {
if (try_icl(logdepth, node, test_c, *inc, NULL, NULL))
return 0;
}
return try_fail(logdepth, node);
}
int find_fs_lstat(const char *name, int logdepth, int fatal)
{
return find_fs_any_lstat(name, logdepth, fatal, "lstat");
}
int find_fs_statlstat(const char *name, int logdepth, int fatal)
{
return find_fs_any_lstat(name, logdepth, fatal, "statlstat");
}
int find_fs_getcwd(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <unistd.h>"
NL "int main() {"
NL " char b[1024];"
NL " if (getcwd(b, sizeof(b)) != NULL)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for getcwd... ");
logprintf(logdepth, "find_fs_getcwd: trying to find getcwd()...\n");
logdepth++;
if (try_icl(logdepth, "libs/fs/getcwd", test_c, NULL, NULL, NULL)) return 0;
return try_fail(logdepth, "libs/fs/getcwd");
}
int find_fs__getcwd(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <stdlib.h>"
NL "int main() {"
NL " char b[1024];"
NL " if (_getcwd(b, sizeof(b)) != NULL)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for _getcwd... ");
logprintf(logdepth, "find_fs__getcwd: trying to find _getcwd()...\n");
logdepth++;
if (try_icl(logdepth, "libs/fs/_getcwd", test_c, "#include <direct.h>", NULL, NULL)) return 0;
return try_fail(logdepth, "libs/fs/_getcwd");
}
int find_fs_getwd(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <unistd.h>"
NL "int main() {"
NL " char b[8192];"
NL " if (getwd(b) != NULL)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for getwd... ");
logprintf(logdepth, "find_fs_getwd: trying to find getwd()...\n");
logdepth++;
if (try_icl(logdepth, "libs/fs/getwd", test_c, NULL, NULL, NULL)) return 0;
return try_fail(logdepth, "libs/fs/getwd");
}
int find_fs_mkdir(const char *name, int logdepth, int fatal)
{
char *dir;
char test_c[1024];
char *test_c_in =
NL "#include <stdio.h>"
NL "int main() {"
NL no_implicit(int, "mkdir", "mkdir")
NL " if (mkdir(\"%s\"%s) == 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
dir = tempfile_new("");
unlink(dir);
report("Checking for mkdir... ");
logprintf(logdepth, "find_fs_mkdir: trying to find mkdir()...\n");
logdepth++;
/* POSIX, 2 arguments, standard includes */
sprintf(test_c, test_c_in, dir, ", 0755");
if (try_icl(logdepth, "libs/fs/mkdir", test_c, "#include <sys/types.h>\n#include <sys/stat.h>\n", NULL, NULL)) {
if (!is_dir(dir))
goto oops1;
put("libs/fs/mkdir/num_args", "2");
rmdir(dir);
return 0;
}
/* POSIX, 2 arguments, no includes */
oops1:;
sprintf(test_c, test_c_in, dir, ", 0755");
if (try_icl(logdepth, "libs/fs/mkdir", test_c, NULL, NULL, NULL)) {
if (!is_dir(dir))
goto oops2;
put("libs/fs/mkdir/num_args", "2");
rmdir(dir);
return 0;
}
/* win32, 1 argument, with <direct.h> */
oops2:;
sprintf(test_c, test_c_in, dir, "");
if (try_icl(logdepth, "libs/fs/mkdir", test_c, "#include <direct.h>\n", NULL, NULL)) {
if (!is_dir(dir))
goto oops3;
put("libs/fs/mkdir/num_args", "1");
rmdir(dir);
return 0;
}
oops3:;
put("libs/fs/mkdir/includes", "");
put("libs/fs/mkdir/ldflags", "");
put("libs/fs/mkdir/cdflags", "");
rmdir(dir);
return try_fail(logdepth, "libs/fs/mkdir");
}
int find_fs__mkdir(const char *name, int logdepth, int fatal)
{
char *dir;
char test_c[1024];
char *test_c_in =
NL "#include <stdio.h>"
NL "int main() {"
NL " if (_mkdir(\"%s\"%s) == 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
dir = tempfile_new("");
unlink(dir);
report("Checking for _mkdir... ");
logprintf(logdepth, "find_fs__mkdir: trying to find _mkdir()...\n");
logdepth++;
/* win32, 2 arguments, standard includes */
sprintf(test_c, test_c_in, dir, ", 0755");
if (try_icl(logdepth, "libs/fs/_mkdir", test_c, "#include <direct.h>\n", NULL, NULL)) {
if (!is_dir(dir))
goto oops1;
put("libs/fs/_mkdir/num_args", "2");
rmdir(dir);
return 0;
}
oops1:;
/* win32, 1 argument, standard includes */
sprintf(test_c, test_c_in, dir, "");
if (try_icl(logdepth, "libs/fs/_mkdir", test_c, "#include <direct.h>\n", NULL, NULL)) {
if (!is_dir(dir))
goto oops2;
put("libs/fs/_mkdir/num_args", "1");
rmdir(dir);
return 0;
}
oops2:;
put("libs/fs/_mkdir/includes", "");
put("libs/fs/_mkdir/ldflags", "");
put("libs/fs/_mkdir/cdflags", "");
rmdir(dir);
return try_fail(logdepth, "libs/fs/_mkdir");
}
int find_fs_mkdtemp(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <stdio.h>"
NL "#include <unistd.h>"
NL "#include <string.h>"
NL "int main() {"
NL " char fn[32], *o;"
NL " strcpy(fn, \"scc.XXXXXX\");"
NL " o = mkdtemp(fn);"
NL " if ((o != NULL) && (strstr(o, \"scc.\") != NULL)) {"
NL " remove(o);"
NL " puts(\"OK\");"
NL " }"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for mkdtemp... ");
logprintf(logdepth, "find_fs_mkdtemp: trying to find mkdtemp()...\n");
logdepth++;
if (try_icl(logdepth, "libs/fs/mkdtemp", test_c, "#include <stdlib.h>\n", NULL, NULL)) return 0;
if (try_icl(logdepth, "libs/fs/mkdtemp", test_c, "#define _BSD_SOURCE\n#include <stdlib.h>\n", NULL, NULL)) return 0;
return try_fail(logdepth, "libs/fs/mkdtemp");
}
int find_fs_mmap(const char *name, int logdepth, int fatal)
{
char test_c[1024];
char *tmp;
FILE *f;
char *test_c_in =
NL "#include <stdio.h>"
NL "#include <unistd.h>"
NL "#include <string.h>"
NL "#include <sys/types.h>"
NL "#include <sys/stat.h>"
NL "#include <fcntl.h>"
NL "int main() {"
NL " int fd, size = 11;"
NL " void *p;"
NL " fd = open(\"%s\", O_RDONLY);"
NL " p = mmap(0, size, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);"
NL " if (p == NULL) {"
NL " puts(\"mmap fail\");"
NL " return 0;"
NL " }"
NL " if (strcmp(p, \"hello world\") != 0) {"
NL " puts(\"strcmp fail\");"
NL " return 0;"
NL " }"
NL " if (munmap(p, size) != 0) {"
NL " puts(\"munmap fail\");"
NL " return 0;"
NL " }"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
tmp = tempfile_new("");
f = fopen(tmp, "w");
fprintf(f, "hello world");
fclose(f);
sprintf(test_c, test_c_in, tmp);
report("Checking for mmap... ");
logprintf(logdepth, "find_fs_mmap: trying to find mmap()...\n");
logdepth++;
if (try_icl(logdepth, "libs/fs/mmap", test_c, "#include <sys/mman.h>\n", NULL, NULL)) {
unlink(tmp);
free(tmp);
return 0;
}
unlink(tmp);
free(tmp);
return try_fail(logdepth, "libs/fs/mmap");
}
/* Haiku/BeOS next_dev */
int find_fsmount_next_dev(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <stdio.h>"
NL "int main()"
NL "{"
NL " int32 pos = 0;"
NL " dev_t res = next_dev(&pos);"
NL " if (res >= 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for next_dev... ");
logprintf(logdepth, "find_fsmount_next_dev: trying to find next_dev()...\n");
logdepth++;
if (try_icl(logdepth, "libs/fsmount/next_dev", test_c, "#include <fs_info.h>\n", NULL, NULL)) return 0;
return try_fail(logdepth, "libs/fsmount/next_dev");
}
int find_fsmount_fsstat_fields(const char *name, int logdepth, int fatal)
{
const char *fields[] = {"f_fstypename", NULL};
return try_icl_sfields(logdepth, "libs/fsmount/struct_fsstat", "struct fsstat", fields, "#include <sys/fsstat.h>", NULL, NULL, 0);
}
int find_fsmount_statfs_fields(const char *name, int logdepth, int fatal)
{
const char *fields[] = {"f_fstypename", "f_type", NULL};
return try_icl_sfields(logdepth, "libs/fsmount/struct_statfs", "struct statfs", fields, "#include <sys/statfs.h>", NULL, NULL, 0);
}
int find_fsmount_statvfs_fields(const char *name, int logdepth, int fatal)
{
const char *fields[] = {"f_fstypename", "f_type", "f_basetype", NULL};
return try_icl_sfields(logdepth, "libs/fsmount/struct_statvfs", "struct statvfs", fields, "#include <sys/statvfs.h>", NULL, NULL, 0);
}
int find_fs_ustat(const char *name, int logdepth, int fatal)
{
const char *key = "libs/fs/ustat";
const char *test_c =
NL "#include <stdio.h>"
NL "#include <sys/stat.h>"
NL "int main()"
NL "{"
NL " struct stat stat_buf;"
NL " struct ustat ustat_buf;"
NL " if (stat(\".\", &stat_buf) == 0 &&"
NL " ustat(stat_buf.st_dev, &ustat_buf) == 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for ustat... ");
logprintf(logdepth, "find_fs_ustat: trying to find ustat()...\n");
logdepth++;
if (try_icl(logdepth, key, test_c, "#include <ustat.h>", NULL, NULL)) return 0;
if (try_icl(logdepth, key, test_c, "#include <unistd.h>", NULL, NULL)) return 0;
if (try_icl(logdepth, key, test_c, "#include <sys/types.h>\n#include <unistd.h>", NULL, NULL)) return 0;
if (try_icl(logdepth, key, test_c, "#include <sys/types.h>\n#include <unistd.h>\n#include <ustat.h>", NULL, NULL)) return 0;
return try_fail(logdepth, key);
}
int find_fs_statfs(const char *name, int logdepth, int fatal)
{
const char *key = "libs/fs/statfs";
const char *test_c =
NL "#include <stdio.h>"
NL "int main()"
NL "{"
NL " struct statfs statfs_buf;"
NL " if (statfs(\".\", &statfs_buf) == 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for statfs... ");
logprintf(logdepth, "find_fs_statfs: trying to find statfs()...\n");
logdepth++;
if (try_icl(logdepth, key, test_c, "#include <sys/statfs.h>", NULL, NULL)) return 0;
if (try_icl(logdepth, key, test_c, "#include <sys/vfs.h>", NULL, NULL)) return 0;
return try_fail(logdepth, key);
}
int find_fs_statvfs(const char *name, int logdepth, int fatal)
{
const char *key = "libs/fs/statvfs";
const char *test_c =
NL "#include <stdio.h>"
NL "int main()"
NL "{"
NL " struct statvfs statvfs_buf;"
NL " if (statvfs(\".\", &statvfs_buf) == 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for statvfs... ");
logprintf(logdepth, "find_fs_statvfs: trying to find statvfs()...\n");
logdepth++;
if (try_icl(logdepth, key, test_c, "#include <sys/statvfs.h>", NULL, NULL)) return 0;
return try_fail(logdepth, key);
}
int find_fs_flock(const char *name, int logdepth, int fatal)
{
const char *key = "libs/fs/flock";
const char *test_c =
NL "#include <stdio.h>"
NL "int main()"
NL "{"
NL " if (flock(1, LOCK_UN) == 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for flock... ");
logprintf(logdepth, "find_fs_flock: trying to find flock()...\n");
logdepth++;
if (try_icl(logdepth, key, test_c, "#include <sys/file.h>", NULL, NULL)) return 0;
return try_fail(logdepth, key);
}
int find_fs_makedev(const char *name, int logdepth, int fatal)
{
const char *key = "libs/fs/makedev";
const char *test_c =
NL "#include <stdio.h>"
NL "int main() {"
NL " if (1 == major(makedev(1, 2)) && 2 == minor(makedev(1, 2)))"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char *includes[] = {
"#include <sys/sysmacros.h>",
NULL
};
const char **i;
require("cc/cc", logdepth, fatal);
report("Checking for makedev()... ");
logprintf(logdepth, "find_fs_makedev: trying to find makedev...\n");
logdepth++;
for (i = includes; *i != NULL; i++)
if (try_icl(logdepth, key, test_c, *i, NULL, NULL))
return 0;
return try_fail(logdepth, key);
}

View File

@ -1,141 +0,0 @@
/*
scconfig - detection of standard library features
Copyright (C) 2009 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
static int try_bad(int logdepth, const char *test_c, char *cflags, char *ldflags)
{
char *out = NULL;
logprintf(logdepth, "trying signal (neg) with ldflags '%s'\n", ldflags == NULL ? get("cc/ldflags") : ldflags);
if (compile_run(logdepth+1, test_c, NULL, cflags, ldflags, &out) == 0) {
if (target_emu_fail(out) || (strncmp(out, "BAD", 3) == 0)) {
free(out);
return 0;
}
free(out);
}
return 1;
}
int find_signal_raise(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <stdio.h>"
NL "#include <signal.h>"
NL "int main(int argc, char *argv[]) {"
NL " printf(\"OK\\n\");"
NL " if (argc == 16)"
NL " raise(1);"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for raise()... ");
logprintf(logdepth, "find_signal_raise: trying to find raise()...\n");
logdepth++;
if (try_icl(logdepth, "signal/raise", test_c, NULL, NULL, NULL))
return 0;
return try_fail(logdepth, "signal/raise");
}
int find_signal_names(const char *rname, int logdepth, int fatal)
{
char *test_c_exists =
NL "#include <stdio.h>"
NL "#include <signal.h>"
NL "int main(int argc, char *argv[]) {"
NL " printf(\"OK\\n\");"
NL " if (argc == 16)"
NL " raise(%s);"
NL " return 0;"
NL "}"
NL;
char *test_c_terms =
NL "#include <stdio.h>"
NL "#include <signal.h>"
NL "int main() {"
NL " raise(%s);"
NL " printf(\"BAD\\n\");"
NL " return 0;"
NL "}"
NL;
char test_c[256];
const char *names[] = {"SIGINT", "SIGABRT", "SIGKILL", "SIGTERM", "SIGQUIT", "SIGHUP", "SIGFPE", "SIGSEGV", "SIGPIPE", NULL};
const char **name;
char path[256], *pathend;
const char *prefix = "signal/names/";
require("cc/cc", logdepth, fatal);
require("signal/raise/*", logdepth, fatal);
strcpy(path, prefix);
pathend = path + strlen(prefix);
for(name = names; *name != NULL; name++) {
/* check whether it exists */
report("Checking whether %s exists... ", *name);
logprintf(logdepth, "find_signal_names: checking whether %s exists\n", *name);
logdepth++;
sprintf(test_c, test_c_exists, *name);
strcpy(pathend, *name);
if (!try_icl(logdepth, path, test_c, NULL, NULL, NULL)) {
logdepth--;
continue;
}
/* check whether it exists */
logdepth--;
report("Checking whether %s terminates... ", *name);
logprintf(logdepth, "find_signal_names: checking whether %s terminates\n", *name);
logdepth++;
sprintf(test_c, test_c_terms, *name);
sprintf(pathend, "%s/terminates", *name);
if (try_bad(logdepth, test_c, NULL, "")) {
put(path, strue);
report("terminates\n");
}
else {
report("does not terminate\n");
put(path, sfalse);
}
logdepth--;
}
/* to avoid redetection */
put("signal/names/presents", strue);
return 0;
}

View File

@ -1,111 +0,0 @@
/*
scconfig - test code for default and scripts
Copyright (C) 2009..2016 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "db.h"
#include "find.h"
#include "log.h"
#include "arg.h"
#include "dep.h"
#include "deps_default.h"
#include "libs.h"
#include "hooks.h"
#include "regex.h"
#include "main_custom_args.h"
#include "main_lib.h"
void re_fail(char *s, char c)
{
fprintf(stderr, "Regex error: %s [opcode %o]\n", s, c);
abort();
}
int no_autodetect_sys = 0;
int no_save_cache = 0;
int main(int argc, char *argv[])
{
int blind_save;
if (main_init() != 0)
return 1;
if (main_process_args(argc, argv) != 0)
return 1;
if (!no_autodetect_sys) {
find_target("", 0, 1);
blind_save = cross_blind;
cross_blind = 0;
printf("--- Detecting host\n");
require("sys/name", 0, 1);
}
if (hook_detect_host()) {
fprintf(stderr, "hook_detect_host failed, exiting\n");
return 1;
}
cross_blind = blind_save;
if (!no_autodetect_sys) {
if (!iscross)
printf("--- Detecting target (same as host)\n");
else
printf("--- Detecting target (differs from host)\n");
}
db_cd("/target");
run_custom_reqs();
if (hook_detect_target()) {
fprintf(stderr, "hook_detect_target failed, exiting\n");
return 1;
}
#ifdef RUNTIME
if (!no_autodetect_sys) {
if (!iscross)
printf("--- Detecting runtime (same as host)\n");
else
printf("--- Detecting runtime (differs from host)\n");
}
db_cd("/runtime");
if (hook_detect_runtime()) {
fprintf(stderr, "hook_detect_runtime failed, exiting\n");
return 1;
}
#endif
if (hook_generate()) {
fprintf(stderr, "hook_generate failed, exiting\n");
return 1;
}
if (!no_save_cache)
export("config.cache", 1, "/");
main_uninit();
return 0;
}

View File

@ -1,443 +0,0 @@
/*
scconfig - database
Copyright (C) 2009..2012 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdarg.h>
#include "db.h"
#include "log.h"
#include "libs.h"
ht_t *DBs = NULL;
char *db_cwd = NULL;
void append(const char *key, const char *value)
{
const char *orig;
char *new;
int l1, l2;
assert(key != NULL);
assert(value != NULL);
if (*value == '\0')
return;
orig = get(key);
if (orig == NULL) {
put(key, value);
return;
}
l1 = strlen(orig);
l2 = strlen(value);
new = malloc(l1 + l2 + 1);
memcpy(new, orig, l1);
memcpy(new + l1, value, l2);
new[l1+l2] = '\0';
put(key, new);
}
static const char *db_split_path(const char *key, ht_t **ht, char **fld)
{
size_t fld_len;
const char *path;
char first_level_dir[32];
path = str_chr((char *)(key+1), '/');
assert(path != NULL);
fld_len = path - key;
path++;
if (*path == '\0') {
*ht = NULL;
if (fld != NULL)
*fld = NULL;
return NULL;
}
assert(fld_len < sizeof(first_level_dir));
strncpy(first_level_dir, key, fld_len);
first_level_dir[fld_len] = '\0';
*ht = ht_get(DBs, first_level_dir+1);
if (fld != NULL)
*fld = first_level_dir;
return path;
}
static void export_qs(FILE *f, const char *s)
{
fputc('"', f);
for(;*s != '\0';s++) {
switch(*s) {
case '"': fputc('\\', f); fputc('"', f); break;
case '\n': fputc('\\', f); fputc('n', f); break;
case '\r': fputc('\\', f); fputc('r', f); break;
case '\t': fputc('\\', f); fputc('t', f); break;
default: fputc(*s, f);
}
}
fputc('"', f);
fputc('\n', f);
}
static int needs_quote(const char *s) {
for(; *s != '\0'; s++)
if ((*s < 32) || (*s > 126) || (*s == '"')) return 1;
return 0;
}
int export_(FILE *f, int export_empty, ht_t *table, const char *fld)
{
ht_entry_t *h;
for(h = ht_first(table); h != NULL; h = ht_next(table, h))
if (export_empty || ((h->value != NULL) && (*(char *)h->value != '\0'))) {
fprintf(f, "/%s/%s=", fld, h->key);
if (h->value != NULL) {
if (needs_quote((char *)h->value))
export_qs(f, (const char *)h->value);
else
fprintf(f, "%s\n", (char *)h->value);
}
else
fprintf(f, "\n");
}
return 0;
}
int export(const char *fn, int export_empty, const char *root)
{
FILE *f;
int ret = 0;
/* ht_t *table; */
ht_entry_t *h;
if (fn != NULL) {
f = fopen(fn, "w");
if (f == NULL)
return -1;
}
else
f = stdout;
if ((root == NULL) || ((root[0] == '/') && (root[1] == '\0'))) {
/* export all directories */
for(h = ht_first(DBs); h != NULL; h = ht_next(DBs, h))
ret += export_(f, export_empty, h->value, h->key);
}
else {
error("not yet implemented\n");
abort();
/* db_split_path(); */
}
if (f != stdout)
fclose(f);
return ret;
}
/* append a single character, grow the buffer as needed */
#define qappend(chr) \
do { \
if (used >= alloced) { \
alloced += 256; \
res = realloc(res, alloced); \
} \
res[used] = chr; \
used++; \
} while(0)
/* read until end of quote and interpret backslash sequences if do_esc is non-zero */
static char *readq(FILE *f, char *str, long strmax, int quote, int do_esc, int *num_lines, const char *fn)
{
int bs = 0;
long used = 0, alloced = 0;
char *res = NULL, *s;
for(;;) {
for(s = str; *s != '\0'; s++) {
if (*s == '\n') (*num_lines)++;
if (bs) { /* character escaped by backslash */
switch(*s) {
case '\\': qappend('\\'); break;
case 'n': qappend('\n'); break;
case 'r': qappend('\r'); break;
case 't': qappend('\t'); break;
default: qappend(*s); break;
}
bs = 0;
}
else if (*s == quote) { /* end */
qappend('\0');
if ((s[1] != '\r') && (s[1] != '\n') && (s[1] != '\0'))
fprintf(stderr, "Warning: trailing text after quote ignored in %s:%d\n", fn, (*num_lines)+1);
return res;
}
else if (do_esc && (*s == '\\')) bs = 1; /* backslash start */
else qappend(*s); /* plain character */
}
/* get the next chunk */
fgets(str, strmax, f);
}
return NULL; /* can't get here */
}
int import(const char *fn)
{
char line[1024];
char *key, *value, *nl, *slash;
int num_records, num_lines;
FILE *f;
f = fopen(fn, "r");
if (f == NULL)
return -1;
for(num_records = 0, num_lines = 0; !feof(f); num_lines++) {
*line = '\0';
fgets(line, sizeof(line) - 1, f);
if ((*line != '#') && (*line != '\n') && (*line != '\r') && (*line != '\0')) {
int quote, do_esc=0;
key = line;
value = str_chr(key, '=');
if (value == NULL) {
error("Error importing: missing '=' in line %d in file %s.\n", num_lines, fn);
abort();
}
num_records++;
*value = '\0';
value++;
if (*value == '"') {
quote=*value;
value++;
do_esc=1;
}
else if (*value == '\'') {
quote=*value;
value++;
}
else
quote=0;
if (!quote) {
nl = str_chr(value, '\n');
if (nl != NULL)
*nl = '\0';
}
else
value = readq(f, value, sizeof(line) - (value - line) - 4, quote, do_esc, &num_lines, fn);
slash = str_chr(key+1, '/');
if (slash == NULL) {
error("Error importing: no directory name for %s.\n", key);
abort();
}
*slash = '\0';
db_mkdir(key);
*slash = '/';
put(key, value);
logprintf(0, "(Import from '%s': '%s'='%s')\n", fn, key, value);
if (quote)
free(value);
}
}
fclose(f);
return num_records;
}
int import_args(const char *key, const char *fn)
{
(void) key; /* suppress compiler warnings for unused key; needed because function pointers to this function from arg.c */
db_mkdir("/target");
db_mkdir("/host");
return import(fn) < 0;
}
static const char *db_get(const char *key)
{
const char *path;
ht_t *ht;
path = db_split_path(key, &ht, NULL);
if (ht == NULL)
return NULL;
return ht_get(ht, path);
}
static const char *db_put(const char *key, const char *value)
{
const char *path;
ht_t *ht;
path = db_split_path(key, &ht, NULL);
if (ht == NULL) {
error("db_put: can't find top level hash for '%s'\n", key);
abort();
}
return ht_set(ht, path, (void *)value);
}
#define assamble_path \
assert(strlen(key) + strlen(db_cwd) < sizeof(tmp)-1); \
sprintf(tmp, "%s/%s", db_cwd, key);
const char *get(const char *key)
{
char tmp[256];
if (*key == '/')
return db_get(key);
assamble_path;
return db_get(tmp);
}
const char *put(const char *key, const char *value)
{
char tmp[256];
if (*key == '/')
return db_put(key, value);
assamble_path;
return db_put(tmp, value);
}
void db_init(void)
{
DBs = ht_resize(ht_alloc(0), 16);
}
void db_uninit(void)
{
ht_entry_t *h;
ht_t *dir;
for(h = ht_first(DBs); h != NULL; h = ht_next(DBs, h)) {
dir = h->value;
dir->refcount--;
if (dir->refcount == 0)
ht_free(dir);
}
ht_free(DBs);
if (db_cwd != NULL)
free(db_cwd);
/* Just in case someone calls db_init again... */
db_cwd = NULL;
DBs = NULL;
}
void db_cd(const char *path)
{
assert(*path == '/');
if (db_cwd != NULL)
free(db_cwd);
db_cwd = strclone(path);
}
void db_mkdir(const char *path)
{
ht_t *ht, *target;
assert(*path == '/');
target = ht_get(DBs, path+1);
if (target == NULL) {
ht = ht_resize(ht_alloc(1), 256);
ht_set(DBs, path+1, ht);
}
}
void db_rmdir(const char *path)
{
ht_t *ht;
assert(*path == '/');
ht = ht_get(DBs, path+1);
if (ht == NULL)
return;
ht_del(DBs, path+1);
/* ht_free(ht); */
}
void db_link(const char *existing, const char *new)
{
ht_t *ht;
assert(*new == '/');
ht = ht_get(DBs, existing+1);
assert(ht != NULL);
ht_set(DBs, new+1, ht);
ht->refcount++;
}
char *concat_nodes(const char *prefix, ...)
{
char *buff;
const char *node, *value;
int allocated = 256, len, totallen;
va_list ap;
va_start(ap, prefix);
buff = malloc(allocated);
if (prefix != NULL) {
strcpy(buff, prefix);
totallen = strlen(prefix);
buff[totallen] = ' ';
totallen++;
}
else
totallen = 0;
while((node = va_arg(ap, const char *)) != NULL) {
value = get(node);
if (value != NULL) {
len = strlen(value);
if (totallen + len >= allocated) {
allocated = totallen + len + 256;
buff = realloc(buff, allocated);
}
memcpy(buff + totallen, value, len);
totallen += len;
buff[totallen] = ' ';
totallen++;
buff[totallen] = '\0';
}
}
buff[totallen - 1] = '\0';
va_end(ap);
return buff;
}
int node_istrue(const char *key)
{
const char *s = get(key);
if (s == NULL)
return 0;
return istrue(s);
}

View File

@ -1,223 +0,0 @@
/*
scconfig - detection of standard library features
Copyright (C) 2009,2017 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
int find_lib_lpthread(const char *name, int logdepth, int fatal)
{
const char *lpthread;
char *s;
int ret = 0;
char *test_c_recursive =
NL "#define _GNU_SOURCE 1 /* Needed for recursive thread-locking */"
NL "#include <pthread.h>"
NL "pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;"
NL "int main() {"
NL " pthread_attr_t a;"
NL " if (pthread_attr_init(&a) == 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL ;
char *test_c_simple =
NL "#include <pthread.h>"
NL "int main() {"
NL " pthread_attr_t a;"
NL " if (pthread_attr_init(&a) == 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL ;
require("cc/cc", logdepth, fatal);
report("Checking for -lpthread... ");
logprintf(logdepth, "find_lib_lpthread: trying to find lpthread...\n");
logdepth++;
lpthread = get("/arg/libs/lpthread");
if (lpthread != NULL) {
put("libs/lpthread", lpthread);
report("User provided... ");
s = strclone(lpthread);
}
else
s = strclone("-lpthread");
if (try_icl(logdepth, NULL, test_c_recursive, NULL, NULL, s)) {
put("libs/lpthread", s);
put("libs/lpthread-recursive", strue);
report("OK, recursive (%s)\n", s);
}
else if (try_icl(logdepth, NULL, test_c_simple, NULL, NULL, s)) {
put("libs/lpthread", s);
put("libs/lpthread-recursive", sfalse);
report("OK, NOT RECURSIVE (%s)\n", s);
}
else
ret = 1;
free(s);
return ret;
}
int find_thread_semget(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <stdio.h>"
NL "int main()"
NL "{"
NL " int semid = semget(IPC_PRIVATE, 1, IPC_CREAT);"
NL " if (semid < 0) return 0;"
NL " if(semctl(semid, 0, IPC_RMID) < 0) return 0;"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char *node = "thread/semget";
char **inc, *incs[] = {"#include <sys/types.h>\n#include <sys/ipc.h>\n#include <sys/sem.h>", "#include <sys/types.h>\n#include <sys/ipc.h>", "#include <sys/types.h>\n#include <sys/sem.h>", NULL};
if (require("cc/cc", logdepth, fatal))
return try_fail(logdepth, node);
report("Checking for semget... ");
logprintf(logdepth, "find_semget:\n");
logdepth++;
for(inc = incs; *inc != NULL; inc++)
if (try_icl(logdepth, node, test_c, *inc, NULL, NULL) != 0)
return 0;
return try_fail(logdepth, node);
}
int find_thread_pthread_create(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <stdio.h>"
NL "void* test_thread(void* param)"
NL "{"
NL " return NULL;"
NL "}"
NL "int main()"
NL "{"
NL " pthread_t pt;"
NL " if (pthread_create(&pt, NULL, test_thread, NULL) == 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char *node = "thread/pthread_create";
char **inc, *incs[] = {"#include <pthread.h>", "#include <pthread.h>\n#include <signal.h>", NULL};
const char *lpthread;
char* s;
if (require("cc/cc", logdepth, fatal))
return try_fail(logdepth, node);
report("Checking for pthread_create... ");
logprintf(logdepth, "find_pthread_create:\n");
logdepth++;
lpthread = get("/arg/libs/lpthread");
if (lpthread != NULL) {
report("User provided... ");
s = strclone(lpthread);
}
else
s = strclone("-lpthread");
for(inc = incs; *inc != NULL; inc++)
if (try_icl(logdepth, node, test_c, *inc, NULL, s) != 0) {
free(s);
return 0;
}
free(s);
return try_fail(logdepth, node);
}
int find_thread_CreateSemaphore(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <stdio.h>"
NL "int main()"
NL "{"
NL " if (CreateSemaphore(NULL, 1, 1, NULL))"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char *node = "thread/CreateSemaphore";
if (require("cc/cc", logdepth, fatal))
return try_fail(logdepth, node);
report("Checking for CreateSemaphore... ");
logprintf(logdepth, "find_thread_CreateSemaphore:\n");
logdepth++;
if (try_icl(logdepth, node, test_c, "#include <windows.h>", NULL, NULL) != 0)
return 0;
return try_fail(logdepth, node);
}
int find_thread_CreateThread(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <stdio.h>"
NL "DWORD WINAPI test_thread(void* param)"
NL "{"
NL " return 0;"
NL "}"
NL "int main()"
NL "{"
NL " if (CreateThread(NULL, 0, test_thread, NULL, 0, NULL))"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char *node = "thread/CreateThread";
if (require("cc/cc", logdepth, fatal))
return try_fail(logdepth, node);
report("Checking for CreateThread... ");
logprintf(logdepth, "find_thread_CreateThread:\n");
logdepth++;
if (try_icl(logdepth, node, test_c, "#include <windows.h>", NULL, NULL) != 0)
return 0;
return try_fail(logdepth, node);
}

View File

@ -1,182 +0,0 @@
/*
scconfig - dependency list of default tests
Copyright (C) 2009..2012 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include "dep.h"
#include "find.h"
void deps_default_init(void)
{
dep_add("cc/cc", find_cc);
dep_add("cc/argstd/*", find_cc_argstd);
dep_add("cc/cflags", find_cc);
dep_add("cc/ldflags", find_cc);
dep_add("cc/inline", find_inline);
dep_add("cc/varargmacro", find_varargmacro);
dep_add("cc/funcmacro", find_funcmacro);
dep_add("cc/constructor", find_constructor);
dep_add("cc/destructor", find_destructor);
dep_add("cc/rdynamic", find_rdynamic);
dep_add("cc/soname", find_soname);
dep_add("cc/so_undefined", find_so_undefined);
dep_add("cc/wlrpath", find_wlrpath);
dep_add("cc/wloutimplib", find_cc_wloutimplib);
dep_add("cc/wloutputdef", find_cc_wloutputdef);
dep_add("cc/fpic", find_fpic);
dep_add("cc/fpie/*", find_cc_fpie);
dep_add("cc/fnopie/*", find_cc_fnopie);
dep_add("cc/fnopic/*", find_cc_fnopic);
dep_add("cc/alloca/*", find_alloca);
dep_add("cc/_exit/*", find__exit);
dep_add("cc/ldflags_dynlib", find_ldflags_dynlib);
dep_add("cc/ldflags_dll", find_ldflags_dll);
dep_add("cc/ldflags_so", find_ldflags_so);
dep_add("cc/func_attr/unused/*", find_fattr_unused);
dep_add("cc/declspec/dllimport/*", find_declspec_dllimport);
dep_add("cc/declspec/dllexport/*", find_declspec_dllexport);
dep_add("cc/argmachine/*", find_cc_argmachine);
dep_add("cc/pragma_message/*", find_cc_pragma_message);
dep_add("cc/static_libgcc/*", find_cc_static_libgcc);
dep_add("libs/ldl", find_lib_ldl);
dep_add("libs/LoadLibrary/*", find_lib_LoadLibrary);
dep_add("libs/lpthread", find_lib_lpthread);
dep_add("libs/lpthread-recursive", find_lib_lpthread);
dep_add("thread/semget/*", find_thread_semget);
dep_add("thread/pthread_create/*", find_thread_pthread_create);
dep_add("thread/CreateSemaphore/*", find_thread_CreateSemaphore);
dep_add("thread/CreateThread/*", find_thread_CreateThread);
dep_add("libs/errno/*", find_lib_errno);
dep_add("libs/printf_x", find_printf_x);
dep_add("libs/printf_ptrcast", find_printf_ptrcast);
dep_add("libs/snprintf", find_snprintf);
dep_add("libs/snprintf_safe", find_snprintf);
dep_add("libs/dprintf", find_dprintf);
dep_add("libs/vdprintf", find_vdprintf);
dep_add("libs/vsnprintf", find_vsnprintf);
dep_add("libs/proc/_spawnvp/*", find_proc__spawnvp);
dep_add("libs/proc/fork/*", find_proc_fork);
dep_add("libs/proc/wait/*", find_proc_wait);
dep_add("libs/proc/_getpid/*", find_proc__getpid);
dep_add("libs/proc/CreateProcessA/*",find_proc_CreateProcessA);
dep_add("libs/proc/getexecname/*", find_proc_getexecname);
dep_add("libs/proc/GetModuleFileNameA/*",find_proc_GetModuleFileNameA);
dep_add("libs/proc/shmget/*", find_proc_shmget);
dep_add("libs/proc/CreateFileMappingA/*",find_proc_CreateFileMappingA);
dep_add("libs/fs/realpath/*", find_fs_realpath);
dep_add("libs/fs/_fullpath/*", find_fs__fullpath);
dep_add("libs/fs/readdir/*", find_fs_readdir);
dep_add("libs/fs/findnextfile/*", find_fs_findnextfile);
dep_add("libs/fs/stat/macros/*", find_fs_stat_macros);
dep_add("libs/fs/stat/fields/*", find_fs_stat_fields);
dep_add("libs/fs/access/*", find_fs_access);
dep_add("libs/fs/access/macros/*", find_fs_access_macros);
dep_add("libs/fs/lstat/*", find_fs_lstat);
dep_add("libs/fs/statlstat/*", find_fs_statlstat);
dep_add("libs/fs/getcwd/*", find_fs_getcwd);
dep_add("libs/fs/_getcwd/*", find_fs__getcwd);
dep_add("libs/fs/getwd/*", find_fs_getwd);
dep_add("libs/fs/mkdir/*", find_fs_mkdir);
dep_add("libs/fs/_mkdir/*", find_fs__mkdir);
dep_add("libs/fs/mkdtemp/*", find_fs_mkdtemp);
dep_add("libs/fs/mmap/*", find_fs_mmap);
dep_add("libs/fsmount/next_dev/*", find_fsmount_next_dev);
dep_add("libs/fsmount/struct_fsstat/*",find_fsmount_fsstat_fields);
dep_add("libs/fsmount/struct_statfs/*",find_fsmount_statfs_fields);
dep_add("libs/fsmount/struct_statvfs/*",find_fsmount_statvfs_fields);
dep_add("libs/fs/ustat/*", find_fs_ustat);
dep_add("libs/fs/statfs/*", find_fs_statfs);
dep_add("libs/fs/statvfs/*", find_fs_statvfs);
dep_add("libs/fs/flock/*", find_fs_flock);
dep_add("libs/fs/makedev/*", find_fs_makedev);
dep_add("libs/io/pipe/*", find_io_pipe);
dep_add("libs/io/dup2/*", find_io_dup2);
dep_add("libs/io/fileno/*", find_io_fileno);
dep_add("libs/io/lseek/*", find_io_lseek);
dep_add("libs/io/popen/*", find_io_popen);
dep_add("libs/time/usleep/*", find_time_usleep);
dep_add("libs/types/stdint/*", find_types_stdint);
dep_add("sys/types/size/*", find_types_sizes);
dep_add("libs/time/Sleep/*", find_time_Sleep);
dep_add("libs/time/gettimeofday/*", find_time_gettimeofday);
dep_add("libs/time/ftime/*", find_time_ftime);
dep_add("libs/time/timegm/*", find_time_timegm);
dep_add("libs/time/_mkgmtime/*", find_time_mkgmtime);
dep_add("libs/time/gmtime_r/*", find_time_gmtime_r);
dep_add("libs/time/gmtime_s/*", find_time_gmtime_s);
dep_add("libs/time/localtime_r/*", find_time_localtime_r);
dep_add("libs/time/localtime_s/*", find_time_localtime_s);
dep_add("libs/env/main_3arg/*", find_main_arg3);
dep_add("libs/env/putenv/*", find_putenv);
dep_add("libs/env/setenv/*", find_setenv);
dep_add("libs/env/environ/*", find_environ);
dep_add("signal/raise/*", find_signal_raise);
dep_add("signal/names/*", find_signal_names);
dep_add("fstools/cp", find_fstools_cp);
dep_add("fstools/ln", find_fstools_ln);
dep_add("fstools/mv", find_fstools_mv);
dep_add("fstools/rm", find_fstools_rm);
dep_add("fstools/mkdir", find_fstools_mkdir);
dep_add("fstools/ar", find_fstools_ar);
dep_add("fstools/ranlib", find_fstools_ranlib);
dep_add("fstools/awk", find_fstools_awk);
dep_add("fstools/cat", find_fstools_cat);
dep_add("fstools/sed", find_fstools_sed);
dep_add("fstools/file_l", find_fstools_file_l);
dep_add("fstools/file", find_fstools_file);
dep_add("fstools/chmodx", find_fstools_chmodx);
dep_add("sys/name", find_uname);
dep_add("sys/uname", find_uname);
dep_add("sys/triplet", find_triplet);
dep_add("sys/sysid", find_sysid);
dep_add("sys/shell", find_shell);
dep_add("sys/shell_needs_quote", find_shell);
dep_add("sys/tmp", find_tmp);
dep_add("sys/shell_eats_backslash", find_tmp);
dep_add("sys/ext_exe", find_uname);
dep_add("sys/ext_dynlib", find_uname);
dep_add("sys/ext_dynlib_native", find_uname);
dep_add("sys/ext_stalib", find_uname);
dep_add("sys/class", find_uname);
dep_add("sys/path_sep", find_uname);
dep_add("sys/ptrwidth", find_sys_ptrwidth);
dep_add("sys/byte_order", find_sys_byte_order);
dep_add("sys/types/size_t/*", find_types_size_t);
dep_add("sys/types/off_t/*", find_types_off_t);
dep_add("sys/types/off64_t/*", find_types_off64_t);
dep_add("sys/types/gid_t/*", find_types_gid_t);
dep_add("sys/types/uid_t/*", find_types_uid_t);
dep_add("sys/types/pid_t/*", find_types_pid_t);
dep_add("sys/types/mode_t/*", find_types_mode_t);
dep_add("sys/types/nlink_t/*", find_types_nlink_t);
dep_add("sys/types/ptrdiff_t/*", find_types_ptrdiff_t);
dep_add("sys/types/dev_t/*", find_types_dev_t);
dep_add("sys/types/ino_t/*", find_types_ino_t);
dep_add("sys/types/void_ptr/*", find_types_void_ptr);
dep_add("str/strcasecmp/*", find_strcasecmp);
dep_add("str/strncasecmp/*", find_strncasecmp);
dep_add("str/stricmp/*", find_stricmp);
dep_add("str/strnicmp/*", find_strnicmp);
dep_add("/internal/filelist/cmd", find_filelist);
dep_add("/internal/filelist/method", find_filelist);
}

View File

@ -1,366 +0,0 @@
/*
scconfig - detection of standard library features (processes)
Copyright (C) 2016 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
int find_proc__spawnvp(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <stdlib.h>"
NL "int main() {"
NL " const char *a[3] = {\"/c\", \"echo OK\", NULL};"
NL " _spawnvp(_P_WAIT, \"cmd\", a);"
NL " return 0;"
NL "}"
NL ;
require("cc/cc", logdepth, fatal);
report("Checking for _spawnvp... ");
logprintf(logdepth, "find_proc__spawnvp: trying to find _spawnvp...\n");
logdepth++;
if (try_icl(logdepth, "libs/proc/_spawnvp", test_c, "#include <process.h>", NULL, NULL)) return 0;
return try_fail(logdepth, "libs/proc/_spawnvp");
}
int find_proc_CreateProcessA(const char *name, int logdepth, int fatal)
{
const char *key = "libs/proc/CreateProcessA";
char *test_c =
NL "#include <stdlib.h>"
NL "char buf[2000];"
NL "int main() {"
NL " const char *cmd;"
NL " STARTUPINFOA si;"
NL " PROCESS_INFORMATION pi;"
NL " cmd = getenv(\"COMSPEC\");"
NL " if (cmd == NULL) { /* fallback to guessing */"
NL " UINT len = GetWindowsDirectoryA(buf, sizeof(buf));"
NL " strcpy(buf+len, \"\\\\system32\\\\cmd.exe\");"
NL " cmd = buf;"
NL " }"
NL " memset(&si, 0, sizeof(si)); si.cb = sizeof(si);"
NL " if (!CreateProcessA(cmd, \"/c \\\"echo OK\\\"\","
NL " NULL, NULL, TRUE,"
NL " 0, NULL, NULL, &si, &pi))"
NL " return 1;"
NL " if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_OBJECT_0)"
NL " abort();"
NL " return 0;"
NL "}"
NL ;
require("cc/cc", logdepth, fatal);
report("Checking for CreateProcessA... ");
logprintf(logdepth, "find_proc_CreateProcessA: trying to find CreateProcessA...\n");
logdepth++;
if (try_icl(logdepth, key, test_c, "#include <windows.h>", NULL, NULL)) return 0;
return try_fail(logdepth, key);
}
int find_proc_fork(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <stdlib.h>"
NL "#include <stdio.h>"
NL "int main() {"
NL " if (fork() == 0) { return 0; }"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL ;
/* NOTE: can't print OK from the child process because of a possible race
with the parent immediately exiting without wait(). */
require("cc/cc", logdepth, fatal);
report("Checking for fork... ");
logprintf(logdepth, "find_proc_fork: trying to find fork...\n");
logdepth++;
if (try_icl(logdepth, "libs/proc/fork", test_c, "#include <unistd.h>", NULL, NULL)) return 0;
return try_fail(logdepth, "libs/proc/fork");
}
int find_proc_wait(const char *name, int logdepth, int fatal)
{
char *inc;
const char *inc1;
char test_c[1024];
char *test_c_in =
NL "%s\n"
NL "#include <stdlib.h>"
NL "#include <stdio.h>"
NL "int main() {"
NL " int st = 0;"
NL " if (fork() == 0) {"
NL " printf(\"O\");"
NL " return 42;"
NL " }"
NL " wait(&st);"
NL " if (WIFEXITED(st) && (WEXITSTATUS(st) == 42))"
NL " printf(\"K\");"
NL " else"
NL " printf(\"%%d\", st);"
NL " printf(\"\\n\");"
NL " return 0;"
NL "}"
NL ;
require("cc/cc", logdepth, fatal);
if (require("libs/proc/fork", logdepth, fatal))
return try_fail(logdepth, "libs/proc/wait");
report("Checking for wait... ");
logprintf(logdepth, "find_proc_wait: trying to find wait...\n");
logdepth++;
inc1 = get("libs/proc/fork/includes");
if (inc1 != NULL) {
char *i, *o;
inc = strclone(inc1);
for(i = o = inc; *i != '\0'; i++,o++) {
if ((i[0] == '\\') && (i[1] == 'n')) {
*o = '\n';
i++;
}
else
*o = *i;
}
*o = '\0';
sprintf(test_c, test_c_in, inc);
free(inc);
}
else
sprintf(test_c, test_c_in, "");
if (try_icl(logdepth, "libs/proc/wait", test_c, "#include <sys/types.h>\n#include <sys/wait.h>", NULL, NULL)) return 0;
return try_fail(logdepth, "libs/proc/wait");
}
int find_proc__getpid(const char *name, int logdepth, int fatal)
{
const char *key = "libs/proc/_getpid";
const char *test_c =
NL "#include <stdio.h>"
NL "int main()"
NL "{"
NL no_implicit(int, "_getpid", "_getpid")
NL " if (_getpid() != (-1))"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for _getpid()... ");
logprintf(logdepth, "find_proc__getpid: trying to find _getpid()...\n");
logdepth++;
if (try_icl(logdepth, key, test_c, "#include <process.h>", NULL, NULL))
return 0;
return try_fail(logdepth, key);
}
int find_proc_getexecname(const char *name, int logdepth, int fatal)
{
const char *key = "libs/proc/getexecname";
const char *test_c =
NL "void my_puts(const char *s);"
NL "int main()"
NL "{"
NL no_implicit(const char*, "getexecname", "getexecname")
NL " getexecname();"
NL " my_puts(\"OK\");"
NL " return 0;"
NL "}"
NL "#include <stdio.h>"
NL "void my_puts(const char *s)"
NL "{"
NL " puts(s);"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for getexecname()... ");
logprintf(logdepth, "find_proc_getexecname: trying to find getexecname()...\n");
logdepth++;
if (try_icl(logdepth, key, test_c, "#include <stdlib.h>", NULL, NULL))
return 0;
return try_fail(logdepth, key);
}
int find_proc_GetModuleFileNameA(const char *name, int logdepth, int fatal)
{
const char *key = "libs/proc/GetModuleFileNameA";
const char *test_c =
NL "void my_puts(const char *s);"
NL "char path_buffer[5000];"
NL "int main()"
NL "{"
NL " HMODULE hModule = GetModuleHandleA(NULL);"
NL " if (GetModuleFileNameA(hModule, path_buffer, sizeof(path_buffer)) != 0)"
NL " my_puts(\"OK\");"
NL " return 0;"
NL "}"
NL "#include <stdio.h>"
NL "void my_puts(const char *s)"
NL "{"
NL " puts(s);"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for GetModuleFileNameA()... ");
logprintf(logdepth, "find_proc_GetModuleFileNameA: trying to find GetModuleFileNameA()...\n");
logdepth++;
if (try_icl(logdepth, key, test_c, "#include <windows.h>", NULL, NULL))
return 0;
if (try_icl(logdepth, key, test_c, "#include <windows.h>", NULL, "-lkernel32"))
return 0;
return try_fail(logdepth, key);
}
int find_proc_shmget(const char *name, int logdepth, int fatal)
{
const char *key = "libs/proc/shmget";
const char *test_c =
NL "void my_puts(const char *s);"
NL "int main()"
NL "{"
NL " int shmid;"
NL " char *addr;"
NL " shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT|IPC_EXCL|0600);"
NL " if (shmid < 0)"
NL " return 1;"
NL " addr = (char *)shmat(shmid, (void *)0, 0);"
NL " if (addr == (char *)0) {"
NL " shmctl(shmid, IPC_RMID, (void *)0);"
NL " return 1;"
NL " }"
NL " if (shmctl(shmid, IPC_RMID, (void *)0) != 0)"
NL " return 1;"
NL " if (addr[2] != 0)"
NL " return 1;"
NL " addr[0] = 'O'; addr[1] = 'K';"
NL " my_puts(addr);"
NL " return 0;"
NL "}"
NL "#include <stdio.h>"
NL "void my_puts(const char *s)"
NL "{"
NL " puts(s);"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for shmget()... ");
logprintf(logdepth, "find_proc_shmget: trying to find shmget()...\n");
logdepth++;
if (try_icl(logdepth, key, test_c, "#include <sys/ipc.h>\n#include <sys/shm.h>", NULL, NULL))
return 0;
return try_fail(logdepth, key);
}
int find_proc_CreateFileMappingA(const char *name, int logdepth, int fatal)
{
const char *key = "libs/proc/CreateFileMappingA";
const char *test_c =
NL "void my_puts(const char *s);"
NL "#define MAP_BUF_SIZE 4096"
NL "int main()"
NL "{"
NL " char *addr;"
NL " HANDLE hMap = CreateFileMappingA("
NL " INVALID_HANDLE_VALUE,"
NL " NULL,"
NL " PAGE_READWRITE,"
NL " 0,"
NL " MAP_BUF_SIZE,"
NL " NULL);"
NL " if (hMap == NULL)"
NL " return 1;"
NL " addr = (char *)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS,"
NL " 0, 0, MAP_BUF_SIZE);"
NL " if (addr == NULL) {"
NL " CloseHandle(hMap);"
NL " return 1;"
NL " }"
NL " if (addr[2] != 0) {"
NL " UnmapViewOfFile(addr);"
NL " CloseHandle(hMap);"
NL " return 1;"
NL " }"
NL " addr[0] = 'O'; addr[1] = 'K';"
NL " my_puts(addr);"
NL " UnmapViewOfFile(addr);"
NL " CloseHandle(hMap);"
NL " return 0;"
NL "}"
NL "#include <stdio.h>"
NL "void my_puts(const char *s)"
NL "{"
NL " puts(s);"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for CreateFileMappingA()... ");
logprintf(logdepth, "find_proc_CreateFileMappingA: trying to find CreateFileMappingA()...\n");
logdepth++;
if (try_icl(logdepth, key, test_c, "#include <windows.h>", NULL, NULL))
return 0;
if (try_icl(logdepth, key, test_c, "#include <windows.h>", NULL, "-lkernel32"))
return 0;
return try_fail(logdepth, key);
}

View File

@ -1,180 +0,0 @@
/*
scconfig - dependency list of default tests
Copyright (C) 2009..2012 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include "dep.h"
#include "find.h"
void deps_default_init(void)
{
dep_add("cc/cc", find_cc);
dep_add("cc/argstd/*", find_cc_argstd);
dep_add("cc/cflags", find_cc);
dep_add("cc/ldflags", find_cc);
dep_add("cc/inline", find_inline);
dep_add("cc/varargmacro", find_varargmacro);
dep_add("cc/funcmacro", find_funcmacro);
dep_add("cc/constructor", find_constructor);
dep_add("cc/destructor", find_destructor);
dep_add("cc/rdynamic", find_rdynamic);
dep_add("cc/soname", find_soname);
dep_add("cc/wlrpath", find_wlrpath);
dep_add("cc/wloutimplib", find_cc_wloutimplib);
dep_add("cc/wloutputdef", find_cc_wloutputdef);
dep_add("cc/fpic", find_fpic);
dep_add("cc/fpie/*", find_cc_fpie);
dep_add("cc/fnopie/*", find_cc_fnopie);
dep_add("cc/fnopic/*", find_cc_fnopic);
dep_add("cc/alloca/*", find_alloca);
dep_add("cc/_exit/*", find__exit);
dep_add("cc/ldflags_dynlib", find_ldflags_dynlib);
dep_add("cc/ldflags_dll", find_ldflags_dll);
dep_add("cc/ldflags_so", find_ldflags_so);
dep_add("cc/func_attr/unused/*", find_fattr_unused);
dep_add("cc/declspec/dllimport/*", find_declspec_dllimport);
dep_add("cc/declspec/dllexport/*", find_declspec_dllexport);
dep_add("cc/argmachine/*", find_cc_argmachine);
dep_add("cc/pragma_message/*", find_cc_pragma_message);
dep_add("cc/static_libgcc/*", find_cc_static_libgcc);
dep_add("libs/ldl", find_lib_ldl);
dep_add("libs/LoadLibrary/*", find_lib_LoadLibrary);
dep_add("libs/lpthread", find_lib_lpthread);
dep_add("libs/lpthread-recursive", find_lib_lpthread);
dep_add("thread/semget/*", find_thread_semget);
dep_add("thread/pthread_create/*", find_thread_pthread_create);
dep_add("thread/CreateSemaphore/*", find_thread_CreateSemaphore);
dep_add("thread/CreateThread/*", find_thread_CreateThread);
dep_add("libs/errno/*", find_lib_errno);
dep_add("libs/printf_x", find_printf_x);
dep_add("libs/printf_ptrcast", find_printf_ptrcast);
dep_add("libs/snprintf", find_snprintf);
dep_add("libs/snprintf_safe", find_snprintf);
dep_add("libs/dprintf", find_dprintf);
dep_add("libs/vdprintf", find_vdprintf);
dep_add("libs/vsnprintf", find_vsnprintf);
dep_add("libs/proc/_spawnvp/*", find_proc__spawnvp);
dep_add("libs/proc/fork/*", find_proc_fork);
dep_add("libs/proc/wait/*", find_proc_wait);
dep_add("libs/proc/_getpid/*", find_proc__getpid);
dep_add("libs/proc/CreateProcessA/*",find_proc_CreateProcessA);
dep_add("libs/proc/getexecname/*", find_proc_getexecname);
dep_add("libs/proc/GetModuleFileNameA/*",find_proc_GetModuleFileNameA);
dep_add("libs/proc/shmget/*", find_proc_shmget);
dep_add("libs/proc/CreateFileMappingA/*",find_proc_CreateFileMappingA);
dep_add("libs/fs/realpath/*", find_fs_realpath);
dep_add("libs/fs/_fullpath/*", find_fs__fullpath);
dep_add("libs/fs/readdir/*", find_fs_readdir);
dep_add("libs/fs/findnextfile/*", find_fs_findnextfile);
dep_add("libs/fs/stat/macros/*", find_fs_stat_macros);
dep_add("libs/fs/stat/fields/*", find_fs_stat_fields);
dep_add("libs/fs/access/*", find_fs_access);
dep_add("libs/fs/access/macros/*", find_fs_access_macros);
dep_add("libs/fs/lstat/*", find_fs_lstat);
dep_add("libs/fs/statlstat/*", find_fs_statlstat);
dep_add("libs/fs/getcwd/*", find_fs_getcwd);
dep_add("libs/fs/_getcwd/*", find_fs__getcwd);
dep_add("libs/fs/getwd/*", find_fs_getwd);
dep_add("libs/fs/mkdir/*", find_fs_mkdir);
dep_add("libs/fs/_mkdir/*", find_fs__mkdir);
dep_add("libs/fs/mkdtemp/*", find_fs_mkdtemp);
dep_add("libs/fs/mmap/*", find_fs_mmap);
dep_add("libs/fsmount/next_dev/*", find_fsmount_next_dev);
dep_add("libs/fsmount/struct_fsstat/*",find_fsmount_fsstat_fields);
dep_add("libs/fsmount/struct_statfs/*",find_fsmount_statfs_fields);
dep_add("libs/fsmount/struct_statvfs/*",find_fsmount_statvfs_fields);
dep_add("libs/fs/ustat/*", find_fs_ustat);
dep_add("libs/fs/statfs/*", find_fs_statfs);
dep_add("libs/fs/statvfs/*", find_fs_statvfs);
dep_add("libs/fs/flock/*", find_fs_flock);
dep_add("libs/io/pipe/*", find_io_pipe);
dep_add("libs/io/dup2/*", find_io_dup2);
dep_add("libs/io/fileno/*", find_io_fileno);
dep_add("libs/io/lseek/*", find_io_lseek);
dep_add("libs/io/popen/*", find_io_popen);
dep_add("libs/time/usleep/*", find_time_usleep);
dep_add("libs/types/stdint/*", find_types_stdint);
dep_add("sys/types/size/*", find_types_sizes);
dep_add("libs/time/Sleep/*", find_time_Sleep);
dep_add("libs/time/gettimeofday/*", find_time_gettimeofday);
dep_add("libs/time/ftime/*", find_time_ftime);
dep_add("libs/time/timegm/*", find_time_timegm);
dep_add("libs/time/_mkgmtime/*", find_time_mkgmtime);
dep_add("libs/time/gmtime_r/*", find_time_gmtime_r);
dep_add("libs/time/gmtime_s/*", find_time_gmtime_s);
dep_add("libs/time/localtime_r/*", find_time_localtime_r);
dep_add("libs/time/localtime_s/*", find_time_localtime_s);
dep_add("libs/env/main_3arg/*", find_main_arg3);
dep_add("libs/env/putenv/*", find_putenv);
dep_add("libs/env/setenv/*", find_setenv);
dep_add("libs/env/environ/*", find_environ);
dep_add("signal/raise/*", find_signal_raise);
dep_add("signal/names/*", find_signal_names);
dep_add("fstools/cp", find_fstools_cp);
dep_add("fstools/ln", find_fstools_ln);
dep_add("fstools/mv", find_fstools_mv);
dep_add("fstools/rm", find_fstools_rm);
dep_add("fstools/mkdir", find_fstools_mkdir);
dep_add("fstools/ar", find_fstools_ar);
dep_add("fstools/ranlib", find_fstools_ranlib);
dep_add("fstools/awk", find_fstools_awk);
dep_add("fstools/cat", find_fstools_cat);
dep_add("fstools/sed", find_fstools_sed);
dep_add("fstools/file_l", find_fstools_file_l);
dep_add("fstools/file", find_fstools_file);
dep_add("fstools/chmodx", find_fstools_chmodx);
dep_add("sys/name", find_uname);
dep_add("sys/uname", find_uname);
dep_add("sys/triplet", find_triplet);
dep_add("sys/sysid", find_sysid);
dep_add("sys/shell", find_shell);
dep_add("sys/shell_needs_quote", find_shell);
dep_add("sys/tmp", find_tmp);
dep_add("sys/shell_eats_backslash", find_tmp);
dep_add("sys/ext_exe", find_uname);
dep_add("sys/ext_dynlib", find_uname);
dep_add("sys/ext_dynlib_native", find_uname);
dep_add("sys/ext_stalib", find_uname);
dep_add("sys/class", find_uname);
dep_add("sys/path_sep", find_uname);
dep_add("sys/ptrwidth", find_sys_ptrwidth);
dep_add("sys/byte_order", find_sys_byte_order);
dep_add("sys/types/size_t/*", find_types_size_t);
dep_add("sys/types/off_t/*", find_types_off_t);
dep_add("sys/types/off64_t/*", find_types_off64_t);
dep_add("sys/types/gid_t/*", find_types_gid_t);
dep_add("sys/types/uid_t/*", find_types_uid_t);
dep_add("sys/types/pid_t/*", find_types_pid_t);
dep_add("sys/types/mode_t/*", find_types_mode_t);
dep_add("sys/types/nlink_t/*", find_types_nlink_t);
dep_add("sys/types/ptrdiff_t/*", find_types_ptrdiff_t);
dep_add("sys/types/dev_t/*", find_types_dev_t);
dep_add("sys/types/ino_t/*", find_types_ino_t);
dep_add("sys/types/void_ptr/*", find_types_void_ptr);
dep_add("str/strcasecmp/*", find_strcasecmp);
dep_add("str/strncasecmp/*", find_strncasecmp);
dep_add("str/stricmp/*", find_stricmp);
dep_add("str/strnicmp/*", find_strnicmp);
dep_add("/internal/filelist/cmd", find_filelist);
dep_add("/internal/filelist/method", find_filelist);
}

View File

@ -1,172 +0,0 @@
/* cc */
int find_cc(const char *name, int logdepth, int fatal);
int find_cc_argstd(const char *name, int logdepth, int fatal);
int find_cc_argmachine(const char *name, int logdepth, int fatal);
int find_cc_fpie(const char *name, int logdepth, int fatal);
int find_cc_fnopie(const char *name, int logdepth, int fatal);
int find_cc_fnopic(const char *name, int logdepth, int fatal);
int find_inline(const char *name, int logdepth, int fatal);
int find_varargmacro(const char *name, int logdepth, int fatal);
int find_funcmacro(const char *name, int logdepth, int fatal);
int find_constructor(const char *name, int logdepth, int fatal);
int find_destructor(const char *name, int logdepth, int fatal);
int find_fattr_unused(const char *name, int logdepth, int fatal);
int find_declspec_dllimport(const char *name, int logdepth, int fatal);
int find_declspec_dllexport(const char *name, int logdepth, int fatal);
int find_rdynamic(const char *name, int logdepth, int fatal);
int find_soname(const char *name, int logdepth, int fatal);
int find_so_undefined(const char *name, int logdepth, int fatal);
int find_wlrpath(const char *name, int logdepth, int fatal);
int find_cc_wloutimplib(const char *name, int logdepth, int fatal);
int find_cc_wloutputdef(const char *name, int logdepth, int fatal);
int find_fpic(const char *name, int logdepth, int fatal);
int find_ldflags_dynlib(const char *name, int logdepth, int fatal);
int find_ldflags_dll(const char *name, int logdepth, int fatal);
int find_ldflags_so(const char *name, int logdepth, int fatal);
int find_alloca(const char *name, int logdepth, int fatal);
int find__exit(const char *name, int logdepth, int fatal);
int find_cc_pragma_message(const char *name, int logdepth, int fatal);
int find_cc_static_libgcc(const char *name, int logdepth, int fatal);
/* libs */
int find_lib_ldl(const char *name, int logdepth, int fatal);
int find_lib_LoadLibrary(const char *name, int logdepth, int fatal);
int find_lib_errno(const char *name, int logdepth, int fatal);
/* thread */
int find_lib_lpthread(const char *name, int logdepth, int fatal);
int find_thread_semget(const char *name, int logdepth, int fatal);
int find_thread_pthread_create(const char *name, int logdepth, int fatal);
int find_thread_CreateSemaphore(const char *name, int logdepth, int fatal);
int find_thread_CreateThread(const char *name, int logdepth, int fatal);
/* fscalls */
int find_fs_realpath(const char *name, int logdepth, int fatal);
int find_fs__fullpath(const char *name, int logdepth, int fatal);
int find_fs_readdir(const char *name, int logdepth, int fatal);
int find_fs_findnextfile(const char *name, int logdepth, int fatal);
int find_fs_access(const char *name, int logdepth, int fatal);
int find_fs_access_macros(const char *name, int logdepth, int fatal);
int find_fs_stat_macros(const char *name, int logdepth, int fatal);
int find_fs_stat_fields(const char *name, int logdepth, int fatal);
int find_fs_lstat(const char *name, int logdepth, int fatal);
int find_fs_statlstat(const char *name, int logdepth, int fatal);
int find_fs_getcwd(const char *name, int logdepth, int fatal);
int find_fs__getcwd(const char *name, int logdepth, int fatal);
int find_fs_getwd(const char *name, int logdepth, int fatal);
int find_fs_mkdir(const char *name, int logdepth, int fatal);
int find_fs__mkdir(const char *name, int logdepth, int fatal);
int find_fs_mkdtemp(const char *name, int logdepth, int fatal);
int find_fs_mmap(const char *name, int logdepth, int fatal);
int find_fsmount_next_dev(const char *name, int logdepth, int fatal);
int find_fsmount_fsstat_fields(const char *name, int logdepth, int fatal);
int find_fsmount_statfs_fields(const char *name, int logdepth, int fatal);
int find_fsmount_statvfs_fields(const char *name, int logdepth, int fatal);
int find_fs_ustat(const char *name, int logdepth, int fatal);
int find_fs_statfs(const char *name, int logdepth, int fatal);
int find_fs_statvfs(const char *name, int logdepth, int fatal);
int find_fs_flock(const char *name, int logdepth, int fatal);
/* printf */
int find_printf_x(const char *name, int logdepth, int fatal);
int find_printf_ptrcast(const char *name, int logdepth, int fatal);
int find_snprintf(const char *name, int logdepth, int fatal);
int find_dprintf(const char *name, int logdepth, int fatal);
int find_vdprintf(const char *name, int logdepth, int fatal);
int find_vsnprintf(const char *name, int logdepth, int fatal);
/* proc */
int find_proc__spawnvp(const char *name, int logdepth, int fatal);
int find_proc_fork(const char *name, int logdepth, int fatal);
int find_proc_wait(const char *name, int logdepth, int fatal);
int find_proc__getpid(const char *name, int logdepth, int fatal);
int find_proc_CreateProcessA(const char *name, int logdepth, int fatal);
int find_proc_getexecname(const char *name, int logdepth, int fatal);
int find_proc_GetModuleFileNameA(const char *name, int logdepth, int fatal);
int find_proc_shmget(const char *name, int logdepth, int fatal);
int find_proc_CreateFileMappingA(const char *name, int logdepth, int fatal);
/* fstools */
int find_fstools_cp(const char *name, int logdepth, int fatal);
int find_fstools_ln(const char *name, int logdepth, int fatal);
int find_fstools_mv(const char *name, int logdepth, int fatal);
int find_fstools_rm(const char *name, int logdepth, int fatal);
int find_fstools_mkdir(const char *name, int logdepth, int fatal);
int find_fstools_ar(const char *name, int logdepth, int fatal);
int find_fstools_ranlib(const char *name, int logdepth, int fatal);
int find_fstools_awk(const char *name, int logdepth, int fatal);
int find_fstools_cat(const char *name, int logdepth, int fatal);
int find_fstools_sed(const char *name, int logdepth, int fatal);
int find_fstools_file(const char *name, int logdepth, int fatal);
int find_fstools_file_l(const char *name, int logdepth, int fatal);
int find_fstools_chmodx(const char *name, int logdepth, int fatal);
/* uname */
int find_uname(const char *name, int logdepth, int fatal);
int find_triplet(const char *name, int logdepth, int fatal);
int find_sysid(const char *name, int logdepth, int fatal);
/* find_target */
int find_target(const char *name, int logdepth, int fatal);
/* filelist */
int find_filelist(const char *name, int logdepth, int fatal);
/* find_str.c */
int find_strcasecmp(const char *name, int logdepth, int fatal);
int find_strncasecmp(const char *name, int logdepth, int fatal);
int find_stricmp(const char *name, int logdepth, int fatal);
int find_strnicmp(const char *name, int logdepth, int fatal);
/* find_sys.c */
int find_sys_ptrwidth(const char *name, int logdepth, int fatal);
int find_sys_byte_order(const char *name, int logdepth, int fatal);
int find_tmp(const char *name, int logdepth, int fatal);
int find_shell(const char *name, int logdepth, int fatal);
/* find_io.c */
int find_io_pipe(const char *name, int logdepth, int fatal);
int find_io_dup2(const char *name, int logdepth, int fatal);
int find_io_fileno(const char *name, int logdepth, int fatal);
int find_io_lseek(const char *name, int logdepth, int fatal);
int find_io_popen(const char *name, int logdepth, int fatal);
/* find_time.c */
int find_time_usleep(const char *name, int logdepth, int fatal);
int find_time_Sleep(const char *name, int logdepth, int fatal);
int find_time_gettimeofday(const char *name, int logdepth, int fatal);
int find_time_ftime(const char *name, int logdepth, int fatal);
int find_time_timegm(const char *name, int logdepth, int fatal);
int find_time_mkgmtime(const char *name, int logdepth, int fatal);
int find_time_gmtime_s(const char *name, int logdepth, int fatal);
int find_time_gmtime_r(const char *name, int logdepth, int fatal);
int find_time_localtime_s(const char *name, int logdepth, int fatal);
int find_time_localtime_r(const char *name, int logdepth, int fatal);
/* find_types.c */
int find_types_stdint(const char *name, int logdepth, int fatal);
int find_types_sizes(const char *name, int logdepth, int fatal);
int find_types_size_t(const char *name, int logdepth, int fatal);
int find_types_off_t(const char *name, int logdepth, int fatal);
int find_types_off64_t(const char *name, int logdepth, int fatal);
int find_types_gid_t(const char *name, int logdepth, int fatal);
int find_types_uid_t(const char *name, int logdepth, int fatal);
int find_types_pid_t(const char *name, int logdepth, int fatal);
int find_types_dev_t(const char *name, int logdepth, int fatal);
int find_types_dev_t(const char *name, int logdepth, int fatal);
int find_types_mode_t(const char *name, int logdepth, int fatal);
int find_types_nlink_t(const char *name, int logdepth, int fatal);
int find_types_ptrdiff_t(const char *name, int logdepth, int fatal);
int find_types_dev_t(const char *name, int logdepth, int fatal);
int find_types_ino_t(const char *name, int logdepth, int fatal);
int find_types_void_ptr(const char *name, int logdepth, int fatal);
/* find_signal.c */
int find_signal_names(const char *name, int logdepth, int fatal);
int find_signal_raise(const char *name, int logdepth, int fatal);
/* environ.c */
int find_main_arg3(const char *name, int logdepth, int fatal);
int find_putenv(const char *name, int logdepth, int fatal);
int find_setenv(const char *name, int logdepth, int fatal);
int find_environ(const char *name, int logdepth, int fatal);

View File

@ -1,181 +0,0 @@
/*
scconfig - dependency list of default tests
Copyright (C) 2009..2012 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include "dep.h"
#include "find.h"
void deps_default_init(void)
{
dep_add("cc/cc", find_cc);
dep_add("cc/argstd/*", find_cc_argstd);
dep_add("cc/cflags", find_cc);
dep_add("cc/ldflags", find_cc);
dep_add("cc/inline", find_inline);
dep_add("cc/varargmacro", find_varargmacro);
dep_add("cc/funcmacro", find_funcmacro);
dep_add("cc/constructor", find_constructor);
dep_add("cc/destructor", find_destructor);
dep_add("cc/rdynamic", find_rdynamic);
dep_add("cc/soname", find_soname);
dep_add("cc/so_undefined", find_so_undefined);
dep_add("cc/wlrpath", find_wlrpath);
dep_add("cc/wloutimplib", find_cc_wloutimplib);
dep_add("cc/wloutputdef", find_cc_wloutputdef);
dep_add("cc/fpic", find_fpic);
dep_add("cc/fpie/*", find_cc_fpie);
dep_add("cc/fnopie/*", find_cc_fnopie);
dep_add("cc/fnopic/*", find_cc_fnopic);
dep_add("cc/alloca/*", find_alloca);
dep_add("cc/_exit/*", find__exit);
dep_add("cc/ldflags_dynlib", find_ldflags_dynlib);
dep_add("cc/ldflags_dll", find_ldflags_dll);
dep_add("cc/ldflags_so", find_ldflags_so);
dep_add("cc/func_attr/unused/*", find_fattr_unused);
dep_add("cc/declspec/dllimport/*", find_declspec_dllimport);
dep_add("cc/declspec/dllexport/*", find_declspec_dllexport);
dep_add("cc/argmachine/*", find_cc_argmachine);
dep_add("cc/pragma_message/*", find_cc_pragma_message);
dep_add("cc/static_libgcc/*", find_cc_static_libgcc);
dep_add("libs/ldl", find_lib_ldl);
dep_add("libs/LoadLibrary/*", find_lib_LoadLibrary);
dep_add("libs/lpthread", find_lib_lpthread);
dep_add("libs/lpthread-recursive", find_lib_lpthread);
dep_add("thread/semget/*", find_thread_semget);
dep_add("thread/pthread_create/*", find_thread_pthread_create);
dep_add("thread/CreateSemaphore/*", find_thread_CreateSemaphore);
dep_add("thread/CreateThread/*", find_thread_CreateThread);
dep_add("libs/errno/*", find_lib_errno);
dep_add("libs/printf_x", find_printf_x);
dep_add("libs/printf_ptrcast", find_printf_ptrcast);
dep_add("libs/snprintf", find_snprintf);
dep_add("libs/snprintf_safe", find_snprintf);
dep_add("libs/dprintf", find_dprintf);
dep_add("libs/vdprintf", find_vdprintf);
dep_add("libs/vsnprintf", find_vsnprintf);
dep_add("libs/proc/_spawnvp/*", find_proc__spawnvp);
dep_add("libs/proc/fork/*", find_proc_fork);
dep_add("libs/proc/wait/*", find_proc_wait);
dep_add("libs/proc/_getpid/*", find_proc__getpid);
dep_add("libs/proc/CreateProcessA/*",find_proc_CreateProcessA);
dep_add("libs/proc/getexecname/*", find_proc_getexecname);
dep_add("libs/proc/GetModuleFileNameA/*",find_proc_GetModuleFileNameA);
dep_add("libs/proc/shmget/*", find_proc_shmget);
dep_add("libs/proc/CreateFileMappingA/*",find_proc_CreateFileMappingA);
dep_add("libs/fs/realpath/*", find_fs_realpath);
dep_add("libs/fs/_fullpath/*", find_fs__fullpath);
dep_add("libs/fs/readdir/*", find_fs_readdir);
dep_add("libs/fs/findnextfile/*", find_fs_findnextfile);
dep_add("libs/fs/stat/macros/*", find_fs_stat_macros);
dep_add("libs/fs/stat/fields/*", find_fs_stat_fields);
dep_add("libs/fs/access/*", find_fs_access);
dep_add("libs/fs/access/macros/*", find_fs_access_macros);
dep_add("libs/fs/lstat/*", find_fs_lstat);
dep_add("libs/fs/statlstat/*", find_fs_statlstat);
dep_add("libs/fs/getcwd/*", find_fs_getcwd);
dep_add("libs/fs/_getcwd/*", find_fs__getcwd);
dep_add("libs/fs/getwd/*", find_fs_getwd);
dep_add("libs/fs/mkdir/*", find_fs_mkdir);
dep_add("libs/fs/_mkdir/*", find_fs__mkdir);
dep_add("libs/fs/mkdtemp/*", find_fs_mkdtemp);
dep_add("libs/fs/mmap/*", find_fs_mmap);
dep_add("libs/fsmount/next_dev/*", find_fsmount_next_dev);
dep_add("libs/fsmount/struct_fsstat/*",find_fsmount_fsstat_fields);
dep_add("libs/fsmount/struct_statfs/*",find_fsmount_statfs_fields);
dep_add("libs/fsmount/struct_statvfs/*",find_fsmount_statvfs_fields);
dep_add("libs/fs/ustat/*", find_fs_ustat);
dep_add("libs/fs/statfs/*", find_fs_statfs);
dep_add("libs/fs/statvfs/*", find_fs_statvfs);
dep_add("libs/fs/flock/*", find_fs_flock);
dep_add("libs/io/pipe/*", find_io_pipe);
dep_add("libs/io/dup2/*", find_io_dup2);
dep_add("libs/io/fileno/*", find_io_fileno);
dep_add("libs/io/lseek/*", find_io_lseek);
dep_add("libs/io/popen/*", find_io_popen);
dep_add("libs/time/usleep/*", find_time_usleep);
dep_add("libs/types/stdint/*", find_types_stdint);
dep_add("sys/types/size/*", find_types_sizes);
dep_add("libs/time/Sleep/*", find_time_Sleep);
dep_add("libs/time/gettimeofday/*", find_time_gettimeofday);
dep_add("libs/time/ftime/*", find_time_ftime);
dep_add("libs/time/timegm/*", find_time_timegm);
dep_add("libs/time/_mkgmtime/*", find_time_mkgmtime);
dep_add("libs/time/gmtime_r/*", find_time_gmtime_r);
dep_add("libs/time/gmtime_s/*", find_time_gmtime_s);
dep_add("libs/time/localtime_r/*", find_time_localtime_r);
dep_add("libs/time/localtime_s/*", find_time_localtime_s);
dep_add("libs/env/main_3arg/*", find_main_arg3);
dep_add("libs/env/putenv/*", find_putenv);
dep_add("libs/env/setenv/*", find_setenv);
dep_add("libs/env/environ/*", find_environ);
dep_add("signal/raise/*", find_signal_raise);
dep_add("signal/names/*", find_signal_names);
dep_add("fstools/cp", find_fstools_cp);
dep_add("fstools/ln", find_fstools_ln);
dep_add("fstools/mv", find_fstools_mv);
dep_add("fstools/rm", find_fstools_rm);
dep_add("fstools/mkdir", find_fstools_mkdir);
dep_add("fstools/ar", find_fstools_ar);
dep_add("fstools/ranlib", find_fstools_ranlib);
dep_add("fstools/awk", find_fstools_awk);
dep_add("fstools/cat", find_fstools_cat);
dep_add("fstools/sed", find_fstools_sed);
dep_add("fstools/file_l", find_fstools_file_l);
dep_add("fstools/file", find_fstools_file);
dep_add("fstools/chmodx", find_fstools_chmodx);
dep_add("sys/name", find_uname);
dep_add("sys/uname", find_uname);
dep_add("sys/triplet", find_triplet);
dep_add("sys/sysid", find_sysid);
dep_add("sys/shell", find_shell);
dep_add("sys/shell_needs_quote", find_shell);
dep_add("sys/tmp", find_tmp);
dep_add("sys/shell_eats_backslash", find_tmp);
dep_add("sys/ext_exe", find_uname);
dep_add("sys/ext_dynlib", find_uname);
dep_add("sys/ext_dynlib_native", find_uname);
dep_add("sys/ext_stalib", find_uname);
dep_add("sys/class", find_uname);
dep_add("sys/path_sep", find_uname);
dep_add("sys/ptrwidth", find_sys_ptrwidth);
dep_add("sys/byte_order", find_sys_byte_order);
dep_add("sys/types/size_t/*", find_types_size_t);
dep_add("sys/types/off_t/*", find_types_off_t);
dep_add("sys/types/off64_t/*", find_types_off64_t);
dep_add("sys/types/gid_t/*", find_types_gid_t);
dep_add("sys/types/uid_t/*", find_types_uid_t);
dep_add("sys/types/pid_t/*", find_types_pid_t);
dep_add("sys/types/mode_t/*", find_types_mode_t);
dep_add("sys/types/nlink_t/*", find_types_nlink_t);
dep_add("sys/types/ptrdiff_t/*", find_types_ptrdiff_t);
dep_add("sys/types/dev_t/*", find_types_dev_t);
dep_add("sys/types/ino_t/*", find_types_ino_t);
dep_add("sys/types/void_ptr/*", find_types_void_ptr);
dep_add("str/strcasecmp/*", find_strcasecmp);
dep_add("str/strncasecmp/*", find_strncasecmp);
dep_add("str/stricmp/*", find_stricmp);
dep_add("str/strnicmp/*", find_strnicmp);
dep_add("/internal/filelist/cmd", find_filelist);
dep_add("/internal/filelist/method", find_filelist);
}

View File

@ -1,410 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
/* Returns true if the first 2 characters of the output is OK */
static int try_icl_accept_ok(char *stdout_str)
{
return (strncmp(stdout_str, "OK", 2) == 0);
}
#define is_ctrl_prefix(ch) (((ch) == '!') || ((ch) == '^'))
static int try_icl__(int logdepth, const char *prefix, const char *test_c_in, const char *includes, const char *cflags, const char *ldflags, const char *db_includes, const char *db_cflags, const char *db_ldflags, int run, int (*accept_res)(char *stdout_str))
{
char *out = NULL;
char *tmp, *inc;
const char *test_c;
char c[1024];
int l, compres;
if (includes != NULL) {
l = strlen(includes);
memcpy(c, includes, l);
c[l] = '\n';
l++;
strcpy(c+l, test_c_in);
test_c = c;
}
else
test_c = test_c_in;
logprintf(logdepth, "trying '%s' and '%s' and '%s', %s\n", str_null(db_includes), str_null(db_cflags), str_null(db_ldflags), run ? "with a run" : "with no run");
if (run)
compres = compile_run(logdepth+1, test_c, NULL, cflags, ldflags, &out);
else {
char *fn_output = NULL;
compres = compile_code(logdepth+1, test_c, &fn_output, NULL, cflags, ldflags);
if (fn_output != NULL) {
unlink(fn_output);
free(fn_output);
}
}
if (compres == 0) {
if (!run || target_emu_fail(out) || accept_res(out)) {
free(out);
/* no prefix: don't modify the database, the caller will do that */
if (prefix == NULL)
return 1;
tmp = malloc(strlen(prefix) + 32);
if ((db_includes == NULL) || (*db_includes == '\0'))
inc = strclone("");
else
inc = uniq_inc_str(db_includes, NULL, "\\n", 0, 0, NULL);
sprintf(tmp, "%s/includes", prefix);
put(tmp, inc);
if (db_cflags == NULL)
db_cflags = "";
sprintf(tmp, "%s/cflags", prefix);
put(tmp, db_cflags);
if (db_ldflags == NULL)
db_ldflags = "";
sprintf(tmp, "%s/ldflags", prefix);
put(tmp, db_ldflags);
if (inc != NULL) {
report("OK ('%s', '%s' and '%s')\n", str_null(inc), str_null(db_cflags), str_null(db_ldflags));
free(inc);
}
else
report("OK ('%s' and '%s')\n", str_null(db_cflags), str_null(db_ldflags));
sprintf(tmp, "%s/presents", prefix);
put(tmp, strue);
free(tmp);
return 1;
}
free(out);
}
return 0;
}
#define LOAD(node) \
do { \
if (u ## node != NULL) break; \
strcpy(apath_end, #node); \
u ## node = get(apath); \
} while(0)
#define SET(dst, src, is_flag) \
do { \
char *__sep__ = is_flag ? " " : "\n"; \
const char *__dst__ = dst == NULL ? "" : dst; \
char *__out__; \
if (is_ctrl_prefix(*__dst__)) __dst__++; \
if (*src == '!') \
__out__ = strclone(src+1); \
else if (*src == '^') {\
if (src[1] != '\0') \
__out__ = str_concat("", src+1, __sep__, __dst__, NULL); \
else \
__out__ = strclone(__dst__); \
} \
else { \
if (*__dst__ != '\0') \
__out__ = str_concat("", __dst__, __sep__, src, NULL); \
else \
__out__ = strclone(src); \
} \
free(dst); \
dst = __out__; \
if (is_flag) { \
char *__s__; \
for(__s__ = dst; *__s__ != '\0'; __s__++) \
if ((*__s__ == '\n') || (*__s__ == '\r')) \
*__s__ = ' '; \
} \
} while(0)
/* Figure user overrides and call try_icl__() accordingly */
int try_icl_(int logdepth, const char *prefix, const char *test_c_in, const char *includes, const char *cflags, const char *ldflags, int run, int (*accept_res)(char *stdout_str))
{
char apath[1024], *apath_end;
int l, res;
const char *uincludes = NULL, *ucflags = NULL, *uldflags = NULL, *uprefix = NULL; /* user specified */
char *rincludes, *rcflags, *rldflags; /* real */
char *dbincludes = NULL, *dbcflags = NULL, *dbldflags = NULL; /* what to add in the db at the end */
/* load uincludes, uclfags, uldflags and uprefix - LOAD() inserts the u */
l = sprintf(apath, "/arg/icl/%s/", prefix); apath_end = apath+l;
LOAD(includes);
LOAD(cflags);
LOAD(ldflags);
LOAD(prefix);
l = sprintf(apath, "/arg/icl/%s/%s/", db_cwd, prefix); apath_end = apath+l;
LOAD(includes);
LOAD(cflags);
LOAD(ldflags);
LOAD(prefix);
/* special case: all three specified by the user - ignore what the detector wanted, but run only once per node prefix */
if ((uincludes != NULL) && (ucflags != NULL) && (uldflags != NULL)) {
const char *am;
sprintf(apath, "%s/icl/all_manual_result", prefix);
am = get(apath);
if (am != NULL)
return istrue(am); /* return cached result if available */
res = try_icl__(logdepth, prefix, test_c_in, uincludes, ucflags, uldflags, uincludes, ucflags, uldflags, run, accept_res);
put(apath, res ? strue : sfalse);
return res;
}
/* TODO: get default cflags here */
rincludes = NULL;
rcflags = strclone(get("cc/cflags"));
rldflags = strclone(get("cc/ldflags"));
/* override base/default values with detection requested ones */
if (includes != NULL) SET(rincludes, includes, 0);
if (cflags != NULL) SET(rcflags, cflags, 1);
if (ldflags != NULL) SET(rldflags, ldflags, 1);
if (includes != NULL) SET(dbincludes, includes, 0);
if (cflags != NULL) SET(dbcflags, cflags, 1);
if (ldflags != NULL) SET(dbldflags, ldflags, 1);
/* override detection with user specified ICL values */
if (uincludes != NULL) SET(rincludes, uincludes, 0);
if (ucflags != NULL) SET(rcflags, ucflags, 1);
if (uldflags != NULL) SET(rldflags, uldflags, 1);
if (uincludes != NULL) SET(dbincludes, uincludes, 0);
if (ucflags != NULL) SET(dbcflags, ucflags, 1);
if (uldflags != NULL) SET(dbldflags, uldflags, 1);
/* insert prefix as needed */
if (uprefix != NULL) {
char *old, *prfx;
old = rcflags;
if ((rcflags != NULL) && (*rcflags == '^')) {
rcflags++;
prfx = "^";
}
else
prfx = "";
rcflags = str_concat("", prfx, "-I", uprefix, "/include ", rcflags, NULL);
if (old != cflags) free(old);
old = rldflags;
if ((rldflags != NULL) && (*rldflags == '^')) {
rldflags++;
prfx = "^";
}
else
prfx = "";
rldflags = str_concat("", prfx, "-L", uprefix, "/lib ", rldflags, NULL);
if (old != ldflags) free(old);
}
res = try_icl__(logdepth, prefix, test_c_in, rincludes, rcflags, rldflags, dbincludes, dbcflags, dbldflags, run, accept_res);
/* if we had to alloc, free here */
free(rincludes);
free(rcflags);
free(rldflags);
free(dbincludes);
free(dbcflags);
free(dbldflags);
return res;
}
#undef LOAD
#undef SET
int try_icl(int logdepth, const char *prefix, const char *test_c_in, const char *includes, const char *cflags, const char *ldflags)
{
return try_icl_(logdepth, prefix, test_c_in, includes, cflags, ldflags, 1, try_icl_accept_ok);
}
int try_icl_with_deps(int logdepth, const char *prefix, const char *test_c_in, const char *includes, const char *cflags, const char *ldflags, const char *dep_includes, const char *dep_cflags, const char *dep_ldflags, int run)
{
int res;
if ((dep_includes != NULL) && (*dep_includes == '\0')) dep_includes = NULL;
if ((dep_cflags != NULL) && (*dep_cflags == '\0')) dep_cflags = NULL;
if ((dep_ldflags != NULL) && (*dep_ldflags == '\0')) dep_ldflags = NULL;
if (dep_includes != NULL) includes = str_concat(" ", dep_includes, includes, NULL);
if (dep_cflags != NULL) cflags = str_concat(" ", dep_cflags, cflags, NULL);
if (dep_ldflags != NULL) ldflags = str_concat(" ", dep_ldflags, ldflags, NULL);
res = try_icl_(logdepth, prefix, test_c_in, includes, cflags, ldflags, run, try_icl_accept_ok);
if (dep_includes != NULL) free((char *)includes);
if (dep_cflags != NULL) free((char *)cflags);
if (dep_ldflags != NULL) free((char *)ldflags);
return res;
}
int try_icl_norun(int logdepth, const char *prefix, const char *test_c_in, const char *includes, const char *cflags, const char *ldflags)
{
return try_icl_(logdepth, prefix, test_c_in, includes, cflags, ldflags, 0, try_icl_accept_ok);
}
int try_fail(int logdepth, const char *prefix)
{
char *tmp;
tmp = malloc(strlen(prefix) + 32);
sprintf(tmp, "%s/presents", prefix);
put(tmp, sfalse);
free(tmp);
report("not found\n");
logprintf(logdepth, "NOT FOUND.");
return 1;
}
static int try_pkg_config_(int logdepth, char *pkgname, const char *prefix, const char *test_c)
{
char *cflags, *ldflags;
int res;
logprintf(logdepth, "Trying pkg-config %s\n", pkgname);
if (run_pkg_config(logdepth+1, pkgname, &cflags, &ldflags) == 0)
res = try_icl(logdepth+1, prefix, test_c, NULL, cflags, ldflags);
else
res = 0;
free(cflags);
free(ldflags);
return res;
}
int try_icl_pkg_config(int logdepth, const char *prefix, const char *test_c, char *includes, const char *pkgpat, const char *reqver)
{
char **pkg_ver, **s;
int num_pkg_ver;
int res = 0;
(void) includes; /* not used */
run_pkg_config_lst(logdepth, pkgpat, &num_pkg_ver, &pkg_ver);
if (pkg_ver == NULL)
return 0;
if (reqver != NULL) {
/* search the list for the preferred version */
for(s = pkg_ver; *s != NULL; s+=2) {
if (strcmp(s[1], reqver) == 0) {
if (try_pkg_config_(logdepth, s[0], prefix, test_c)) {
res = 1;
report("Found version required (%s) using pkg_config.\n", reqver);
goto out;
}
else {
report("The version required (%s) is found (via pkg_config) but does not work\n", reqver);
goto out;
}
}
}
goto out;
}
for(s = pkg_ver; *s != NULL; s+=2) {
if (try_pkg_config_(logdepth, s[0], prefix, test_c)) {
res = 1;
goto out;
}
}
out:;
filelist_free(&num_pkg_ver, &pkg_ver);
return res;
}
int import_icl(const char *key, const char *fn)
{
char path[1024];
switch(*key) {
case 'l': sprintf(path, "/arg/icl/%s/ldflags", key+8); break;
case 'c': sprintf(path, "/arg/icl/%s/cflags", key+7); break;
case 'i': sprintf(path, "/arg/icl/%s/includes", key+9); break;
case 'p': sprintf(path, "/arg/icl/%s/prefix", key+7); break;
default:
return 1;
}
printf("path='%s' fn='%s'\n", path, fn);
return put(path, fn) == NULL;
}
static long field_accept_len;
static int field_accept_res(char *stdout_str)
{
char *end;
field_accept_len = strtol(stdout_str, &end, 10);
if (((*end == '\0') || (*end == '\r') || (*end == '\n')) && (field_accept_len > 0))
return 1;
return 0;
}
int try_icl_sfield(int logdepth, const char *prefix, const char *structn, const char *fieldn, const char *includes, const char *cflags, const char *ldflags)
{
int res;
char test_c[512];
char ls[16];
const char *test_c_in =
NL "#include <stdio.h>"
NL "int main()"
NL "{"
NL " %s s;"
NL " printf(\"%%ld\\n\", (long)sizeof(s.%s));"
NL "}"
NL;
sprintf(test_c, test_c_in, structn, fieldn);
res = try_icl_(logdepth, prefix, test_c, includes, cflags, ldflags, 1, field_accept_res);
if (res) {
sprintf(test_c, "%s/sizeof", prefix);
sprintf(ls, "%ld", field_accept_len);
put(test_c, ls);
}
return res;
}
int try_icl_sfields(int logdepth, const char *prefix, const char *structn, const char **fields, const char *includes, const char *cflags, const char *ldflags, int silent_exit_first_fail)
{
int succ = 0, first = 1;
require("cc/cc", logdepth, 1);
for(; *fields != NULL; fields++) {
report("Checking for %s.%s... ", structn, *fields);
logprintf(logdepth, "%s: checking for field %s...\n", structn, *fields);
logdepth++;
if (try_icl_sfield(logdepth, prefix, structn, *fields, includes, cflags, ldflags)) {
succ = 1;
}
else if ((silent_exit_first_fail) && (first)) {
return 1;
}
logdepth--;
first = 0;
}
if (!succ)
try_fail(logdepth, "libs/fsmount/next_dev");
return 0;
}

View File

@ -1,51 +0,0 @@
#ifndef STR_HT_H
#define STR_HT_H
/* char * -> void * open addressing hashtable */
/* keys and values are strdupped (strcloned) */
#define ht_deleted_key ((char *)1)
#define ht_isused(e) ((e)->key && (e)->key != ht_deleted_key)
#define ht_isempty(e) (((e)->key == NULL) || (e)->key == ht_deleted_key)
#define ht_isdeleted(e) ((e)->key == ht_deleted_key)
typedef struct {
unsigned int hash;
char *key;
void *value;
} ht_entry_t;
typedef struct {
unsigned int mask;
unsigned int fill;
unsigned int used;
int isstr;
ht_entry_t *table;
int refcount;
} ht_t;
ht_t *ht_alloc(int isstr);
void ht_free(ht_t *ht);
ht_t *ht_clear(ht_t *ht);
ht_t *ht_resize(ht_t *ht, unsigned int hint);
/* value of ht[key], NULL if key is empty or deleted */
void *ht_get(ht_t *ht, const char *key);
/* ht[key] = value and return NULL or return ht[key] if key is already used */
void *ht_insert(ht_t *ht, const char *key, void *value);
/* ht[key] = value and return a pointer to the strdupped key */
const char *ht_set(ht_t *ht, const char *key, void *value);
/* delete key and return ht_deleted_key or NULL if key was not used */
const char *ht_del(ht_t *ht, const char *key);
/* iteration */
#define foreach(ht, e) \
for (e = (ht)->table; e != (ht)->table + (ht)->mask + 1; e++) \
if (ht_isused(e))
/* first used (useful for iteration) NULL if empty */
ht_entry_t *ht_first(const ht_t *ht);
/* next used (useful for iteration) NULL if there is no more used */
ht_entry_t *ht_next(const ht_t *ht, ht_entry_t *entry);
#endif

View File

@ -1,355 +0,0 @@
/*
scconfig - evaluate uname and classify the system
Copyright (C) 2009 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "regex.h"
#include "log.h"
#include "db.h"
#include "libs.h"
#include "dep.h"
static void sys_unix(void)
{
put("sys/ext_exe", "");
put("sys/ext_dynlib", ".so");
put("sys/ext_stalib", ".a");
put("sys/ext_dynlib_native", ".so");
}
static void sys_netbsd(void)
{
sys_unix();
put("cc/ldflags", "-Wl,-R/usr/pkg/lib -L/usr/pkg/lib"); /* TODO: is this the best way? */
}
static void sys_win32dlc(void)
{
put("sys/ext_exe", ".exe");
put("sys/ext_dynlib", ".dlc");
put("sys/ext_stalib", ".a");
put("sys/ext_dynlib_native", ".dll");
}
typedef void (*callback_t)(void);
typedef struct {
char *uname_regex;
char *name;
char *class;
callback_t callback;
} uname_t;
typedef struct {
char *file_name;
char *name;
char *class;
callback_t callback;
} magic_file_t;
/* Guess system class by uname; class is informative, nothing important
should depend on it.
Order *does* matter */
uname_t unames[] = {
{"[Nn]et[Bb][Ss][Dd]", "NetBSD", "UNIX", sys_netbsd},
{"[Ll]inux", "Linux", "UNIX", sys_unix},
{"[Bb][Ss][Dd]", "BSD", "UNIX", sys_unix},
{"SunOS", "SunOS", "UNIX", sys_unix},
{"OSF1", "OSF", "UNIX", sys_unix}, /* TODO: note the difference in cflags for debugging ("-ms -g") */
{"IRIX", "IRIX", "UNIX", sys_unix},
{"SunOS", "SunOS", "UNIX", sys_unix},
{"[Mm]inix", "Minix", "UNIX", sys_unix},
{"[Aa][Rr][Oo][Ss]", "Aros", "UNIX", sys_unix},
{"^Darwin", "MacOSX", "UNIX", sys_unix},
{"[Th]hreos", "Threos", "UNIX", sys_unix},
{"[Cc]ygwin", "cygwin", "WIN32", sys_win32dlc},
{"[Mm][Ii][Nn][Gg][Ww]", "mingw", "WIN32", sys_win32dlc},
{"win32", "win32", "WIN32", sys_win32dlc}, /* vanilla windows */
{NULL, NULL, NULL, NULL}
};
/* Fallback: extract machine name from uname -a if uname -m fails */
static const char *machine_names[] = {
"i[0-9]86[^ ]*", "x86_[^ ]*", "amd[0-9]*", "armv[0-9][^ ]*", "ppc[0-9]+",
"sparc[0-9]*", "BePC", "ia64", "x86", "IP[0-9]*", "k1om", "sun4u",
"RM600", "R4000", "alpha",
NULL
};
/* Fallback: extract system name from uname -a if uname -s fails */
static const char *system_names[] = {
"[Ll]inux", "sn5[0-9]*", "CYGWIN_NT[^ ]*", "GNU[^ ]*", "DragonFly",
"[^ ]*BSD[^ ]*", "Haiku", "HP-UX", "AIX", "OS4000", "Interix",
"IRIX[0-9]*", "Darwin", "Minix", "MINGW[^ ]*", "ReliantUNIX[^ ]*",
"SunOS", "OSF1", "ULTRIX", "UWIN-W7", "IS/WB", "OS/390",
"SCO[^ ]*", "QNX",
NULL
};
/* Fallback: if uname -a fails, guess system by looking at "magic file names" */
magic_file_t magic_files[] = {
{"/dev/null", "UNIX", "UNIX", sys_unix},
{"c:\\config.sys", "win32", "WIN32", sys_win32dlc},
{"c:\\windows\\system.ini", "win32", "WIN32", sys_win32dlc},
{"c:\\windows\\win.ini", "win32", "WIN32", sys_win32dlc},
{"c:\\windows\\notepad.exe", "win32", "WIN32", sys_win32dlc},
{NULL, NULL, NULL, NULL}
} ;
static int match(const char *regex, const char *str)
{
re_comp(regex);
return re_exec(str);
}
/* match uname against each pattern on the list; on a match, put() the portion
of the string matched in node and return 1 */
int uname_guess(const char *node, const char *uname, const char *list[])
{
const char **l;
if (uname == NULL)
return 0;
for(l = list; *l != NULL; l++) {
if (match(*l, uname)) {
char *s;
int len = eopat[0] - bopat[0];
s = malloc(len+1);
memcpy(s, bopat[0], len);
s[len] = '\0';
put(node, s);
return 1;
}
}
return 0;
}
/* Don't worry about linear search or matching regexes all the time - this
function will be run at most two times */
static callback_t lookup_uname(char **uname, const char **name, const char **class)
{
uname_t *u;
for(u = unames; u->uname_regex != NULL; u++) {
if (
((*uname != NULL) && (match(u->uname_regex, *uname))) /* uname match */
|| ((*name != NULL) && ((strcmp(u->name, *name) == 0))) /* name match */
|| ((*class != NULL) && ((strcmp(u->class, *class) == 0))) /* class match */
) {
if (*name == NULL) *name = u->name;
if (*class == NULL) *class = u->class;
return u->callback;
}
}
return NULL;
}
static callback_t lookup_magic_file(int logdepth, const char **name, const char **class)
{
magic_file_t *u;
for(u = magic_files; u->file_name != NULL; u++) {
if (is_file(u->file_name)) {
logprintf(logdepth, "%s -> %s\n", u->file_name, u->class);
if (*name == NULL) *name = u->name;
if (*class == NULL) *class = u->class;
return u->callback;
}
}
return NULL;
}
int find_uname(const char *rname, int logdepth, int fatal)
{
const char *name, *class, *tname, *uname_orig;
char *s, *uname, *mname, *sname;
void (*callback)(void);
require("sys/tmp", logdepth, fatal);
if (istarget(db_cwd))
require("/target/sys/target", logdepth, fatal);
report("Checking for system type... ");
logprintf(logdepth, "[find_uname] checking for sys/name\n");
logdepth++;
tname = get("/arg/sys/target-name");
if (istarget(db_cwd) && (tname != NULL))
put("sys/name", tname);
tname = get("/arg/sys/target-uname");
if (istarget(db_cwd) && (tname != NULL))
put("sys/uname", tname);
name = get("sys/name");
uname_orig = get("sys/uname");
if (name == NULL) {
if (uname_orig == NULL) {
logprintf(logdepth, "not set, running\n");
run_shell(logdepth, "uname -a", (char **)&uname);
if (uname != NULL) {
for(s = uname; *s != '\0'; s++)
if ((*s == '\n') || (*s == '\r')) *s = ' ';
put("sys/uname", uname);
}
else
put("sys/uname", "");
if (run_shell(logdepth, "uname -m", (char **)&mname) == 0)
put("sys/machine_name", strip(mname));
else
put("sys/machine_name", NULL);
if (mname != NULL)
free(mname);
if (run_shell(logdepth, "uname -o", (char **)&sname) == 0)
put("sys/system_name", strip(sname));
else if (run_shell(logdepth, "uname -s", (char **)&sname) == 0)
put("sys/system_name", strip(sname));
else
put("sys/system_name", NULL);
if (sname != NULL)
free(sname);
}
/* we have uname by now, set sys/name */
name = NULL;
class = NULL;
callback = lookup_uname(&uname, &name, &class);
if (name == NULL) {
/* no uname or unknown system by uname - fallback: check for cross target */
const char *target = get("/arg/sys/target");
if ((target != NULL) && (strstr(target, "mingw") != NULL)) {
name = "WIN32";
report("(detected mingw cross compilation to WIN32)\n");
}
else {
report("Warning: unknown system\n");
name = "unknown";
}
}
put("sys/name", name);
}
else {
/* we had sys/name, that should be enough */
uname = NULL;
class = name;
callback = lookup_uname(&uname, &name, &class);
}
/* predefined and/or detected uname failed, try magic file method */
if (callback == NULL) {
logprintf(logdepth, "System class is unknown by uname, running heuristics...\n");
report("System class is unknown by uname, running heuristics... ");
callback = lookup_magic_file(logdepth + 1, &name, &class);
}
if (callback == NULL) {
/* System unknown. */
error("Unknown system '%s'\n", get("sys/uname"));
abort();
}
callback();
report("OK (name: %s; class: %s)\n", name, class);
put("sys/class", class);
/* fallbacks */
if (get("sys/machine_name") == NULL)
uname_guess("sys/machine_name", uname, machine_names);
if (get("sys/system_name") == NULL)
uname_guess("sys/system_name", uname, system_names);
/* on windows, overwrite the path sep with the right amount of \ (the tmp finder may have left / in it) */
if ((strcmp(class, "WIN32") == 0) || (strcmp(class, "win32") == 0)) {
int eats = istrue(get("sys/shell_eats_backslash"));
if (eats)
put("sys/path_sep", "\\\\\\\\");
else
put("sys/path_sep", "\\");
}
return 0;
}
static int find_triplet_(const char *name, int logdepth, int fatal, const char *nodename, int include_vendor, char *sep, char *esc)
{
const char *machine, *vendor, *os;
char *triplet, *s;
char fake_sep[2];
fake_sep[0] = 1;
fake_sep[1] = 0;
require("sys/uname", logdepth, fatal);
machine = get("sys/machine_name");
if (machine == NULL)
machine = "unknown";
vendor = "unknown";
os = get("sys/system_name");
if (os == NULL)
os = "unknown";
if (include_vendor)
triplet = str_concat(fake_sep, machine, vendor, os, NULL);
else
triplet = str_concat(fake_sep, machine, os, NULL);
for(s = triplet; *s != '\0'; s++) {
if ((esc != NULL) && (*s == *sep))
*s = *esc;
if (isalnum(*s))
*s = tolower(*s);
else {
if (*s == *fake_sep)
*s = *sep;
else if (esc != NULL)
*s = *esc;
else
*s = '-';
}
}
put(nodename, triplet);
free(triplet);
return 0;
}
int find_triplet(const char *name, int logdepth, int fatal)
{
return find_triplet_(name, logdepth, fatal, "sys/triplet", 1, "-", NULL);
}
int find_sysid(const char *name, int logdepth, int fatal)
{
return find_triplet_(name, logdepth, fatal, "sys/sysid", 0, "-", "_");
}

View File

@ -1,313 +0,0 @@
/*
scconfig - detection of standard library features: time/date/sleep related calls
Copyright (C) 2011..2012 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
int find_time_usleep(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <unistd.h>"
NL "int main() {"
NL " if (usleep(1) == 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for usleep()... ");
logprintf(logdepth, "find_time_usleep: trying to find usleep...\n");
logdepth++;
if (try_icl(logdepth, "libs/time/usleep", test_c, NULL, NULL, NULL))
return 0;
return try_fail(logdepth, "libs/time/usleep");
}
int find_time_Sleep(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "int main() {"
NL " Sleep(1);"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for Sleep()... ");
logprintf(logdepth, "find_time_Sleep: trying to find Sleep...\n");
logdepth++;
if (try_icl(logdepth, "libs/time/Sleep", test_c, "#include <windows.h>", NULL, NULL))
return 0;
return try_fail(logdepth, "libs/time/Sleep");
}
int find_time_gettimeofday(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <stdlib.h>"
NL "int main() {"
NL " struct timeval tv;"
NL " if (gettimeofday(&tv, NULL) == 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for gettimeofday()... ");
logprintf(logdepth, "find_time_gettimeofday: trying to find gettimeofday...\n");
logdepth++;
if (try_icl(logdepth, "libs/time/gettimeofday", test_c, "#include <sys/time.h>", NULL, NULL))
return 0;
return try_fail(logdepth, "libs/time/gettimeofday");
}
int find_time_ftime(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "int main() {"
NL " struct timeb tb;"
NL " if (ftime(&tb) == 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for ftime()... ");
logprintf(logdepth, "find_time_ftime: trying to find ftime...\n");
logdepth++;
if (try_icl(logdepth, "libs/time/ftime", test_c, "#include <sys/timeb.h>", NULL, NULL))
return 0;
return try_fail(logdepth, "libs/time/ftime");
}
static const char timegm_test_c_template[] =
NL "void my_puts(const char *s);"
NL "int main() {"
NL " struct tm tm;"
NL " tm.tm_sec = 50;"
NL " tm.tm_min = 30;"
NL " tm.tm_hour = 6;"
NL " tm.tm_mday = 1;"
NL " tm.tm_mon = 11;"
NL " tm.tm_year = 2018 - 1900;"
NL " tm.tm_wday = 0;"
NL " tm.tm_yday = 0;"
NL " if (%s(&tm) != (time_t)(-1))"
NL " my_puts(\"OK\");"
NL " return 0;"
NL "}"
NL "#include <stdio.h>"
NL "void my_puts(const char *s)"
NL "{"
NL " puts(s);"
NL "}"
NL;
int find_time_timegm(const char *name, int logdepth, int fatal)
{
char test_c[1000];
sprintf(test_c, timegm_test_c_template, "timegm");
require("cc/cc", logdepth, fatal);
report("Checking for timegm()... ");
logprintf(logdepth, "find_time_timegm: trying to find timegm...\n");
logdepth++;
if (try_icl(logdepth, "libs/time/timegm", test_c, "#include <time.h>", NULL, NULL))
return 0;
return try_fail(logdepth, "libs/time/timegm");
}
int find_time_mkgmtime(const char *name, int logdepth, int fatal)
{
char test_c[1000];
const char *ldflags[] = {"","-lmsvcr120","-lmsvcr110","-lmsvcr100","-lmsvcr90","-lmsvcr80","-lmsvcr71","-lmsvcr70",NULL};
const char **ldf;
sprintf(test_c, timegm_test_c_template, "_mkgmtime");
require("cc/cc", logdepth, fatal);
report("Checking for _mkgmtime()... ");
logprintf(logdepth, "find_time_mkgmtime: trying to find _mkgmtime...\n");
logdepth++;
for (ldf = ldflags; *ldf; ++ldf)
if (try_icl(logdepth, "libs/time/_mkgmtime", test_c, "#include <time.h>", NULL, *ldf))
return 0;
return try_fail(logdepth, "libs/time/_mkgmtime");
}
int find_time_gmtime_r(const char *name, int logdepth, int fatal)
{
const char test_c[] =
NL "void my_puts(const char *s);"
NL "int main() {"
NL " time_t tim = 1543645850;"
NL " struct tm tm;"
NL " if (gmtime_r(&tim, &tm)" /* returns '&tm' */
NL " && 50==tm.tm_sec"
NL " && 30==tm.tm_min"
NL " && 6==tm.tm_hour"
NL " && 1==tm.tm_mday"
NL " && 11==tm.tm_mon"
NL " && (2018-1900)==tm.tm_year)"
NL " my_puts(\"OK\");"
NL " return 0;"
NL "}"
NL "#include <stdio.h>"
NL "void my_puts(const char *s)"
NL "{"
NL " puts(s);"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for gmtime_r()... ");
logprintf(logdepth, "find_time_gmtime_r: trying to find gmtime_r...\n");
logdepth++;
if (try_icl(logdepth, "libs/time/gmtime_r", test_c, "#include <time.h>", NULL, NULL))
return 0;
return try_fail(logdepth, "libs/time/gmtime_r");
}
int find_time_gmtime_s(const char *name, int logdepth, int fatal)
{
const char test_c[] =
NL "void my_puts(const char *s);"
NL "int main() {"
NL " time_t tim = 1543645850;"
NL " struct tm tm;"
NL " if (0==gmtime_s(&tm, &tim)" /* returns errno */
NL " && 50==tm.tm_sec"
NL " && 30==tm.tm_min"
NL " && 6==tm.tm_hour"
NL " && 1==tm.tm_mday"
NL " && 11==tm.tm_mon"
NL " && (2018-1900)==tm.tm_year)"
NL " my_puts(\"OK\");"
NL " return 0;"
NL "}"
NL "#include <stdio.h>"
NL "void my_puts(const char *s)"
NL "{"
NL " puts(s);"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for gmtime_s()... ");
logprintf(logdepth, "find_time_gmtime_s: trying to find gmtime_s...\n");
logdepth++;
if (try_icl(logdepth, "libs/time/gmtime_s", test_c, "#include <time.h>", NULL, NULL))
return 0;
return try_fail(logdepth, "libs/time/gmtime_s");
}
int find_time_localtime_r(const char *name, int logdepth, int fatal)
{
const char *key = "libs/time/localtime_r";
const char test_c[] =
NL "void my_puts(const char *s);"
NL "int main() {"
NL " time_t tim = 1543645850;"
NL " struct tm tm;"
NL " if (localtime_r(&tim, &tm)" /* returns '&tm' */
NL " && 0!=tm.tm_sec" /* depends on TZ: sadly we can't sure in anything */
NL " && 0!=tm.tm_min"
NL " && 0!=tm.tm_hour)"
NL " my_puts(\"OK\");"
NL " return 0;"
NL "}"
NL "#include <stdio.h>"
NL "void my_puts(const char *s)"
NL "{"
NL " puts(s);"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for localtime_r()... ");
logprintf(logdepth, "find_time_localtime_r: trying to find localtime_r...\n");
logdepth++;
if (try_icl(logdepth, key, test_c, "#include <time.h>", NULL, NULL))
return 0;
return try_fail(logdepth, key);
}
int find_time_localtime_s(const char *name, int logdepth, int fatal)
{
const char *key = "libs/time/localtime_s";
const char test_c[] =
NL "void my_puts(const char *s);"
NL "int main() {"
NL " time_t tim = 1543645850;"
NL " struct tm tm;"
NL " if (0==localtime_s(&tm, &tim)" /* returns errno */
NL " && 0!=tm.tm_sec" /* depends on TZ: sadly we can't sure in anything */
NL " && 0!=tm.tm_min"
NL " && 0!=tm.tm_hour)"
NL " my_puts(\"OK\");"
NL " return 0;"
NL "}"
NL "#include <stdio.h>"
NL "void my_puts(const char *s)"
NL "{"
NL " puts(s);"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for localtime_s()... ");
logprintf(logdepth, "find_time_localtime_s: trying to find localtime_s...\n");
logdepth++;
if (try_icl(logdepth, key, test_c, "#include <time.h>", NULL, NULL))
return 0;
return try_fail(logdepth, key);
}

View File

@ -1,324 +0,0 @@
/*
scconfig - library for making includes on a list unique
Copyright (C) 2012, 2017 Tibor Palinkas
Copyright (C) 2017 Aron Barath
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <string.h>
#include "libs.h"
#include "db.h"
#include "regex.h"
#define grow \
if (used >= alloced) { \
alloced += 16; \
list = realloc(list, alloced * sizeof(char *)); \
}
char **uniq_inc_arr(const char *includes, int indirect, const char *sep_, int *numlines)
{
char *node, *next, *cw, *nw, *snode, *orig_node;
char *sep;
char **list;
int alloced, used, n;
orig_node = strclone(includes);
node = orig_node;
if (sep_ == NULL)
sep = strclone("\r\n");
else
sep = strclone(sep_);
/* reset list */
alloced = used = 0;
list = NULL;
/* take arguments one by one */
while(node != NULL) {
if (indirect) {
while((*node == ' ') || (*node == '\t')) node++;
next = strpbrk(node, " \t");
}
else {
for(;;) {
next = strpbrk(node, sep);
if ((next > node) || (next == NULL))
break;
node = next+1;
}
}
if (next != NULL) {
*next = '\0';
next++;
}
if (indirect)
snode = str_subsn(get(node));
else
snode = node;
cw = snode;
/* split node value (s) by sep */
/* fprintf(stderr, "nodename=%s snode=%s next=%s\n", node, snode, next);*/
while(cw != NULL) {
nw = strpbrk(cw, sep);
if (nw != NULL) {
*nw = '\0';
nw++;
}
if (*cw != '\0') {
/* try to find cw in the existing list - this is a slow linear search for now */
for(n = 0; n < used; n++) {
if (strcmp(list[n], cw) == 0)
goto already_on_list;
}
/* not found, append */
grow;
list[used] = strclone(cw);
used++;
}
already_on_list:;
cw = nw;
}
if (indirect)
free(snode);
node = next;
}
grow;
list[used] = NULL;
if (numlines != NULL)
*numlines = used;
free(orig_node);
free(sep);
return list;
}
void uniq_inc_free(char **arr)
{
char **s;
for(s = arr; *s != NULL; s++)
free(*s);
free(arr);
}
static int uniq_inc_str_cmp(const void *a_, const void *b_)
{
char **a = (char **)a_, **b = (char **)b_;
return strcmp(*a, *b);
}
static void uniq_inc_assemble_normal(char* const ret, int numelem, char **arr, const char *osep, const int oseplen)
{
char *end;
int len;
for(end = ret; 0 < numelem; ++arr, --numelem) {
if (!*arr)
continue;
len = strlen(*arr);
memcpy(end, *arr, len);
end += len;
memcpy(end, osep, oseplen);
end += oseplen;
free(*arr);
}
*end = '\0';
}
static void uniq_inc_assemble_groups(char* const ret, int numelem, char **arr, const char *osep, const int oseplen, int eren, char **eres)
{
char *end = ret;
int erei, ndx, len;
/* re_comp() uses a global variable to store the compiler regex! */
for (erei = 0; erei < eren; ++erei) {
if (re_comp(eres[erei]))
abort();
for (ndx = 0; ndx < numelem; ++ndx) {
if (!arr[ndx])
continue;
if (re_exec(arr[ndx])) {
len = strlen(arr[ndx]);
memcpy(end, arr[ndx], len);
end += len;
memcpy(end, osep, oseplen);
end += oseplen;
free(arr[ndx]);
arr[ndx] = NULL;
}
}
}
/* collect remaining elements */
uniq_inc_assemble_normal(end, numelem, arr, osep, oseplen);
}
char *uniq_inc_str(const char *includes, const char *isep, const char *osep, int sort, int eren, char **eres)
{
char **arr, **s, *ret;
int len, numelem, oseplen;
/* split and uniq */
oseplen = strlen(osep);
arr = uniq_inc_arr(includes, 0, isep, NULL);
/* calculate the required amount of memory */
len = 4; /* safety margin, for terminator \0, etc. */
numelem = 0;
for(s = arr; *s != NULL; s++) {
len += strlen(*s) + oseplen + 1;
numelem++;
}
/* sort if needed */
if (sort)
qsort(arr, numelem, sizeof(char *), uniq_inc_str_cmp);
/* allocate memory to assemble into */
ret = malloc(len);
/* assemble the output */
if (0>=eren)
uniq_inc_assemble_normal(ret, numelem, arr, osep, oseplen);
else
uniq_inc_assemble_groups(ret, numelem, arr, osep, oseplen, eren, eres);
/* done */
free(arr);
return ret;
}
char *order_inc_str(const char *includes, const char *isep, const char *word1, int dir, const char *word2)
{
const char *s, *next, *pre, *mid, *post;
char *out, *end;
long w1o = -1, w2o = -1;
long w1len = strlen(word1), w2len = strlen(word2), tlen;
long pre_len, mid_len, post_len;
if (dir == 0)
return NULL;
if ((w1len == 0) || (w2len == 0))
return strclone(includes);
if ((w1len == w2len) && (strcmp(word1, word2) == 0))
return strclone(includes);
/* search the starting offset of the first occurence of word1 and word2 */
for(s = includes; (s != NULL) && ((w1o < 0) || (w2o < 0)); s = next) {
next = strpbrk(s, isep);
if (next == NULL)
tlen = strlen(s);
else
tlen = next-s;
if ((w1o < 0) && (w1len == tlen) && (memcmp(s, word1, tlen) == 0))
w1o = s - includes;
if ((w2o < 0) && (w2len == tlen) && (memcmp(s, word2, tlen) == 0))
w2o = s - includes;
if (next != NULL)
next += strspn(next, isep);
}
/* one of the words is not on the list, the list is ordered */
if ((w1o < 0) || (w2o < 0))
return strclone(includes);
/* both words are not on the list, but the list is ordered */
if (((dir < 0) && (w1o < w2o)) || ((dir > 0) && (w1o > w2o)))
return strclone(includes);
/* split up the input at word1 and word2 */
tlen = strlen(includes);
if (dir < 0) { /* input is: 'pre w2 mid w1 post', goal is mowing w1 before w2 */
pre = includes;
pre_len = w2o;
mid = includes + w2o + w2len + 1;
mid_len = (includes + w1o) - mid;
post = includes + w1o + w1len + 1;
post_len = (includes + tlen) - post + 1;
}
else { /* input is: 'pre w1 mid w2 post' goal is moving w1 after w2*/
pre = includes;
pre_len = w1o;
mid = includes + w1o + w1len + 1;
mid_len = (includes + w2o) - mid;
post = includes + w2o + w2len + 1;
post_len = (includes + tlen) - post + 1;
}
/* truncate trailing separator, if present */
if ((pre_len > 0) && (strchr(isep, pre[pre_len-1])))
pre_len--;
if ((mid_len > 0) && (strchr(isep, mid[mid_len-1])))
mid_len--;
if ((post_len > 0) && (strchr(isep, post[mid_len-1])))
post_len--;
/* allocate extra space for a trailing separator and/or \0 */
end = out = malloc(tlen+2);
/* build the string by appending the parts */
#define append(str, len) \
if (len > 0) { \
memcpy(end, str, len); \
end += len; \
*end = *isep; \
end++; \
}
append(pre, pre_len);
if (dir < 0) {
append(word1, w1len);
append(word2, w2len);
}
append(mid, mid_len);
if (dir > 0) {
append(word2, w2len);
append(word1, w1len);
}
append(post, post_len);
#undef append
/* replace the last separator with \0 or just add a \0 at the end */
if ((end > out) && (strchr(isep, end[-1])))
end[-1] = '\0';
else
end[0] = '\0';
return out;
}

View File

@ -1,335 +0,0 @@
/*
scconfig - library functions for compiling and running test code
Copyright (C) 2009 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include "log.h"
#include "libs.h"
#include "db.h"
#include "dep.h"
/*
#define KEEP_TEST_SRCS
*/
int cross_blind = 0;
static char *clone_flags(const char *input, const char *node)
{
char *output;
const char *s;
int len;
if (input != NULL) {
if (*input == '+') {
s = get(node);
if (s != NULL) {
len = strlen(s);
output = malloc(len + strlen(input) + 4);
memcpy(output, s, len);
output[len] = ' ';
strcpy(output + len + 1, input + 1);
}
else
output = strclone(input);
}
else
output = strclone(input);
}
else {
s = get(node);
if (s != NULL)
output = strclone(s);
else
output = strclone("");
}
return output;
}
int compile_file_raw(int logdepth, const char *fn_input, char **fn_output, const char *cc, const char *cflags, const char *ldflags)
{
char *cmdline;
char *cc_esc, *fn_input_esc, *fn_output_esc, *temp_out_esc, *temp_out;
int ret;
temp_out = tempfile_new(".out");
if (*fn_output == NULL)
*fn_output = tempfile_new(get("sys/ext_exe"));
else
*fn_output = tempfile_new(*fn_output);
unlink(*fn_output);
cc_esc = shell_escape_dup(cc == NULL ? get("cc/cc") : cc);
fn_input_esc = shell_escape_dup(fn_input);
fn_output_esc = shell_escape_dup(*fn_output);
temp_out_esc = shell_escape_dup(temp_out);
cmdline = str_concat("",
get("/host/sys/shell"), " \"", cc_esc, " ", cflags, " ", fn_input_esc, " ", \
ldflags, " -o ", fn_output_esc, " 2>&1\" >", temp_out_esc, NULL);
free(cc_esc);
free(fn_input_esc);
free(fn_output_esc);
free(temp_out_esc);
logprintf(logdepth, "compile: '%s'\n", cmdline);
ret = system(cmdline);
free(cmdline);
log_merge(logdepth + 1, temp_out);
#ifndef KEEP_TEST_SRCS
unlink(temp_out);
#endif
free(temp_out);
logprintf(logdepth, "compile result: %d\n", ret);
return ret;
}
int compile_file(int logdepth, const char *fn_input, char **fn_output, const char *cc, const char *cflags, const char *ldflags)
{
int ret;
char *ldflags_, *cflags_;
cflags_ = clone_flags(cflags, "cc/cflags");
ldflags_ = clone_flags(ldflags, "cc/ldflags");
ret = compile_file_raw(logdepth, fn_input, fn_output, cc, cflags_, ldflags_);
free(cflags_);
free(ldflags_);
return ret;
}
int compile_code(int logdepth, const char *testcode, char **fn_output, const char *cc, const char *cflags, const char *ldflags)
{
char *temp_in;
int ret;
require("sys/ext_exe", logdepth, 1);
assert(testcode != NULL);
assert(fn_output != NULL);
temp_in = tempfile_dump(testcode, ".c");
ret = compile_file(logdepth, temp_in, fn_output, cc, cflags, ldflags);
#ifndef KEEP_TEST_SRCS
unlink(temp_in);
#endif
free(temp_in);
return ret;
}
int compile_code_raw(int logdepth, const char *testcode, char **fn_output, const char *cc, const char *cflags, const char *ldflags)
{
char *temp_in;
int ret;
require("sys/ext_exe", logdepth, 1);
assert(testcode != NULL);
assert(fn_output != NULL);
temp_in = tempfile_dump(testcode, ".c");
ret = compile_file_raw(logdepth, temp_in, fn_output, cc, cflags, ldflags);
#ifndef KEEP_TEST_SRCS
unlink(temp_in);
#endif
free(temp_in);
return ret;
}
char *shell_escape_dup(const char *in)
{
char *o, *out;
const char *i;
const char *esc = get("sys/shell_escape_char");
/* in the early phase, before detecting the shell, this happens */
if (esc == NULL)
return strclone(in);
out = malloc(strlen(in)*2+1);
for(i = in, o = out; *i != '\0'; i++) {
if (*i == *esc) {
*o++ = *esc;
}
else if (!isalnum(*i)) {
switch(*i) {
case '/':
case '_':
case '-':
case '.':
break;
default:
*o++ = *esc;
}
}
*o++ = *i;
}
*o = '\0';
return out;
}
int run(int logdepth, const char *cmd_, char **stdout_saved)
{
char *cmd;
char *fn_out, *temp_out;
char *fn_out_esc, *temp_out_esc;
int ret;
const char *emu;
assert(cmd_ != NULL);
/* blind cross compiling mode means we always assume success */
if (cross_blind) {
if (stdout_saved != NULL)
*stdout_saved = NULL;
return 0;
}
emu = get("sys/emu");
/* emu == NULL means we need an emulator but we don't have one and
we should pretend everything went well (and of course can't provide
output.) */
if (emu == NULL) {
if (stdout_saved != NULL)
*stdout_saved = NULL;
return 0;
}
/* emu == false means we need an emulator and we don't want to pretend -> fatal */
if (strcmp(emu, sfalse) == 0) {
error("Trying to run unavailable emulator (db_cwd='%s')\n", db_cwd);
abort();
}
temp_out = tempfile_new(".out");
fn_out = tempfile_new("");
temp_out_esc = shell_escape_dup(temp_out);
fn_out_esc = shell_escape_dup(fn_out);
cmd = malloc(strlen(emu) + strlen(cmd_) + strlen(fn_out_esc) + strlen(temp_out_esc) + 32);
sprintf(cmd, "%s %s >%s 2>>%s", emu, cmd_, fn_out_esc, temp_out_esc);
free(temp_out_esc);
free(fn_out_esc);
logprintf(logdepth, "run: '%s'\n", cmd);
ret = system(cmd);
log_merge(logdepth + 1, temp_out);
unlink(temp_out);
free(temp_out);
logprintf(logdepth, "run result: %d\n", ret);
free(cmd);
if (stdout_saved != NULL) {
if (ret == 0) {
*stdout_saved = load_file(fn_out);
logprintf(logdepth, "stdout: '%s'\n", *stdout_saved);
}
else
*stdout_saved = NULL;
}
unlink(fn_out);
free(fn_out);
return ret;
}
int run_shell(int logdepth, const char *cmd_, char **stdout_saved)
{
int ret;
char *cmd, *cmd_esc;
const char *emu;
const char *shell;
emu = get("sys/emulator");
if (emu == NULL)
emu = "";
shell = get("sys/shell");
if (shell == NULL) {
error("No shell was specified (db_cwd='%s')\n", db_cwd);
abort();
}
cmd_esc = shell_escape_dup(cmd_);
cmd = malloc(strlen(emu) + strlen(shell) + strlen(cmd_esc) + 16);
if (istrue(get("sys/shell_needs_quote")))
sprintf(cmd, "%s %s \"%s\"", emu, shell, cmd_);
else
sprintf(cmd, "%s %s %s", emu, shell, cmd_);
free(cmd_esc);
ret = run(logdepth, cmd, stdout_saved);
free(cmd);
return ret;
}
int compile_run(int logdepth, const char *testcode, const char *cc, const char *cflags, const char *ldflags, char **stdout_saved)
{
int ret;
char *fn_output = NULL;
ret = compile_code(logdepth+1, testcode, &fn_output, cc, cflags, ldflags);
if (ret == 0) {
char *fn_output_esc = shell_escape_dup(fn_output);
ret = run(logdepth+1, fn_output_esc, stdout_saved);
free(fn_output_esc);
}
if (fn_output != NULL) {
unlink(fn_output);
free(fn_output);
}
return ret;
}
int run_script(int logdepth, const char *interpreter, const char *script, const char *suffix, char **out)
{
char *temp, *cmd;
int res;
temp = tempfile_dump(script, suffix);
cmd = malloc(strlen(temp) + strlen(interpreter) + 4);
sprintf(cmd, "%s %s", interpreter, temp);
res = run(logdepth, cmd, out);
unlink(temp);
free(temp);
free(cmd);
return res;
}

View File

@ -1,153 +0,0 @@
/*
scconfig - command line argument processing
Copyright (C) 2009..2012 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <string.h>
#include "db.h"
#include "arg.h"
#include "dep.h"
#include "log.h"
#include "libs.h"
argtbl_t main_argument_table[] = {
{"import", NULL, import_args, "Import saved config (sub)tree"},
{"target", "/arg/sys/target", NULL, "set cross compilation target (prefix)"},
{"target-name", "/arg/sys/target-name", NULL, "set cross compilation target (system name)"},
{"target-shell","/arg/sys/target-shell",NULL, "set the shell on cross compilation target"},
{"emu", "/arg/sys/emu", NULL, "emulator for testing cross compiled executables with"},
{"pkg-config", "/arg/sys/pkg-config", NULL, "path to pkg-config to use"},
{"pkg-config-zap","/arg/sys/pkg-config-zap",NULL, "ignore pkg-config results by this regex pattern"},
/* wildcard rules for icl() control */
{"^ldflags/", NULL, import_icl, "force LDFLAGS for a node"},
{"^cflags/", NULL, import_icl, "force CFLAGS for a node"},
{"^includes/", NULL, import_icl, "force #includes for a node"},
{"^prefix/", NULL, import_icl, "force using prefix path for detecting the node"},
/* the followings are autoconf compatibility translations */
{"CC", "/arg/cc/cc", NULL, "Force using a C compiler (command line)"},
{"CFLAGS", "/arg/cc/cflags", NULL, "Force using a CFLAGS for C compilation"},
{"LDFLAGS", "/arg/cc/ldflags", NULL, "Force using a LDFLAGS for linking"},
{"LDL", "/arg/libs/ldl", NULL, "Force using -ldl string"},
{"gpmi-prefix", "/arg/gpmi/prefix", NULL, NULL},
{NULL, NULL, NULL, NULL}
};
void process_args(int argc, char *argv[])
{
int n;
char *key, *value;
argtbl_t *a;
int found, tainted = 0;
db_mkdir("/arg");
logprintf(0, "CLI arg 0: '%s'\n", argv[0]);
for(n = 1; n < argc; n++) {
key = argv[n];
logprintf(0, "CLI arg %d: '%s'\n", n, key);
while(*key == '-') key++;
value = str_chr(key, '=');
found = 0;
if (value != NULL) {
*value = '\0';
value++;
if (strcmp(key, "without") == 0) {
char *tmp;
if (*value != '/') {
const char **r, *roots[] = {"target", "host", "runtime", NULL};
for(r = roots; *r != NULL; r++) {
tmp = str_concat("/", "/arg/without", *r, value, NULL);
put(tmp, strue);
free(tmp);
}
}
else {
tmp = str_concat("/", "/arg/without", value+1, NULL);
put(tmp, strue);
free(tmp);
}
found = 1;
}
else {
/* Look in the argument translate table */
for(a = main_argument_table; a->arg != NULL; a++) {
if (((a->arg[0] == '^') && (strncmp(a->arg+1, key, strlen(a->arg+1)) == 0)) || (strcmp(a->arg, key) == 0)) {
found = 1;
if (a->callback != NULL) {
if (a->callback(key, value) != 0) {
error("Processing argument '%s' failed in the callback\n", argv[n]);
abort();
}
}
if (a->path != NULL)
put(a->path, value);
}
}
}
/* Look in known deps table or /arg */
if (found == 0) {
if ((is_dep_known(key)) || (strncmp(key, "/arg/", 5) == 0)) {
put(key, value);
found = 1;
}
}
}
if (found == 0) {
if (custom_arg(key, value) == 0) {
error("Unknown argument '%s'\n", key);
tainted++;
}
}
}
if (tainted)
exit(1);
}
void help_default_args(FILE *f, const char *prefix)
{
argtbl_t *a;
if (prefix == NULL)
prefix = "";
fprintf(f, "%sscconfig generic command line arguments:\n", prefix);
for(a = main_argument_table; a->arg != NULL; a++) {
char *tmp;
if (a->help == NULL)
continue;
if (*a->arg == '^') {
tmp = str_concat("", a->arg+1, "...=...", NULL);
fprintf(f, "%s --%-22s %s\n", prefix, tmp, a->help);
}
else {
tmp = str_concat("", a->arg, "=...", NULL);
fprintf(f, "%s --%-22s %s\n", prefix, tmp, a->help);
}
free(tmp);
}
}

View File

@ -1,187 +0,0 @@
/*
scconfig - non-standard string manipulation routines
Copyright (C) 2009 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
char *strclone(const char *str)
{
int l;
char *ret;
if (str == NULL)
return NULL;
l = strlen(str)+1;
ret = malloc(l);
memcpy(ret, str, l);
return ret;
}
#define SPACE(c) (((c) == '\r') || ((c) == '\n') || ((c) == '\t') || ((c) == ' '))
char *trim_left(char *str)
{
while(SPACE(*str)) str++;
return str;
}
char *trim_right(char *str)
{
char *end;
end = str + strlen(str) - 1;
while((end >= str) && SPACE(*end)) { *end = '\0'; end--; }
return str;
}
char *strip(char *str)
{
return trim_left(trim_right(str));
}
char *str_chr(char *str, char c)
{
char *s;
for(s = str; *s != '\0'; s++)
if (*s == c)
return s;
return NULL;
}
char *str_rchr(char *str, char c)
{
char *s, *last;
last = NULL;
for(s = str; *s != '\0'; s++)
if (*s == c)
last = s;
return last;
}
char *str_subsn(const char *str)
{
char *out, *o;
const char *i;
if (str == NULL)
return strclone("");
o = out = malloc(strlen(str)+1);
for(i = str; *i != '\0'; i++, o++) {
if ((i[0] == '\\') && (i[1] == 'n')) {
i++;
*o = '\n';
}
else
*o = *i;
}
*o = '\0';
return out;
}
char *str_concat(const char *sep, ...)
{
# define CONCAT_MAX 64
int len[CONCAT_MAX];
const char *str[CONCAT_MAX];
int n, v, sum, sl;
char *out, *o;
va_list ap;
va_start(ap, sep);
if (sep == NULL)
sep = "";
/* load all strings into an array, measure their lengths */
sum = 0;
for(v = 0; ;v++) {
if (v >= CONCAT_MAX) {
fprintf(stderr, "Internal error: str_concat got more strings than CONCAT_MAX\n");
abort();
}
str[v] = va_arg(ap, const char *);
if (str[v] == NULL) {
len[v] = 0;
break;
}
len[v] = strlen(str[v]);
sum += len[v];
}
/* first string is NULL; return a new allocation that is a simple \0, empty string to avoid a nasty corner case */
if (sum == 0)
return calloc(1, 1);
sl = strlen(sep);
sum += (v-1) * sl + 1; /* + a sep between each two strings and a terminator at the end */
o = out = malloc(sum);
for(n = 0; n < v; n++) {
if ((n > 0) && (sl > 0)) {
memcpy(o, sep, sl);
o += sl;
}
if (len[n] > 0) {
memcpy(o, str[n], len[n]);
o += len[n];
}
}
*o = '\0';
va_end(ap);
return out;
}
char *esc_interpret(const char *str)
{
char *out, *si, *so;
out = strclone(str);
/* replace (interpret) \ sequences in seq */
for(si = so = out; *si != '\0'; si++,so++) {
if (si[0] == '\\') {
switch(si[1]) {
case 'n': *so = '\n'; break;
case 't': *so = '\t'; break;
case 's': *so = ' '; break;
case '\\': *so = '\\'; break;
}
si++;
}
else
*so = *si;
}
*so = '\0';
return out;
}
int chr_inset(char c, const char *set)
{
while (*set != '\0') {
if (c == *set)
return 1;
set++;
}
return 0;
}

View File

@ -1,37 +0,0 @@
#include "ht.h"
#define strue "true"
#define sfalse "false"
#define istrue(s) ((s != NULL) && (*s == 't'))
#define isfalse(s) ((s != NULL) && (*s == 'f'))
/* the 3rd option is "unknown" */
/* accessors */
const char *get(const char *key);
const char *put(const char *key, const char *data);
void append(const char *key, const char *value);
char *concat_nodes(const char *prefix, ...);
int node_istrue(const char *key);
/* init/uninit */
void db_init(void);
void db_uninit(void);
/* export/import */
int export(const char *fn, int export_empty, const char *root);
int import(const char *fn);
int import_args(const char *key, const char *fn);
/* file system features */
extern char *db_cwd;
void db_cd(const char *path);
void db_mkdir(const char *path);
void db_link(const char *existing, const char *new);
void db_rmdir(const char *path);
extern ht_t *DBs;
#define iscross (ht_get(DBs, "target") != ht_get(DBs, "host"))
#define in_cross_target (iscross && (strcmp(db_cwd, "/target") == 0))
#define in_cross_host (iscross && (strcmp(db_cwd, "/host") == 0))

View File

@ -1,808 +0,0 @@
/*
scconfig - detection of standard library features: file system specific calls
Copyright (C) 2010 Tibor Palinkas
Copyright (C) 2018 Aron Barath
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
int find_fs_realpath(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <limits.h>"
NL "#include <stdlib.h>"
NL "#include <stdio.h>"
NL "#ifdef PATH_MAX"
NL "char out_buf[PATH_MAX];"
NL "#else"
NL "char out_buf[32768];"
NL "#endif"
NL "int main() {"
NL " if (realpath(\".\", out_buf) == out_buf)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for realpath()... ");
logprintf(logdepth, "find_fs_realpath: trying to find realpath...\n");
logdepth++;
if (try_icl(logdepth, "libs/fs/realpath", test_c, NULL, NULL, NULL)) return 0;
if (try_icl(logdepth, "libs/fs/realpath", test_c, "#define _DEFAULT_SOURCE", NULL, NULL)) return 0;
if (try_icl(logdepth, "libs/fs/realpath", test_c, "#define _BSD_SOURCE", NULL, NULL)) return 0;
return try_fail(logdepth, "libs/fs/realpath");
}
int find_fs__fullpath(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <stdio.h>"
NL "#include <conio.h>"
NL "#include <stdlib.h>"
NL "#include <direct.h>"
NL "int main() {"
NL " char full[_MAX_PATH];"
NL " if (_fullpath(full, \".\", _MAX_PATH) != NULL)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for _fullpath()... ");
logprintf(logdepth, "find_fs__fullpath: trying to find _fullpath...\n");
logdepth++;
if (try_icl(logdepth, "libs/fs/_fullpath", test_c, NULL, NULL, NULL)) return 0;
return try_fail(logdepth, "libs/fs/_fullpath");
}
int find_fs_readdir(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <stdlib.h>"
NL "#include <stdio.h>"
NL "int main() {"
NL " DIR *dirp;"
NL " struct dirent *dp;"
NL " int found = 0;"
NL " if ((dirp = opendir(\".\")) == 0)"
NL " return -1;"
NL " while ((dp = readdir(dirp)) != 0)"
NL " if (strcmp(dp->d_name, \"configure\") == 0)"
NL " found++;"
NL " closedir(dirp);"
NL " if (found == 1)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
char *includes[] = {
"#include <dirent.h>",
"#include <sys/dir.h>", /* 4.2BSD */
NULL
};
char **i;
require("cc/cc", logdepth, fatal);
report("Checking for readdir()... ");
logprintf(logdepth, "find_fs_readdir: trying to find readdir...\n");
logdepth++;
for (i = includes; *i != NULL; i++)
if (try_icl(logdepth, "libs/fs/readdir", test_c, *i, NULL, NULL))
return 0;
return try_fail(logdepth, "libs/fs/readdir");
}
int find_fs_findnextfile(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <stdlib.h>"
NL "#include <stdio.h>"
NL "#include <windows.h>"
NL "int main(int argc, char *argv[]) {"
NL " WIN32_FIND_DATA fd;"
NL " HANDLE h;"
NL " int found=0;"
NL " h = FindFirstFile(argv[0], &fd);"
NL " if (h == INVALID_HANDLE_VALUE)"
NL " return -1;"
NL " while (FindNextFile(h, &fd) != 0);"
NL " found++;"
NL " FindClose(h);"
NL " if (found > 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for FindNextFile()... ");
logprintf(logdepth, "find_fs_findnextfile: trying to find FindNextFile...\n");
logdepth++;
if (try_icl(logdepth, "libs/fs/findnextfile", test_c, NULL, NULL, NULL)) return 0;
return try_fail(logdepth, "libs/fs/findnextfile");
}
int find_fs_access(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "int my_test() { return access(\".\", 0); }"
NL "#include <stdio.h>"
NL "int main() {"
NL " if (my_test() == 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char* includes[] = { "#include <unistd.h>", "#include <stdlib.h>\n#include <direct.h>", "#include <stdlib.h>", NULL };
const char** inc;
require("cc/cc", logdepth, fatal);
report("Checking for access()... ");
logprintf(logdepth, "find_fs_access: trying to find access...\n");
logdepth++;
for (inc=includes; *inc; ++inc)
if (try_icl(logdepth, "libs/fs/access", test_c, *inc, NULL, NULL)) return 0;
return try_fail(logdepth, "libs/fs/access");
}
int find_fs_access_macros(const char *rname, int logdepth, int fatal)
{
char *test_c_templ =
NL "%s"
NL "void my_test() { int a = %s; }"
NL "#include <stdio.h>"
NL "int main() {"
NL " my_test();"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
char test_c[256];
char *names[][3] = {
{"F_OK", "F_OK", NULL},
{"R_OK", "R_OK", NULL},
{"W_OK", "W_OK", NULL},
{"X_OK", "X_OK", NULL},
{NULL, NULL, NULL}
};
char **n;
const char* access_includes;
int name, pr;
char nodename[128];
require("cc/cc", logdepth, fatal);
if (require("libs/fs/access/*", logdepth, fatal)!=0 ||
!istrue(get("libs/fs/access/presents"))) {
put("libs/fs/access/macros/presents", sfalse);
return 1;
}
access_includes = get("libs/fs/access/includes");
report("Checking for access macros:\n");
logprintf(logdepth, "find_fs_access_macros: trying to find access macros...\n");
logdepth++;
pr = 0;
for(name = 0; *names[name] != NULL; name++) {
report(" %s...\t", names[name][0]);
for(n = &names[name][0]; *n != NULL; n++) {
sprintf(test_c, test_c_templ, access_includes, *n);
if (try_icl(logdepth, NULL, test_c, NULL, NULL, NULL)) {
sprintf(nodename, "libs/fs/access/macros/%s", names[name][0]);
put(nodename, *n);
report("found as %s\n", *n);
pr++;
goto found;
}
}
report("not found\n");
found:;
}
put("libs/fs/access/macros/presents", ((pr > 0) ? (strue) : (sfalse)));
return (pr == 0);
}
int find_fs_stat_macros(const char *rname, int logdepth, int fatal)
{
char *test_c_templ =
NL "#include <sys/stat.h>"
NL "#include <sys/types.h>"
NL "void my_test() { int a = %s(0); }"
NL "#include <stdio.h>"
NL "int main() {"
NL " my_test();"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
char test_c[256];
char *names[][3] = {
{"S_ISREG", "S_IFREG", NULL},
{"S_ISDIR", "S_IFDIR", NULL},
{"S_ISCHR", "S_IFCHR", NULL},
{"S_ISBLK", "S_IFBLK", NULL},
{"S_ISFIFO", "S_IFFIFO", NULL},
{"S_ISLNK", "S_IFLNK", NULL},
{"S_ISCHR", "S_IFCHR", NULL},
{"S_ISSOCK", "S_IFSOCK", NULL},
{NULL, NULL, NULL}
};
char **n;
int name, pr;
char nodename[128];
require("cc/cc", logdepth, fatal);
report("Checking for stat macros:\n");
logprintf(logdepth, "find_fs_stat_macros: trying to find stat macros...\n");
logdepth++;
pr = 0;
for(name = 0; *names[name] != NULL; name++) {
report(" %s...\t", names[name][0]);
for(n = &names[name][0]; *n != NULL; n++) {
sprintf(test_c, test_c_templ, *n);
if (try_icl(logdepth, NULL, test_c, NULL, NULL, NULL)) {
sprintf(nodename, "libs/fs/stat/macros/%s", names[name][0]);
put(nodename, *n);
report("found as %s\n", *n);
pr++;
goto found;
}
}
report("not found\n");
found:;
}
put("libs/fs/stat/macros/presents", ((pr > 0) ? (strue) : (sfalse)));
return (pr == 0);
}
int find_fs_stat_fields(const char *rname, int logdepth, int fatal)
{
char *test_c_templ =
NL "#include <sys/stat.h>"
NL "#include <sys/types.h>"
NL "#include <stdio.h>"
NL "int main() {"
NL " struct stat st;"
NL " (void)st.%s;"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
char test_c[256];
char *names[] = {"st_blksize", "st_blocks", "st_rdev", "st_mtim", "st_mtime", "st_birthtim", "st_birthtime", NULL };
int name, pr;
char nodename[128];
require("cc/cc", logdepth, fatal);
report("Checking for stat macros:\n");
logprintf(logdepth, "find_fs_stat_fields: trying to find stat macros...\n");
logdepth++;
pr = 0;
for(name = 0; names[name] != NULL; name++) {
report(" %s...\t", names[name]);
sprintf(test_c, test_c_templ, names[name]);
sprintf(nodename, "libs/fs/stat/fields/%s/presents", names[name]);
if (try_icl(logdepth, NULL, test_c, NULL, NULL, NULL)) {
put(nodename, strue);
report("found\n");
pr++;
}
else {
report("not found\n");
put(nodename, sfalse);
}
}
return (pr == 0);
}
static int find_fs_any_lstat(const char *name, int logdepth, int fatal, char *fn)
{
/* make sure <stdio.h> does not affect our lstat() detection */
const char *test_c_in =
NL "void my_puts(const char *s);"
NL "int main() {"
NL " struct stat buf;"
NL " if (%s(\".\", &buf) == 0)"
NL " my_puts(\"OK\");"
NL " return 0;"
NL "}"
NL "#include <stdio.h>"
NL "void my_puts(const char *s)"
NL "{"
NL " puts(s);"
NL "}"
NL;
char test_c[384], node[64];
const char *incs[] = {"#include <sys/stat.h>", "#include <unistd.h>", "#include <sys/types.h>\n#include <sys/stat.h>\n#include <unistd.h>", NULL};
const char **inc;
require("cc/cc", logdepth, fatal);
sprintf(node, "libs/fs/%s", fn);
sprintf(test_c, test_c_in, fn);
report("Checking for %s... ", fn);
logprintf(logdepth, "find_fs_%s: trying to find lstat()...\n", fn);
logdepth++;
for (inc = incs; *inc; ++inc) {
if (try_icl(logdepth, node, test_c, *inc, NULL, NULL))
return 0;
}
return try_fail(logdepth, node);
}
int find_fs_lstat(const char *name, int logdepth, int fatal)
{
return find_fs_any_lstat(name, logdepth, fatal, "lstat");
}
int find_fs_statlstat(const char *name, int logdepth, int fatal)
{
return find_fs_any_lstat(name, logdepth, fatal, "statlstat");
}
int find_fs_getcwd(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <unistd.h>"
NL "int main() {"
NL " char b[1024];"
NL " if (getcwd(b, sizeof(b)) != NULL)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for getcwd... ");
logprintf(logdepth, "find_fs_getcwd: trying to find getcwd()...\n");
logdepth++;
if (try_icl(logdepth, "libs/fs/getcwd", test_c, NULL, NULL, NULL)) return 0;
return try_fail(logdepth, "libs/fs/getcwd");
}
int find_fs__getcwd(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <stdlib.h>"
NL "int main() {"
NL " char b[1024];"
NL " if (_getcwd(b, sizeof(b)) != NULL)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for _getcwd... ");
logprintf(logdepth, "find_fs__getcwd: trying to find _getcwd()...\n");
logdepth++;
if (try_icl(logdepth, "libs/fs/_getcwd", test_c, "#include <direct.h>", NULL, NULL)) return 0;
return try_fail(logdepth, "libs/fs/_getcwd");
}
int find_fs_getwd(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <unistd.h>"
NL "int main() {"
NL " char b[8192];"
NL " if (getwd(b) != NULL)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for getwd... ");
logprintf(logdepth, "find_fs_getwd: trying to find getwd()...\n");
logdepth++;
if (try_icl(logdepth, "libs/fs/getwd", test_c, NULL, NULL, NULL)) return 0;
return try_fail(logdepth, "libs/fs/getwd");
}
int find_fs_mkdir(const char *name, int logdepth, int fatal)
{
char *dir;
char test_c[1024];
char *test_c_in =
NL "#include <stdio.h>"
NL "int main() {"
NL no_implicit(int, "mkdir", "mkdir")
NL " if (mkdir(\"%s\"%s) == 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
dir = tempfile_new("");
unlink(dir);
report("Checking for mkdir... ");
logprintf(logdepth, "find_fs_mkdir: trying to find mkdir()...\n");
logdepth++;
/* POSIX, 2 arguments, standard includes */
sprintf(test_c, test_c_in, dir, ", 0755");
if (try_icl(logdepth, "libs/fs/mkdir", test_c, "#include <sys/types.h>\n#include <sys/stat.h>\n", NULL, NULL)) {
if (!is_dir(dir))
goto oops1;
put("libs/fs/mkdir/num_args", "2");
rmdir(dir);
return 0;
}
/* POSIX, 2 arguments, no includes */
oops1:;
sprintf(test_c, test_c_in, dir, ", 0755");
if (try_icl(logdepth, "libs/fs/mkdir", test_c, NULL, NULL, NULL)) {
if (!is_dir(dir))
goto oops2;
put("libs/fs/mkdir/num_args", "2");
rmdir(dir);
return 0;
}
/* win32, 1 argument, with <direct.h> */
oops2:;
sprintf(test_c, test_c_in, dir, "");
if (try_icl(logdepth, "libs/fs/mkdir", test_c, "#include <direct.h>\n", NULL, NULL)) {
if (!is_dir(dir))
goto oops3;
put("libs/fs/mkdir/num_args", "1");
rmdir(dir);
return 0;
}
oops3:;
put("libs/fs/mkdir/includes", "");
put("libs/fs/mkdir/ldflags", "");
put("libs/fs/mkdir/cdflags", "");
rmdir(dir);
return try_fail(logdepth, "libs/fs/mkdir");
}
int find_fs__mkdir(const char *name, int logdepth, int fatal)
{
char *dir;
char test_c[1024];
char *test_c_in =
NL "#include <stdio.h>"
NL "int main() {"
NL " if (_mkdir(\"%s\"%s) == 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
dir = tempfile_new("");
unlink(dir);
report("Checking for _mkdir... ");
logprintf(logdepth, "find_fs__mkdir: trying to find _mkdir()...\n");
logdepth++;
/* win32, 2 arguments, standard includes */
sprintf(test_c, test_c_in, dir, ", 0755");
if (try_icl(logdepth, "libs/fs/_mkdir", test_c, "#include <direct.h>\n", NULL, NULL)) {
if (!is_dir(dir))
goto oops1;
put("libs/fs/_mkdir/num_args", "2");
rmdir(dir);
return 0;
}
oops1:;
/* win32, 1 argument, standard includes */
sprintf(test_c, test_c_in, dir, "");
if (try_icl(logdepth, "libs/fs/_mkdir", test_c, "#include <direct.h>\n", NULL, NULL)) {
if (!is_dir(dir))
goto oops2;
put("libs/fs/_mkdir/num_args", "1");
rmdir(dir);
return 0;
}
oops2:;
put("libs/fs/_mkdir/includes", "");
put("libs/fs/_mkdir/ldflags", "");
put("libs/fs/_mkdir/cdflags", "");
rmdir(dir);
return try_fail(logdepth, "libs/fs/_mkdir");
}
int find_fs_mkdtemp(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <stdio.h>"
NL "#include <unistd.h>"
NL "#include <string.h>"
NL "int main() {"
NL " char fn[32], *o;"
NL " strcpy(fn, \"scc.XXXXXX\");"
NL " o = mkdtemp(fn);"
NL " if ((o != NULL) && (strstr(o, \"scc.\") != NULL)) {"
NL " remove(o);"
NL " puts(\"OK\");"
NL " }"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for mkdtemp... ");
logprintf(logdepth, "find_fs_mkdtemp: trying to find mkdtemp()...\n");
logdepth++;
if (try_icl(logdepth, "libs/fs/mkdtemp", test_c, "#include <stdlib.h>\n", NULL, NULL)) return 0;
if (try_icl(logdepth, "libs/fs/mkdtemp", test_c, "#define _BSD_SOURCE\n#include <stdlib.h>\n", NULL, NULL)) return 0;
return try_fail(logdepth, "libs/fs/mkdtemp");
}
int find_fs_mmap(const char *name, int logdepth, int fatal)
{
char test_c[1024];
char *tmp;
FILE *f;
char *test_c_in =
NL "#include <stdio.h>"
NL "#include <unistd.h>"
NL "#include <string.h>"
NL "#include <sys/types.h>"
NL "#include <sys/stat.h>"
NL "#include <fcntl.h>"
NL "int main() {"
NL " int fd, size = 11;"
NL " void *p;"
NL " fd = open(\"%s\", O_RDONLY);"
NL " p = mmap(0, size, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);"
NL " if (p == NULL) {"
NL " puts(\"mmap fail\");"
NL " return 0;"
NL " }"
NL " if (strcmp(p, \"hello world\") != 0) {"
NL " puts(\"strcmp fail\");"
NL " return 0;"
NL " }"
NL " if (munmap(p, size) != 0) {"
NL " puts(\"munmap fail\");"
NL " return 0;"
NL " }"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
tmp = tempfile_new("");
f = fopen(tmp, "w");
fprintf(f, "hello world");
fclose(f);
sprintf(test_c, test_c_in, tmp);
report("Checking for mmap... ");
logprintf(logdepth, "find_fs_mmap: trying to find mmap()...\n");
logdepth++;
if (try_icl(logdepth, "libs/fs/mmap", test_c, "#include <sys/mman.h>\n", NULL, NULL)) {
unlink(tmp);
free(tmp);
return 0;
}
unlink(tmp);
free(tmp);
return try_fail(logdepth, "libs/fs/mmap");
}
/* Haiku/BeOS next_dev */
int find_fsmount_next_dev(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <stdio.h>"
NL "int main()"
NL "{"
NL " int32 pos = 0;"
NL " dev_t res = next_dev(&pos);"
NL " if (res >= 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for next_dev... ");
logprintf(logdepth, "find_fsmount_next_dev: trying to find next_dev()...\n");
logdepth++;
if (try_icl(logdepth, "libs/fsmount/next_dev", test_c, "#include <fs_info.h>\n", NULL, NULL)) return 0;
return try_fail(logdepth, "libs/fsmount/next_dev");
}
int find_fsmount_fsstat_fields(const char *name, int logdepth, int fatal)
{
const char *fields[] = {"f_fstypename", NULL};
return try_icl_sfields(logdepth, "libs/fsmount/struct_fsstat", "struct fsstat", fields, "#include <sys/fsstat.h>", NULL, NULL, 0);
}
int find_fsmount_statfs_fields(const char *name, int logdepth, int fatal)
{
const char *fields[] = {"f_fstypename", "f_type", NULL};
return try_icl_sfields(logdepth, "libs/fsmount/struct_statfs", "struct statfs", fields, "#include <sys/statfs.h>", NULL, NULL, 0);
}
int find_fsmount_statvfs_fields(const char *name, int logdepth, int fatal)
{
const char *fields[] = {"f_fstypename", "f_type", "f_basetype", NULL};
return try_icl_sfields(logdepth, "libs/fsmount/struct_statvfs", "struct statvfs", fields, "#include <sys/statvfs.h>", NULL, NULL, 0);
}
int find_fs_ustat(const char *name, int logdepth, int fatal)
{
const char *key = "libs/fs/ustat";
const char *test_c =
NL "#include <stdio.h>"
NL "#include <sys/stat.h>"
NL "int main()"
NL "{"
NL " struct stat stat_buf;"
NL " struct ustat ustat_buf;"
NL " if (stat(\".\", &stat_buf) == 0 &&"
NL " ustat(stat_buf.st_dev, &ustat_buf) == 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for ustat... ");
logprintf(logdepth, "find_fs_ustat: trying to find ustat()...\n");
logdepth++;
if (try_icl(logdepth, key, test_c, "#include <ustat.h>", NULL, NULL)) return 0;
if (try_icl(logdepth, key, test_c, "#include <unistd.h>", NULL, NULL)) return 0;
if (try_icl(logdepth, key, test_c, "#include <sys/types.h>\n#include <unistd.h>", NULL, NULL)) return 0;
if (try_icl(logdepth, key, test_c, "#include <sys/types.h>\n#include <unistd.h>\n#include <ustat.h>", NULL, NULL)) return 0;
return try_fail(logdepth, key);
}
int find_fs_statfs(const char *name, int logdepth, int fatal)
{
const char *key = "libs/fs/statfs";
const char *test_c =
NL "#include <stdio.h>"
NL "int main()"
NL "{"
NL " struct statfs statfs_buf;"
NL " if (statfs(\".\", &statfs_buf) == 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for statfs... ");
logprintf(logdepth, "find_fs_statfs: trying to find statfs()...\n");
logdepth++;
if (try_icl(logdepth, key, test_c, "#include <sys/statfs.h>", NULL, NULL)) return 0;
if (try_icl(logdepth, key, test_c, "#include <sys/vfs.h>", NULL, NULL)) return 0;
return try_fail(logdepth, key);
}
int find_fs_statvfs(const char *name, int logdepth, int fatal)
{
const char *key = "libs/fs/statvfs";
const char *test_c =
NL "#include <stdio.h>"
NL "int main()"
NL "{"
NL " struct statvfs statvfs_buf;"
NL " if (statvfs(\".\", &statvfs_buf) == 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for statvfs... ");
logprintf(logdepth, "find_fs_statvfs: trying to find statvfs()...\n");
logdepth++;
if (try_icl(logdepth, key, test_c, "#include <sys/statvfs.h>", NULL, NULL)) return 0;
return try_fail(logdepth, key);
}
int find_fs_flock(const char *name, int logdepth, int fatal)
{
const char *key = "libs/fs/flock";
const char *test_c =
NL "#include <stdio.h>"
NL "int main()"
NL "{"
NL " if (flock(1, LOCK_UN) == 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for flock... ");
logprintf(logdepth, "find_fs_flock: trying to find flock()...\n");
logdepth++;
if (try_icl(logdepth, key, test_c, "#include <sys/file.h>", NULL, NULL)) return 0;
return try_fail(logdepth, key);
}

View File

@ -1,357 +0,0 @@
/*
scconfig - evaluate uname and classify the system
Copyright (C) 2009 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "regex.h"
#include "log.h"
#include "db.h"
#include "libs.h"
#include "dep.h"
static void sys_unix(void)
{
put("sys/ext_exe", "");
put("sys/ext_dynlib", ".so");
put("sys/ext_stalib", ".a");
put("sys/ext_dynlib_native", ".so");
}
static void sys_netbsd(void)
{
sys_unix();
put("cc/ldflags", "-Wl,-R/usr/pkg/lib -L/usr/pkg/lib"); /* TODO: is this the best way? */
}
static void sys_win32dlc(void)
{
put("sys/ext_exe", ".exe");
put("sys/ext_dynlib", ".dlc");
put("sys/ext_stalib", ".a");
put("sys/ext_dynlib_native", ".dll");
}
typedef void (*callback_t)(void);
typedef struct {
char *uname_regex;
char *name;
char *class;
callback_t callback;
} uname_t;
typedef struct {
char *file_name;
char *name;
char *class;
callback_t callback;
} magic_file_t;
/* Guess system class by uname; class is informative, nothing important
should depend on it.
Order *does* matter */
uname_t unames[] = {
{"[Nn]et[Bb][Ss][Dd]", "NetBSD", "UNIX", sys_netbsd},
{"[Ll]inux", "Linux", "UNIX", sys_unix},
{"[Bb][Ss][Dd]", "BSD", "UNIX", sys_unix},
{"SunOS", "SunOS", "UNIX", sys_unix},
{"OSF1", "OSF", "UNIX", sys_unix}, /* TODO: note the difference in cflags for debugging ("-ms -g") */
{"IRIX", "IRIX", "UNIX", sys_unix},
{"SunOS", "SunOS", "UNIX", sys_unix},
{"[Mm]inix", "Minix", "UNIX", sys_unix},
{"[Aa][Rr][Oo][Ss]", "Aros", "UNIX", sys_unix},
{"^Darwin", "MacOSX", "UNIX", sys_unix},
{"[Th]hreos", "Threos", "UNIX", sys_unix},
{"[Cc]ygwin", "cygwin", "WIN32", sys_win32dlc},
{"[Mm][Ii][Nn][Gg][Ww]", "mingw", "WIN32", sys_win32dlc},
{"win32", "win32", "WIN32", sys_win32dlc}, /* vanilla windows */
{NULL, NULL, NULL, NULL}
};
/* Fallback: extract machine name from uname -a if uname -m fails */
static const char *machine_names[] = {
"i[0-9]86[^ ]*", "x86_[^ ]*", "amd[0-9]*", "armv[0-9][^ ]*", "ppc[0-9]+",
"sparc[0-9]*", "BePC", "ia64", "x86", "IP[0-9]*", "k1om", "sun4u",
"RM600", "R4000", "alpha",
NULL
};
/* Fallback: extract system name from uname -a if uname -s fails */
static const char *system_names[] = {
"[Ll]inux", "sn5[0-9]*", "CYGWIN_NT[^ ]*", "GNU[^ ]*", "DragonFly",
"[^ ]*BSD[^ ]*", "Haiku", "HP-UX", "AIX", "OS4000", "Interix",
"IRIX[0-9]*", "Darwin", "Minix", "MINGW[^ ]*", "ReliantUNIX[^ ]*",
"SunOS", "OSF1", "ULTRIX", "UWIN-W7", "IS/WB", "OS/390",
"SCO[^ ]*", "QNX",
NULL
};
/* Fallback: if uname -a fails, guess system by looking at "magic file names" */
magic_file_t magic_files[] = {
{"/dev/null", "UNIX", "UNIX", sys_unix},
{"c:\\config.sys", "win32", "WIN32", sys_win32dlc},
{"c:\\windows\\system.ini", "win32", "WIN32", sys_win32dlc},
{"c:\\windows\\win.ini", "win32", "WIN32", sys_win32dlc},
{"c:\\windows\\notepad.exe", "win32", "WIN32", sys_win32dlc},
{NULL, NULL, NULL, NULL}
} ;
static int match(const char *regex, const char *str)
{
re_comp(regex);
return re_exec(str);
}
/* match uname against each pattern on the list; on a match, put() the portion
of the string matched in node and return 1 */
int uname_guess(const char *node, const char *uname, const char *list[])
{
const char **l;
if (uname == NULL)
return 0;
for(l = list; *l != NULL; l++) {
if (match(*l, uname)) {
char *s;
int len = eopat[0] - bopat[0];
s = malloc(len+1);
memcpy(s, bopat[0], len);
s[len] = '\0';
put(node, s);
return 1;
}
}
return 0;
}
/* Don't worry about linear search or matching regexes all the time - this
function will be run at most two times */
static callback_t lookup_uname(char **uname, const char **name, const char **class)
{
uname_t *u;
for(u = unames; u->uname_regex != NULL; u++) {
if (
((*uname != NULL) && (match(u->uname_regex, *uname))) /* uname match */
|| ((*name != NULL) && ((strcmp(u->name, *name) == 0))) /* name match */
|| ((*class != NULL) && ((strcmp(u->class, *class) == 0))) /* class match */
) {
if (*name == NULL) *name = u->name;
if (*class == NULL) *class = u->class;
return u->callback;
}
}
return NULL;
}
static callback_t lookup_magic_file(int logdepth, const char **name, const char **class)
{
magic_file_t *u;
for(u = magic_files; u->file_name != NULL; u++) {
if (is_file(u->file_name)) {
logprintf(logdepth, "%s -> %s\n", u->file_name, u->class);
if (*name == NULL) *name = u->name;
if (*class == NULL) *class = u->class;
return u->callback;
}
}
return NULL;
}
int find_uname(const char *rname, int logdepth, int fatal)
{
const char *name, *class, *tname, *uname_orig;
char *s, *uname, *mname, *sname;
void (*callback)(void);
require("sys/tmp", logdepth, fatal);
if (istarget(db_cwd))
require("/target/sys/target", logdepth, fatal);
report("Checking for system type... ");
logprintf(logdepth, "[find_uname] checking for sys/name\n");
logdepth++;
tname = get("/arg/sys/target-name");
if (istarget(db_cwd) && (tname != NULL))
put("sys/name", tname);
tname = get("/arg/sys/target-uname");
if (istarget(db_cwd) && (tname != NULL))
put("sys/uname", tname);
name = get("sys/name");
uname_orig = get("sys/uname");
if (name == NULL) {
if (uname_orig == NULL) {
logprintf(logdepth, "not set, running\n");
run_shell(logdepth, "uname -a", (char **)&uname);
if (uname != NULL) {
for(s = uname; *s != '\0'; s++)
if ((*s == '\n') || (*s == '\r')) *s = ' ';
put("sys/uname", uname);
}
else
put("sys/uname", "");
if (run_shell(logdepth, "uname -m", (char **)&mname) == 0)
put("sys/machine_name", strip(mname));
else
put("sys/machine_name", NULL);
if (mname != NULL)
free(mname);
if (run_shell(logdepth, "uname -o", (char **)&sname) == 0)
put("sys/system_name", strip(sname));
else if (run_shell(logdepth, "uname -s", (char **)&sname) == 0)
put("sys/system_name", strip(sname));
else
put("sys/system_name", NULL);
if (sname != NULL)
free(sname);
}
/* we have uname by now, set sys/name */
name = NULL;
class = NULL;
callback = lookup_uname(&uname, &name, &class);
if (name == NULL) {
/* no uname or unknown system by uname - fallback: check for cross target */
const char *target = get("/arg/sys/target");
if ((target != NULL) && (strstr(target, "mingw") != NULL)) {
name = "WIN32";
report("(detected mingw cross compilation to WIN32)\n");
}
else {
report("Warning: unknown system\n");
name = "unknown";
}
}
put("sys/name", name);
}
else {
/* we had sys/name, that should be enough */
uname = NULL;
class = name;
callback = lookup_uname(&uname, &name, &class);
}
/* predefined and/or detected uname failed, try magic file method */
if (callback == NULL) {
logprintf(logdepth, "System class is unknown by uname, running heuristics...\n");
report("System class is unknown by uname, running heuristics... ");
callback = lookup_magic_file(logdepth + 1, &name, &class);
}
if (callback == NULL) {
/* System unknown. */
error("Unknown system '%s'\n", get("sys/uname"));
abort();
}
callback();
report("OK (name: %s; class: %s)\n", name, class);
put("sys/class", class);
/* fallbacks */
if (get("sys/machine_name") == NULL)
uname_guess("sys/machine_name", uname, machine_names);
if (get("sys/system_name") == NULL)
uname_guess("sys/system_name", uname, system_names);
/* on windows, overwrite the path sep with the right amount of \ (the tmp finder may have left / in it) */
if ((strcmp(class, "WIN32") == 0) || (strcmp(class, "win32") == 0)) {
int eats = istrue(get("sys/shell_eats_backslash"));
if (eats)
put("sys/path_sep", "\\\\\\\\");
else
put("sys/path_sep", "\\");
put("sys/path_sep_escaped", "\\\\");
}
return 0;
}
static int find_triplet_(const char *name, int logdepth, int fatal, const char *nodename, int include_vendor, char *sep, char *esc)
{
const char *machine, *vendor, *os;
char *triplet, *s;
char fake_sep[2];
fake_sep[0] = 1;
fake_sep[1] = 0;
require("sys/uname", logdepth, fatal);
machine = get("sys/machine_name");
if (machine == NULL)
machine = "unknown";
vendor = "unknown";
os = get("sys/system_name");
if (os == NULL)
os = "unknown";
if (include_vendor)
triplet = str_concat(fake_sep, machine, vendor, os, NULL);
else
triplet = str_concat(fake_sep, machine, os, NULL);
for(s = triplet; *s != '\0'; s++) {
if ((esc != NULL) && (*s == *sep))
*s = *esc;
if (isalnum(*s))
*s = tolower(*s);
else {
if (*s == *fake_sep)
*s = *sep;
else if (esc != NULL)
*s = *esc;
else
*s = '-';
}
}
put(nodename, triplet);
free(triplet);
return 0;
}
int find_triplet(const char *name, int logdepth, int fatal)
{
return find_triplet_(name, logdepth, fatal, "sys/triplet", 1, "-", NULL);
}
int find_sysid(const char *name, int logdepth, int fatal)
{
return find_triplet_(name, logdepth, fatal, "sys/sysid", 0, "-", "_");
}

View File

@ -1,166 +0,0 @@
/*
scconfig - detection of environmental variable access features
Copyright (C) 2014 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
int find_main_arg3(const char *name, int logdepth, int fatal)
{
char *out;
char *test_c =
NL "#include <stdlib.h>"
NL "#include <stdio.h>"
NL "int main(int argc, char *argv[], char *env[])"
NL "{"
NL " char **e;"
NL " int cnt;"
NL " for(e = env, cnt = 0; *e != NULL; e++, cnt++) ;"
NL " printf(\"%d\\n\", cnt);"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for main() with 3 arguments... ");
logprintf(logdepth, "find_main_3args: checking for main() with 3 arguments\n");
if (compile_run(logdepth+1, test_c, NULL, NULL, NULL, &out) == 0) {
if (atoi(out) > 1) {
put("libs/env/main_3arg", strue);
report("OK\n");
free(out);
return 0;
}
free(out);
report("not found (broken output).\n");
}
else {
report("not found (no output).\n");
}
put("libs/env/main_3arg", sfalse);
return 1;
}
int find_environ(const char *name, int logdepth, int fatal)
{
char *out;
char *test_c =
NL "#include <stdlib.h>"
NL "#include <stdio.h>"
NL "extern char **environ;"
NL "int main(int argc, char *argv[])"
NL "{"
NL " char **e;"
NL " int cnt;"
NL " for(e = environ, cnt = 0; *e != NULL; e++, cnt++) ;"
NL " printf(\"%d\\n\", cnt);"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for extern environ... ");
logprintf(logdepth, "find_environ: checking for extern environ\n");
if (compile_run(logdepth+1, test_c, NULL, NULL, NULL, &out) == 0) {
if (atoi(out) > 1) {
put("libs/env/environ", strue);
report("OK\n");
free(out);
return 0;
}
free(out);
report("not found (broken output).\n");
}
else {
report("not found (no output).\n");
}
put("libs/env/environ", sfalse);
return 1;
}
int find_putenv(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <stdlib.h>"
NL "#include <stdio.h>"
NL "int main(int argc, char *argv[])"
NL "{"
NL " putenv(\"SCCONFIG_TEST=bad\");"
NL " putenv(\"SCCONFIG_TEST=OK\");"
NL " printf(\"%s\\n\", getenv(\"SCCONFIG_TEST\"));"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for putenv()... ");
logprintf(logdepth, "find_putenv: trying to find putenv...\n");
logdepth++;
if (try_icl(logdepth, "libs/env/putenv", test_c, "", NULL, NULL))
return 0;
if (try_icl(logdepth, "libs/env/putenv", test_c, "#define _XOPEN_SOURCE", NULL, NULL))
return 0;
if (try_icl(logdepth, "libs/env/putenv", test_c, "#define _SVID_SOURCE", NULL, NULL))
return 0;
return try_fail(logdepth, "libs/env/putenv");
}
int find_setenv(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <stdlib.h>"
NL "#include <stdio.h>"
NL "int main(int argc, char *argv[])"
NL "{"
NL " setenv(\"SCCONFIG_TEST\", \"bad\", 1);"
NL " setenv(\"SCCONFIG_TEST\", \"OK\", 1);"
NL " printf(\"%s\\n\", getenv(\"SCCONFIG_TEST\"));"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for setenv()... ");
logprintf(logdepth, "find_setenv: trying to find setenv...\n");
logdepth++;
if (try_icl(logdepth, "libs/env/setenv", test_c, "", NULL, NULL))
return 0;
if (try_icl(logdepth, "libs/env/setenv", test_c, "#define _BSD_SOURCE", NULL, NULL))
return 0;
if (try_icl(logdepth, "libs/env/setenv", test_c, "#define _POSIX_C_SOURCE 200112L", NULL, NULL))
return 0;
if (try_icl(logdepth, "libs/env/setenv", test_c, "#define _XOPEN_SOURCE 600", NULL, NULL))
return 0;
return try_fail(logdepth, "libs/env/setenv");
}

View File

@ -1,171 +0,0 @@
/* cc */
int find_cc(const char *name, int logdepth, int fatal);
int find_cc_argstd(const char *name, int logdepth, int fatal);
int find_cc_argmachine(const char *name, int logdepth, int fatal);
int find_cc_fpie(const char *name, int logdepth, int fatal);
int find_cc_fnopie(const char *name, int logdepth, int fatal);
int find_cc_fnopic(const char *name, int logdepth, int fatal);
int find_inline(const char *name, int logdepth, int fatal);
int find_varargmacro(const char *name, int logdepth, int fatal);
int find_funcmacro(const char *name, int logdepth, int fatal);
int find_constructor(const char *name, int logdepth, int fatal);
int find_destructor(const char *name, int logdepth, int fatal);
int find_fattr_unused(const char *name, int logdepth, int fatal);
int find_declspec_dllimport(const char *name, int logdepth, int fatal);
int find_declspec_dllexport(const char *name, int logdepth, int fatal);
int find_rdynamic(const char *name, int logdepth, int fatal);
int find_soname(const char *name, int logdepth, int fatal);
int find_wlrpath(const char *name, int logdepth, int fatal);
int find_cc_wloutimplib(const char *name, int logdepth, int fatal);
int find_cc_wloutputdef(const char *name, int logdepth, int fatal);
int find_fpic(const char *name, int logdepth, int fatal);
int find_ldflags_dynlib(const char *name, int logdepth, int fatal);
int find_ldflags_dll(const char *name, int logdepth, int fatal);
int find_ldflags_so(const char *name, int logdepth, int fatal);
int find_alloca(const char *name, int logdepth, int fatal);
int find__exit(const char *name, int logdepth, int fatal);
int find_cc_pragma_message(const char *name, int logdepth, int fatal);
int find_cc_static_libgcc(const char *name, int logdepth, int fatal);
/* libs */
int find_lib_ldl(const char *name, int logdepth, int fatal);
int find_lib_LoadLibrary(const char *name, int logdepth, int fatal);
int find_lib_errno(const char *name, int logdepth, int fatal);
/* thread */
int find_lib_lpthread(const char *name, int logdepth, int fatal);
int find_thread_semget(const char *name, int logdepth, int fatal);
int find_thread_pthread_create(const char *name, int logdepth, int fatal);
int find_thread_CreateSemaphore(const char *name, int logdepth, int fatal);
int find_thread_CreateThread(const char *name, int logdepth, int fatal);
/* fscalls */
int find_fs_realpath(const char *name, int logdepth, int fatal);
int find_fs__fullpath(const char *name, int logdepth, int fatal);
int find_fs_readdir(const char *name, int logdepth, int fatal);
int find_fs_findnextfile(const char *name, int logdepth, int fatal);
int find_fs_access(const char *name, int logdepth, int fatal);
int find_fs_access_macros(const char *name, int logdepth, int fatal);
int find_fs_stat_macros(const char *name, int logdepth, int fatal);
int find_fs_stat_fields(const char *name, int logdepth, int fatal);
int find_fs_lstat(const char *name, int logdepth, int fatal);
int find_fs_statlstat(const char *name, int logdepth, int fatal);
int find_fs_getcwd(const char *name, int logdepth, int fatal);
int find_fs__getcwd(const char *name, int logdepth, int fatal);
int find_fs_getwd(const char *name, int logdepth, int fatal);
int find_fs_mkdir(const char *name, int logdepth, int fatal);
int find_fs__mkdir(const char *name, int logdepth, int fatal);
int find_fs_mkdtemp(const char *name, int logdepth, int fatal);
int find_fs_mmap(const char *name, int logdepth, int fatal);
int find_fsmount_next_dev(const char *name, int logdepth, int fatal);
int find_fsmount_fsstat_fields(const char *name, int logdepth, int fatal);
int find_fsmount_statfs_fields(const char *name, int logdepth, int fatal);
int find_fsmount_statvfs_fields(const char *name, int logdepth, int fatal);
int find_fs_ustat(const char *name, int logdepth, int fatal);
int find_fs_statfs(const char *name, int logdepth, int fatal);
int find_fs_statvfs(const char *name, int logdepth, int fatal);
int find_fs_flock(const char *name, int logdepth, int fatal);
/* printf */
int find_printf_x(const char *name, int logdepth, int fatal);
int find_printf_ptrcast(const char *name, int logdepth, int fatal);
int find_snprintf(const char *name, int logdepth, int fatal);
int find_dprintf(const char *name, int logdepth, int fatal);
int find_vdprintf(const char *name, int logdepth, int fatal);
int find_vsnprintf(const char *name, int logdepth, int fatal);
/* proc */
int find_proc__spawnvp(const char *name, int logdepth, int fatal);
int find_proc_fork(const char *name, int logdepth, int fatal);
int find_proc_wait(const char *name, int logdepth, int fatal);
int find_proc__getpid(const char *name, int logdepth, int fatal);
int find_proc_CreateProcessA(const char *name, int logdepth, int fatal);
int find_proc_getexecname(const char *name, int logdepth, int fatal);
int find_proc_GetModuleFileNameA(const char *name, int logdepth, int fatal);
int find_proc_shmget(const char *name, int logdepth, int fatal);
int find_proc_CreateFileMappingA(const char *name, int logdepth, int fatal);
/* fstools */
int find_fstools_cp(const char *name, int logdepth, int fatal);
int find_fstools_ln(const char *name, int logdepth, int fatal);
int find_fstools_mv(const char *name, int logdepth, int fatal);
int find_fstools_rm(const char *name, int logdepth, int fatal);
int find_fstools_mkdir(const char *name, int logdepth, int fatal);
int find_fstools_ar(const char *name, int logdepth, int fatal);
int find_fstools_ranlib(const char *name, int logdepth, int fatal);
int find_fstools_awk(const char *name, int logdepth, int fatal);
int find_fstools_cat(const char *name, int logdepth, int fatal);
int find_fstools_sed(const char *name, int logdepth, int fatal);
int find_fstools_file(const char *name, int logdepth, int fatal);
int find_fstools_file_l(const char *name, int logdepth, int fatal);
int find_fstools_chmodx(const char *name, int logdepth, int fatal);
/* uname */
int find_uname(const char *name, int logdepth, int fatal);
int find_triplet(const char *name, int logdepth, int fatal);
int find_sysid(const char *name, int logdepth, int fatal);
/* find_target */
int find_target(const char *name, int logdepth, int fatal);
/* filelist */
int find_filelist(const char *name, int logdepth, int fatal);
/* find_str.c */
int find_strcasecmp(const char *name, int logdepth, int fatal);
int find_strncasecmp(const char *name, int logdepth, int fatal);
int find_stricmp(const char *name, int logdepth, int fatal);
int find_strnicmp(const char *name, int logdepth, int fatal);
/* find_sys.c */
int find_sys_ptrwidth(const char *name, int logdepth, int fatal);
int find_sys_byte_order(const char *name, int logdepth, int fatal);
int find_tmp(const char *name, int logdepth, int fatal);
int find_shell(const char *name, int logdepth, int fatal);
/* find_io.c */
int find_io_pipe(const char *name, int logdepth, int fatal);
int find_io_dup2(const char *name, int logdepth, int fatal);
int find_io_fileno(const char *name, int logdepth, int fatal);
int find_io_lseek(const char *name, int logdepth, int fatal);
int find_io_popen(const char *name, int logdepth, int fatal);
/* find_time.c */
int find_time_usleep(const char *name, int logdepth, int fatal);
int find_time_Sleep(const char *name, int logdepth, int fatal);
int find_time_gettimeofday(const char *name, int logdepth, int fatal);
int find_time_ftime(const char *name, int logdepth, int fatal);
int find_time_timegm(const char *name, int logdepth, int fatal);
int find_time_mkgmtime(const char *name, int logdepth, int fatal);
int find_time_gmtime_s(const char *name, int logdepth, int fatal);
int find_time_gmtime_r(const char *name, int logdepth, int fatal);
int find_time_localtime_s(const char *name, int logdepth, int fatal);
int find_time_localtime_r(const char *name, int logdepth, int fatal);
/* find_types.c */
int find_types_stdint(const char *name, int logdepth, int fatal);
int find_types_sizes(const char *name, int logdepth, int fatal);
int find_types_size_t(const char *name, int logdepth, int fatal);
int find_types_off_t(const char *name, int logdepth, int fatal);
int find_types_off64_t(const char *name, int logdepth, int fatal);
int find_types_gid_t(const char *name, int logdepth, int fatal);
int find_types_uid_t(const char *name, int logdepth, int fatal);
int find_types_pid_t(const char *name, int logdepth, int fatal);
int find_types_dev_t(const char *name, int logdepth, int fatal);
int find_types_dev_t(const char *name, int logdepth, int fatal);
int find_types_mode_t(const char *name, int logdepth, int fatal);
int find_types_nlink_t(const char *name, int logdepth, int fatal);
int find_types_ptrdiff_t(const char *name, int logdepth, int fatal);
int find_types_dev_t(const char *name, int logdepth, int fatal);
int find_types_ino_t(const char *name, int logdepth, int fatal);
int find_types_void_ptr(const char *name, int logdepth, int fatal);
/* find_signal.c */
int find_signal_names(const char *name, int logdepth, int fatal);
int find_signal_raise(const char *name, int logdepth, int fatal);
/* environ.c */
int find_main_arg3(const char *name, int logdepth, int fatal);
int find_putenv(const char *name, int logdepth, int fatal);
int find_setenv(const char *name, int logdepth, int fatal);
int find_environ(const char *name, int logdepth, int fatal);

View File

@ -1,14 +0,0 @@
#ifndef REGEX_H
#define REGEX_H
extern const char *bopat[];
extern const char *eopat[];
extern char *re_comp(const char *);
extern int re_exec(const char *);
extern void re_modw(char *);
char *re_subs_dup(char *sub);
#endif /* REGEX_H */

View File

@ -1,194 +0,0 @@
/*
scconfig - detect I/O features of the system
Copyright (C) 2010 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
int find_io_pipe(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <unistd.h>"
NL "int main() {"
NL " int fd[2];"
NL " if (pipe(fd) == 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for pipe(2)... ");
logprintf(logdepth, "find_io_pipe: trying to find pipe(2)...\n");
logdepth++;
if (try_icl(logdepth, "libs/io/pipe", test_c, NULL, NULL, NULL)) return 0;
return try_fail(logdepth, "libs/io/pipe");
}
int find_io_dup2(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <unistd.h>"
NL "int main() {"
NL " int fd;"
NL " if (dup2(1, 4) == 4)"
NL " write(4, \"OK\\n\", 3); "
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for dup2(2)... ");
logprintf(logdepth, "find_io_dup2: trying to find dup2(2)...\n");
logdepth++;
if (try_icl(logdepth, "libs/io/dup2", test_c, NULL, NULL, NULL)) return 0;
return try_fail(logdepth, "libs/io/dup2");
}
int find_io_fileno(const char *name, int logdepth, int fatal)
{
char test_c[256];
char *test_c_ =
NL "#include <stdio.h>"
NL "int main() {"
NL no_implicit(int, "%s", "%s")
NL " if (%s(stdout) >= 0)"
NL " puts(\"OK\"); "
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for fileno(3)... ");
logprintf(logdepth, "find_io_fileno: trying to find fileno(3)...\n");
logdepth++;
/* UNIX */
sprintf(test_c, test_c_, "fileno", "fileno", "fileno");
if (try_icl(logdepth, "libs/io/fileno", test_c, "#include <unistd.h>\n", NULL, NULL)) {
put("libs/io/fileno/call", "fileno");
return 0;
}
sprintf(test_c, test_c_, "fileno", "fileno", "fileno");
if (try_icl(logdepth, "libs/io/fileno", test_c, "#define _XOPEN_SOURCE\n#include <unistd.h>\n", NULL, NULL)) {
put("libs/io/fileno/call", "fileno");
return 0;
}
/* windows */
sprintf(test_c, test_c_, "_fileno", "_fileno", "_fileno");
if (try_icl(logdepth, "libs/io/fileno", test_c, "#include <stdio.h>\n", NULL, NULL)) {
put("libs/io/fileno/call", "_fileno");
return 0;
}
return try_fail(logdepth, "libs/io/fileno");
}
int find_io_lseek(const char *name, int logdepth, int fatal)
{
#define NODE "libs/io/lseek"
char test_c[3256];
const char *test_c_template =
NL "#include <stdio.h>"
NL "#include <fcntl.h>"
NL "int main() {"
NL " const char *filename = \"%s\";"
NL no_implicit(int, "%s", "%s")
NL " int fd = open(filename, O_WRONLY);"
NL " if (write(fd, \"abc\", 3) == 3 && %s(fd, 1, SEEK_SET) == 1)"
NL " puts(\"OK\"); "
NL " return 0;"
NL "}"
NL;
char *tmpf;
const char *incs[] = {"#include <unistd.h>","#include <io.h>",NULL};
const char *fns[] = {"lseek", "_lseek", NULL};
const char **inc;
const char **fn;
require("cc/cc", logdepth, fatal);
report("Checking for lseek(2)... ");
logprintf(logdepth, "find_io_lseek: trying to find lseek(2)...\n");
logdepth++;
tmpf = tempfile_new(".psx");
for (inc = incs, fn = fns; *fn; ++inc, ++fn) {
sprintf(test_c, test_c_template, tmpf, *fn, *fn, *fn);
if (try_icl(logdepth, NODE, test_c, *inc, NULL, NULL)) {
unlink(tmpf);
free(tmpf);
put(NODE "/call", *fn);
return 0;
}
}
unlink(tmpf);
free(tmpf);
return try_fail(logdepth, NODE);
#undef NODE
}
int find_io_popen(const char *name, int logdepth, int fatal)
{
const char **i, *incs[] = {"#define _XOPEN_SOURCE", "#define _BSD_SOURCE", "#define _POSIX_C_SOURCE 2", NULL};
char *test_c =
NL "#include <stdlib.h>"
NL "#include <stdio.h>"
NL "int main() {"
NL " FILE *f = popen(\"echo OK\", \"r\");"
NL " char line[16];"
NL " if (f == NULL) return 0;"
NL " if (fgets(line, sizeof(line)-1, f) == NULL) return 0;"
NL " puts(line);"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for popen(3)... ");
logprintf(logdepth, "find_io_popen: trying to find popen(3)...\n");
logdepth++;
for(i = incs; *i != NULL; i++)
if (try_icl(logdepth, "libs/io/popen", test_c, *i, NULL, NULL)) return 0;
return try_fail(logdepth, "libs/io/popen");
}

View File

@ -1,161 +0,0 @@
#define NL "\n"
/* main.c */
extern int no_autodetect_sys; /* set this to 1 to suppress system and cross detection */
extern int no_save_cache; /* set this to 1 to avoid saving config.cache */
/* lib_try.c: try to compile and run a test code; save results under prefix, if worked */
/* include, compile-flags, link-flags;
NULL includes, cflags, *ldflags means don't put anything in the db; cflags
and ldflags may be prefixed with "+" to include standard flags;
the test code has to print "OK" if it worked. If prefix is NULL, do not
modify the db or announce the output, silently return 0 or 1.
Returns 1 if worked, 0 if not */
int try_icl(int logdepth, const char *prefix, const char *test_c_in, const char *includes, const char *cflags,
const char *ldflags);
/* same as try_icl(), but does not execute the code, only compiles. Useful
for test programs with undesirable side effects (e.g. gtk: would open a window) */
int try_icl_norun(int logdepth, const char *prefix, const char *test_c_in, const char *includes, const char *cflags,
const char *ldflags);
/* same as try_icl, but also insert flags picked up from deps (if not NULL);
useful for detecting features that depend on other detected features.
If run is 0, do not run the test program, compile only */
int try_icl_with_deps(int logdepth, const char *prefix, const char *test_c_in, const char *includes, const char *cflags, const char *ldflags, const char *dep_includes, const char *dep_cflags, const char *dep_ldflags, int run);
/* Low level function for the same, giving more control to the caller */
int try_icl_(int logdepth, const char *prefix, const char *test_c_in, const char *includes, const char *cflags, const char *ldflags, int run, int (*accept_res)(char *stdout_str));
/* use try_icl() on a list of packages found by pkg-config. Stick to the version
required if reqver is non-NULL, else try them in the order pkg-config returned
them. */
int try_icl_pkg_config(int logdepth, const char *prefix, const char *test_c, char *includes, const char *pkgpat,
const char *reqver);
/* call this when failed to find the feature (after multiple try_*() calls);
always returns 1 (so that return try_fail() does the Right Thing) */
int try_fail(int logdepth, const char *prefix);
/* Import an argument for controlling try_icl() */
int import_icl(const char *key, const char *fn);
/* Determine the sizeof() of a struct field; works the same way as icl() but
also sets prefix/sizeof */
int try_icl_sfield(int logdepth, const char *prefix, const char *structn, const char *fieldn, const char *includes, const char *cflags, const char *ldflags);
int try_icl_sfields(int logdepth, const char *prefix, const char *structn, const char **fields, const char *includes, const char *cflags, const char *ldflags, int silent_exit_first_fail);
/* lib_compile.c */
extern int cross_blind; /* 1 if crosscompiling is blind (no emulator to test with) */
char *shell_escape_dup(const char *in); /* strdup in and escape any special char for the shell */
int compile_file(int logdepth, const char *fn_input, char **fn_output, const char *cc, const char *cflags, const char *ldflags);
int compile_code(int logdepth, const char *testcode, char **fn_output, const char *cc, const char *cflags, const char *ldflags);
/* same as above, but do not add cc/cflags and cc/ldfags */
int compile_file_raw(int logdepth, const char *fn_input, char **fn_output, const char *cc, const char *cflags, const char *ldflags);
int compile_code_raw(int logdepth, const char *testcode, char **fn_output, const char *cc, const char *cflags, const char *ldflags);
int run(int logdepth, const char *cmd_, char **stdout_saved);
int run_shell(int logdepth, const char *cmd_, char **stdout_saved);
int compile_run(int logdepth, const char *testcode, const char *cc, const char *cflags, const char *ldflags,
char **stdout_saved);
int run_script(int logdepth, const char *interpreter, const char *script, const char *suffix, char **out);
/* lib_file.c */
int file_size(const char *name);
char *tempdir_new(int logdepth, const char *suffix);
char *tempfile_new(const char *suffix);
char *tempfile_dump(const char *testcode, const char *suffix);
char *load_file(const char *name);
int is_dir(const char *path);
int is_file(const char *path);
int exists(const char *path);
int exists_in(const char *dir, const char *file);
char *file_name(const char *path); /* returns malloc'd buffer */
char *dir_name(const char *path); /* returns malloc'd buffer */
char *tempfile_new_noabort(const char *suffix); /* for internal use - returns NULL instead of aborting when temp file can not be created */
int touch_file(const char *path);
/* lib_filelist.c */
void filelist(int logdepth, const char *dir, int *argc, char ***argv);
void filelist_free(int *argc, char ***argv);
/* lib_pkg_config.c */
/** run pkg config on @pkgname:
- with `--cflags` if cflags is not NULL, storing the result in cflags (malloc()'d)
- with `--libs` if ldflags is not NULL, storing the result in ldflags (malloc()'d)
Returns 0 on success.
*/
int run_pkg_config(int logdepth, const char *pkgname, char **cflags, char **ldflags);
/** same as run_pkg_config(), but runs a generic config tool (e.g. gdconfig)
passed in confname */
int run_gen_config(int logdepth, const char *confname, const char *pkgname, char **cflags, char **ldflags);
int run_pkg_config_modversion(int logdepth, const char *pkgname, char **modversion);
int run_pkg_config_modversion_db(int logdepth, const char *node, const char *pkgname);
/** run pkg-config --list-all and keep lines matching regex pkgpat.
argc/argv is a filelist output, each item pair is package name returned by
pkg_config (odd items are full package names, even items are suffixes:
pkgpath match removed)
*/
void run_pkg_config_lst(int logdepth, const char *pkgpat, int *argc, char ***argv);
/* lib_uniqinc.c */
char **uniq_inc_arr(const char *includes, int indirect, const char *sep, int *numlines); /* split includes by sep; includes is a list of nodes to get() if indirect is non-zero; return a NULL-terminated array of unique include strings and set *numlines if numlines is not NULL */
void uniq_inc_free(char **arr); /* free an array returned by uniq_inc_arr() */
char *uniq_inc_str(const char *includes, const char *isep, const char *osep, int sort, int eren, char **eres); /* take a long list of includes separated by isep and emit an uniq list separated by osep */
char *order_inc_str(const char *includes, const char *isep, const char *word1, int dir, const char *word2); /* take a long list of includes separated by isep and emit a new list where word1 is moved before/after of word2 if dir < 0 or dir > 0 */
/* find_types.c */
int find_types_something_t(const char *name, int logdepth, int fatal, const char* prefix, const char *typ, const char* define, const char *try_include);
/* str.c */
char *strclone(const char *str);
char *trim_left(char *str);
char *trim_right(char *str);
char *strip(char *str);
char *str_chr(char *str, char c);
char *str_rchr(char *str, char c);
char *str_subsn(const char *str); /* advanced strdup that also interprets \n */
char *str_concat(const char *sep, ...); /* concat a list of strings into a newly allocated buffer, putting sep between them */
char *esc_interpret(const char *str);
int chr_inset(char c, const char *set); /* returns whether c is in set */
/* srctree.c */
/* Run svn info on dir and extract the value for key;
key is case sensitive. The first match is returned or NULL if not found
or on error. */
char *svn_info(int logdepth, const char *dir, const char *key);
#define isblind(root) ((strncmp((root), "/target", 7) == 0) && cross_blind)
#define istarget(root) (strncmp((root), "/target", 7) == 0)
#define target_emu_fail(out) ((isblind(db_cwd)) && (out == NULL))
#define safeNULL(s) ((s) == NULL ? "(NULL)" : (s))
#define str_null(s) ((s) == NULL ? "" : (s))
/* Test program helper: generate code that ensures a given FUNCT exists
and is a function; can be turned off by defining SCCONFIG_ACCEPT_IMPLICIT
on scconfig compilation time */
/* Both FUNCT1 and FUNCT2 argument *must* be used exactly once! In some
cases FUNCT1 and FUNCT2 is a format string parameter. We expect, however,
both arguments will substituted to the same value. */
#ifdef SCCONFIG_ACCEPT_IMPLICIT
# define no_implicit(RET_TYPE, FUNCT1, FUNCT2) \
"/* accept implicit (" FUNCT1 ", " FUNCT2 ") */\n"
#else
# define no_implicit(RET_TYPE, FUNCT1, FUNCT2) \
"#ifndef " FUNCT1 "\n" \
"{ " #RET_TYPE " (*tmp)() = " FUNCT2 "; if (tmp) {}}\n" \
"#endif\n"
#endif

View File

@ -1,496 +0,0 @@
/*
scconfig - detect features of the system or the host/target computer
Copyright (C) 2009..2012 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
int find_sys_ptrwidth(const char *name, int logdepth, int fatal)
{
char *end, W[32];
char *out = NULL;
int w;
char *test_c =
NL "#include <stdio.h>"
NL "int main() {"
NL " void *ptr;"
NL " printf(\"%d\\n\", sizeof(ptr));"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for pointer width... ");
logprintf(logdepth, "find_sys_ptrwidth: trying to find pointer width...\n");
logdepth++;
if (compile_run(logdepth, test_c, NULL, NULL, NULL, &out) == 0) {
w = strtol(out, &end, 10);
if ((*end != '\0') && (*end != '\n') && (*end != '\r')) {
report("FAILED (test code failed)\n");
logprintf(logdepth+1, "FAILED: returned '%s' which is not a valid decimal number (at '%s')\n", out, end);
return 1;
}
sprintf(W, "%d", w * 8);
report("OK (%s bits)\n", W);
put("sys/ptrwidth", W);
logprintf(logdepth+1, "OK (%s bits)\n", W);
}
return 0;
}
int find_sys_byte_order(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <stdio.h>"
NL "int main() {"
NL " long int i = 8;"
NL " char *s = (char *)&i;"
NL " printf(\"%d\\n\", s[0]);"
NL " return 0;"
NL "}"
NL;
const char* test_c_blind_template =
NL "#include <stdio.h>"
NL "#include <endian.h>"
NL "#ifndef __BYTE_ORDER"
NL "#error \"ERROR 1\""
NL "void void *;"
NL "#endif"
NL "#ifndef __%s_ENDIAN"
NL "#error \"ERROR 2\""
NL "char char *;"
NL "#endif"
NL "#if __BYTE_ORDER != __%s_ENDIAN"
NL "#error \"ERROR 3\""
NL "int int *;"
NL "#endif"
NL "int main() {"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char *key = "sys/byte_order";
const char *endians1[] = { "LITTLE", "BIG", NULL };
const char *endians2[] = { "LSB", "MSB", NULL };
int index;
char test_c_blind[1024];
char *end;
const char *W;
char *out = NULL;
int w;
require("cc/cc", logdepth, fatal);
report("Checking for byte order... ");
logprintf(logdepth, "find_sys_byte_order: trying to find byte order...\n");
logdepth++;
if ((!isblind(db_cwd)) && compile_run(logdepth, test_c, NULL, NULL, NULL, &out) == 0) {
w = strtol(out, &end, 10);
if (((*end != '\0') && (*end != '\n') && (*end != '\r')) || ((w != 0) && (w != 8))) {
report("FAILED (test code failed)\n");
logprintf(logdepth+1, "FAILED: returned '%s' which is not a valid decimal number (at '%s')\n", out, end);
return 1;
}
if (w == 0)
W = "MSB";
else
W = "LSB";
report("OK (%s first)\n", W);
put("sys/byte_order", W);
logprintf(logdepth+1, "OK (%s first)\n", W);
return 0;
}
for (index=0; endians1[index]!=NULL; ++index)
{
sprintf(test_c_blind, test_c_blind_template, endians1[index], endians1[index]);
if (compile_run(logdepth, test_c_blind, NULL, NULL, NULL, NULL) == 0)
{
W = endians2[index];
report("OK (%s first)\n", W);
put(key, W);
return 0;
}
}
report("FAILED (cannot determine byte order, you must supply it)\n");
return try_fail(logdepth, key);
}
static int test_shell_eats_backslash(int logdepth)
{
char *test = "echo c:\\n";
char *out;
logprintf(logdepth, "testing if shell eats \\...\n");
run_shell(logdepth+1, test, &out);
if (out == NULL) {
logprintf(logdepth+1, "oops, couldn't run shell?! (returned NULL)\n");
report("ERROR: shell fails.");
abort();
}
if (out[2] == '\\') {
logprintf(logdepth, "shell does NOT eat \\...\n");
put("sys/shell_eats_backslash", sfalse);
free(out);
return 0;
}
free(out);
logprintf(logdepth, "shell eats \\...\n");
put("sys/shell_eats_backslash", strue);
return 1;
}
static int try_get_cwd(int logdepth, const char *cmd)
{
char *cwd, *end;
run_shell(logdepth+1, cmd, &cwd);
if (cwd != NULL) {
end = strpbrk(cwd, "\r\n");
if (end != NULL)
*end = '\0';
if (*cwd != '\0') {
end = cwd + strlen(cwd) - 1;
while((*end == ' ') || (*end == '\t')) { *end = '\0'; end--; }
put("sys/tmp", cwd);
/* ugly hack for win32: paths there start as c:\ */
if ((cwd[1] == ':') && (cwd[2] == '\\'))
append("sys/tmp", "\\");
else
append("sys/tmp", "/");
logprintf(logdepth, "cwd is '%s'\n", get("sys/tmp"));
free(cwd);
return 1;
}
else
free(cwd);
}
return 0;
}
static int try_tmp(int logdepth)
{
char *fn;
logprintf(logdepth, "validating temp dir '%s'\n", get("sys/tmp"));
fn = tempfile_new_noabort("");
if (fn != NULL) {
unlink(fn);
free(fn);
logprintf(logdepth, "temp dir works!\n");
return 1;
}
logprintf(logdepth, "temp dir fails\n");
return 0;
}
/* test temp dir with all sort of workarounds */
static int try_tmp_all(int logdepth)
{
const char *tmp, *si;
char c;
char *t, *so, *old_tmp;
int eats, n;
tmp = get("sys/tmp");
/* path must end in path separator */
c = tmp[strlen(tmp)-1];
if ((c != '/') && (c != '\\')) {
append("sys/tmp", "/");
tmp = get("sys/tmp");
}
logprintf(logdepth, "trying detected temp dir '%s'\n", tmp);
if (try_tmp(logdepth+1)) return 1;
/* try msys-on-windows hack: if path starts with /d/something, try d:/ instead */
if ((tmp[0] == '/') && (isalpha(tmp[1])) && (tmp[2] == '/')) {
/* for the next test we shouldn't use our half-detected tmp path but go with . */
old_tmp = strclone(tmp);
put("sys/tmp", "");
eats = istrue(get("sys/shell_eats_backslash"));
tmp = old_tmp;
logprintf(logdepth, "tmp2='%s' eats=%d\n", tmp, eats);
t = malloc(strlen(tmp) * 2);
t[0] = tmp[1];
t[1] = ':';
for(si = tmp + 2, so = t + 2; *si != '\0'; si++, so++) {
if (*si == '/') {
*so = '\\';
if (eats) {
for(n = 0; n < 3; n++) {
so++;
*so = '\\';
}
}
}
else
*so = *si;
}
*so = '\0';
free(old_tmp);
logprintf(logdepth, "trying windows fix: '%s'\n", t);
put("sys/tmp", t);
free(t);
if (try_tmp(logdepth+1)) {
if (eats)
put("sys/path_sep", "\\\\\\\\");
else
put("sys/path_sep", "\\");
put("sys/path_sep_escaped", "\\\\");
return 1;
}
tmp = get("sys/tmp");
}
/* fail. Set back tmp to empty so next command has a chance to run */
put("sys/tmp", "");
return 0;
}
int find_tmp(const char *name, int logdepth, int fatal)
{
const char *usertmp;
if (in_cross_target) {
report("Temp dir for cross compilation target is the same as for host...");
logprintf(logdepth, "Copying temp dir from host to target\n");
require("/host/sys/tmp", logdepth, fatal);
usertmp = get("/host/sys/tmp");
if (usertmp == NULL) {
report("Host temp dir not found.\n");
logprintf(logdepth, "Host temp dir not found.\n");
return 1;
}
put("sys/tmp", usertmp);
return 0;
}
/* we need shell for later tests; do this detection in . */
put("sys/tmp", "");
require("sys/shell", logdepth, fatal);
put("sys/path_sep", "/");
put("sys/path_sep_escaped", "/");
report("Detecting temp dir...");
logprintf(logdepth, "Finding temp dir (current working directory)...\n");
usertmp = get("/arg/sys/tmp");
/* . as tmp would fail for commands including a "cd" - this would cause
temporary files left in the target dir. We start out with empty
string (which is ., but on windows ./ would fail), and run
pwd (without cd) to find out the current directory (as getcwd() is not
portable). If pwd fails, we stay with ./ */
put("sys/tmp", "");
/* we need to know about shell backslash problem regardless of how
we end up with tmp - currently tmp is ., where the test could run
safely */
test_shell_eats_backslash(logdepth+1);
/* Special case: cross-compilation with emulator; we can not assume
the emulator uses the same paths as the host system, while we mix
accessing files from host and emu. If we stay in ., both emulator
and host system should be (more or less) happy. */
if (istarget(db_cwd) && iscross) {
if (usertmp == NULL) {
report("using temp dir . for cross-compilation\n");
logprintf(logdepth, "staying with . for cross-compilation\n");
}
else {
put("sys/tmp", usertmp);
report("using user supplied temp dir '%s' for cross-compilation\n", usertmp);
logprintf(logdepth, "using user supplied temp dir '%s' for cross-compilation\n", usertmp);
logprintf(logdepth, "Path sep: '%s'\n", get("sys/path_sep"));
}
return 0;
}
if ((usertmp != NULL))
put("sys/tmp", usertmp);
if (
((usertmp != NULL) && (try_tmp_all(logdepth+2))) || /* try user supplied temp dir */
((try_get_cwd(logdepth+1, "pwd")) && (try_tmp_all(logdepth+2))) || /* try pwd for finding out cwd */
((try_get_cwd(logdepth+1, "echo %cd%") && (try_tmp_all(logdepth+2))))) { /* try windows-specific way for finding out cwd */
report(" validated %s\n", get("sys/tmp"));
logprintf(logdepth, "Detected temp dir '%s'\n", get("sys/tmp"));
logprintf(logdepth, "Path sep: '%s'\n", get("sys/path_sep"));
return 0;
}
put("sys/tmp", "");
report("using temp dir fallback .\n");
logprintf(logdepth, "all temp directories failed, using . as tmp\n");
logprintf(logdepth, "Path sep: '%s'\n", get("sys/path_sep"));
return 0;
}
int test_shell(const char *shell, int logdepth, int quote)
{
char *test = "echo hello";
char *cmd;
char *out;
char *q;
if (quote)
q = "\"";
else
q = "";
logprintf(logdepth, "testing '%s' as shell\n", shell);
cmd = malloc(strlen(test) + strlen(shell) + 8);
sprintf(cmd, "%s %s%s%s", shell, q, test, q);
run(logdepth+1, cmd, &out);
free(cmd);
if ((out != NULL) && (strncmp(out, "hello", 5) == 0)) {
put("sys/shell", shell);
if (quote)
put("sys/shell_needs_quote", strue);
else
put("sys/shell_needs_quote", sfalse);
logprintf(logdepth, "accepted.\n");
free(out);
return 1;
}
logprintf(logdepth, "refused.\n");
free(out);
return 0;
}
static int find_shell_escape(const char *name, int logdepth, int fatal, const char *shell)
{
char cmdline[256];
char **t;
char *tests[] = {
"\\", "\\ {}&;|",
"^", "^ &",
NULL, NULL
};
(void) fatal; /* not used */
(void) shell; /* not used */
report("Looking for a shell escape character... ");
logprintf(logdepth, "finding shell escape character...\n");
for(t = tests; *t != NULL; t += 2) {
char *s, *end, *out, *start;
strcpy(cmdline, "echo ");
end = cmdline+5;
for(s = t[1]; *s != '\0'; s++) {
*end++ = *t[0];
*end++ = *s;
}
*end = '\0';
run(logdepth+1, cmdline, &out);
if (out != NULL) {
int res;
if (*out == '\"') /* wine likes to wrap the output in quotes for some reason */
start = out+1;
else
start = out;
res = strncmp(start, t[1], strlen(t[1]));
free(out);
if (res == 0) {
report("found: '%s'\n", t[0]);
logprintf(logdepth, "found shell escape char '%s'\n", t[0]);
put("sys/shell_escape_char", t[0]);
return 0;
}
}
}
report("NOT FOUND\n");
logprintf(logdepth, "shell escape character not found\n");
return 1;
}
int find_shell(const char *name, int logdepth, int fatal)
{
const char *shells[] = {
"/bin/sh -c",
"/bin/bash -c",
"bash -c",
"cmd.exe /c",
"sh -c",
"/bin/dash -c",
"dash -c",
"/bin/ksh -c",
"ksh -c",
NULL
};
const char **s;
if (cross_blind) {
const char *shell = get("/arg/sys/target-shell");
if (shell == NULL) {
report("Need to specify sys/target-shell in blind cross compiling mode, because the shell cannot be detected (note: scconfig will not attempt to run the target shell)\n");
exit(1);
}
put("sys/shell", shell);
report("Blind cross compiling: accepting '%s' as shell\n", shell);
logprintf(logdepth, "Blind cross compiling: accepting '%s' as shell\n", shell);
return 0;
}
report("Looking for a shell... ");
logprintf(logdepth, "finding a shell\n");
for(s = shells; *s != NULL; s++) {
if ((test_shell(*s, logdepth+1, 0)) || (test_shell(*s, logdepth+1, 1))) {
report("%s\n", *s);
logprintf(logdepth, "found a shell '%s', need quote: %s\n", *s, get("sys/shell_needs_quote"));
return find_shell_escape(name, logdepth, fatal, *s);
}
}
report("NOT FOUND\n");
logprintf(logdepth, "shell not found\n");
return 1;
}

View File

@ -1,240 +0,0 @@
/*
scconfig - library to query files and directories
Copyright (C) 2009..2012 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include "db.h"
#include "libs.h"
#include "log.h"
#include "dep.h"
int file_size(const char *name)
{
struct stat buf;
if (stat(name, &buf) != 0)
return -1;
return buf.st_size;
}
char *tempdir_new(int logdepth, const char *suffix)
{
char s[1024];
char *cmd;
const char *tmp;
const char *mkdir, *emu;
unsigned int rn, n;
require("sys/tmp", logdepth+1, 1);
tmp = get("sys/tmp");
if (strlen(suffix) > sizeof(s) - strlen(tmp) - 32) {
fprintf(stderr, "Not enough room for creating temporary file name\n");
abort();
}
require("fstools/mkdir", logdepth+1, 1);
mkdir = get("fstools/mkdir");
emu = get("sys/emu");
if (emu == NULL)
emu = "";
for(n = 0; n < 128; n++) {
rn = rand() % 100000;
sprintf(s, "%sscc_%u%s", tmp, rn, suffix);
if (!exists(s)) {
char *s_esc = shell_escape_dup(s);
cmd = malloc(strlen(s_esc) + strlen(mkdir) + 16);
sprintf(cmd, "%s %s", mkdir, s_esc);
run_shell(logdepth+1, cmd, NULL);
free(s_esc);
free(cmd);
if (is_dir(s))
return strclone(s);
}
}
error("Couldn't find a suitable temp dir name\n");
abort();
}
char *tempfile_new_noabort(const char *suffix)
{
char s[1024];
const char *tmp;
unsigned int rn, n;
FILE *f;
require("/host/sys/tmp", 0, 1);
tmp = get("/host/sys/tmp");
if (strlen(suffix) > sizeof(s) - strlen(tmp) - 32) {
fprintf(stderr, "tempfile_new_noabort(): not enough room for creating temporary file name\n");
abort();
}
for(n = 0; n < 128; n++) {
rn = rand() % 100000;
sprintf(s, "%sscc_%u%s", tmp, rn, suffix);
if (!is_file(s)) { /* can not test for exists() because that would recurse is_dir */
f = fopen(s, "w");
if (f != NULL) {
fclose(f);
return strclone(s);
}
}
}
return NULL;
}
char *tempfile_new(const char *suffix)
{
char *tmp;
tmp = tempfile_new_noabort(suffix);
if (tmp == NULL) {
error("Couldn't find a suitable temp file name\n");
abort();
}
return tmp;
}
char *tempfile_dump(const char *testcode, const char *suffix)
{
char *fn;
FILE *f;
fn = tempfile_new(suffix);
f = fopen(fn, "w");
fprintf(f, "%s", testcode);
fclose(f);
return fn;
}
char *load_file(const char *name)
{
int size;
char *content;
FILE *f;
size = file_size(name);
if (size > 0) {
content = malloc(size+1);
*content = '\0';
f = fopen(name, "r");
if (f != NULL) {
int len = fread(content, 1, size, f);
if (len < 0)
len = 0;
content[len] = '\0';
fclose(f);
}
}
else {
content = malloc(1);
*content = '\0';
}
return content;
}
int is_dir(const char *path)
{
char *tmp, *path_esc;
int ret;
require("sys/shell", 0, 1);
path_esc = shell_escape_dup(path);
tmp = malloc(strlen(path_esc) + 16);
sprintf(tmp, "cd %s", path_esc);
ret = run_shell(0, tmp, NULL);
free(tmp);
free(path_esc);
return !ret;
}
int is_file(const char *path)
{
return file_size(path) >= 0;
}
int exists(const char *path)
{
return is_file(path) || is_dir(path);
}
int exists_in(const char *dir, const char *file)
{
char *path;
int ret;
path = malloc(strlen(dir) + strlen(file) + 5);
sprintf(path, "%s/%s", dir, file);
ret = is_file(path) || is_dir(path);
free(path);
return ret;
}
const char *file_name_ptr(const char *path)
{
const char *s;
s = str_rchr((char *)path, '/');
if (s == NULL)
s = str_rchr((char *)path, '\\');
return s;
}
char *file_name(const char *path)
{
const char *s;
s = file_name_ptr(path);
if (s == NULL)
return strclone(path);
s++;
return strclone(s);
}
char *dir_name(const char *path)
{
char *s, *r;
s = strclone(path);
r = (char *)file_name_ptr(s);
if (r == NULL) {
free(s);
return strclone("");
}
*r = '\0';
return s;
}
int touch_file(const char *path)
{
FILE *f;
f = fopen(path, "a");
if (f == NULL)
return -1;
fclose(f);
return 0;
}

View File

@ -1,257 +0,0 @@
/*
scconfig - hash tables
Copyright (C) 2007, 2008, 2009 by Szabolcs Nagy
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <assert.h>
#include "libs.h"
#include "ht.h"
#define HT_MINSIZE 8
#define HT_MAXSIZE ((UINT_MAX >> 1U) + 1U)
#define JUMP(i, j) i += j++
#define JUMP_FIRST(i, j) j = 1, i += j++
/* portable str hash */
#define HASH_INIT 0xbabeface
static unsigned int keyhash(const char *key) {
unsigned int a = HASH_INIT;
while (*key)
a += (a << 5) + *key++;
return a;
}
/* fill threshold = 3/4 */
#define HT_LOG_THRES 2
static void checkfill(ht_t *ht)
{
if (ht->fill > ht->mask - (ht->mask >> HT_LOG_THRES) || ht->fill > ht->used << 2)
ht_resize(ht, ht->used << (ht->used > 1U << 15 ? 1 : 2));
}
static ht_t *ht_init(ht_t *ht, int isstr)
{
ht->mask = HT_MINSIZE - 1;
ht->fill = 0;
ht->used = 0;
ht->isstr = isstr;
ht->table = calloc(ht->mask + 1, sizeof(ht_entry_t));
ht->refcount = 1;
return ht;
}
static ht_t *ht_uninit(ht_t *ht)
{
ht_entry_t *entry;
for (entry = ht->table; entry != ht->table + ht->mask + 1; entry++)
if (ht_isused(entry)) {
if (ht->isstr)
free(entry->value);
free(entry->key);
}
free(ht->table);
return ht;
}
ht_t *ht_alloc(int isstr)
{
ht_t *ht;
ht = malloc(sizeof(ht_t));
return ht_init(ht, isstr);
}
void ht_free(ht_t *ht)
{
ht_uninit(ht);
free(ht);
}
ht_t *ht_clear(ht_t *ht)
{
ht_uninit(ht);
return ht_init(ht, ht->isstr);
}
/* one lookup function to rule them all */
static ht_entry_t *ht_lookup(ht_t *ht, const char *key, unsigned int hash)
{
unsigned int mask;
unsigned int i;
unsigned int j;
ht_entry_t *table;
ht_entry_t *entry;
ht_entry_t *free_entry;
mask = ht->mask;
i = hash;
table = ht->table;
assert(ht->table);
entry = table + (i & mask);
if (ht_isempty(entry) || !strcmp(entry->key, key))
return entry;
/* free_entry: first deleted entry for insert */
free_entry = ht_isdeleted(entry) ? entry : NULL;
assert(ht->fill <= ht->mask);
for (JUMP_FIRST(i, j); ; JUMP(i, j)) {
entry = table + (i & mask);
if (ht_isempty(entry))
return (free_entry == NULL) ? entry : free_entry;
if (entry->hash == hash && !strcmp(entry->key, key))
return entry;
if (ht_isdeleted(entry) && free_entry == NULL)
free_entry = entry;
}
}
/* for resize: no deleted entries in ht, entry->key is not in ht, no strdup */
static void cleaninsert(ht_t *ht, const ht_entry_t *entry)
{
unsigned int i;
unsigned int j;
ht_entry_t *newentry;
i = entry->hash;
newentry = ht->table + (i & ht->mask);
if (!ht_isempty(newentry))
for (JUMP_FIRST(i, j); !ht_isempty(newentry); JUMP(i, j))
newentry = ht->table + (i & ht->mask);
++ht->fill;
++ht->used;
memcpy(newentry, entry, sizeof(ht_entry_t));
}
ht_t *ht_resize(ht_t *ht, unsigned int hint)
{
unsigned int newsize;
unsigned int oldused;
ht_entry_t *oldtable, *newtable, *entry;
oldused = ht->used;
if (hint < oldused << 1)
hint = oldused << 1;
assert(hint <= HT_MAXSIZE && hint > oldused);
for (newsize = HT_MINSIZE; newsize < hint; newsize <<= 1);
newtable = calloc(newsize, sizeof(ht_entry_t));
oldtable = ht->table;
ht->mask = newsize - 1;
ht->fill = 0;
ht->used = 0;
ht->table = newtable;
for (entry = oldtable; oldused > 0; ++entry)
if (ht_isused(entry)) {
--oldused;
cleaninsert(ht, entry);
}
free(oldtable);
return ht;
}
void *ht_get(ht_t *ht, const char *key)
{
ht_entry_t *entry;
entry = ht_lookup(ht, key, keyhash(key));
return ht_isused(entry) ? entry->value : NULL;
}
void *ht_insert(ht_t *ht, const char *key, void *value)
{
unsigned int hash;
ht_entry_t *entry;
hash = keyhash(key);
entry = ht_lookup(ht, key, hash);
if (ht_isused(entry))
return entry->value;
if (ht_isempty(entry))
++ht->fill;
++ht->used;
entry->hash = hash;
entry->key = strclone(key);
entry->value = ht->isstr ? strclone(value) : value;
checkfill(ht);
return NULL;
}
const char *ht_set(ht_t *ht, const char *key, void *value)
{
unsigned int hash;
ht_entry_t *entry;
char *k;
hash = keyhash(key);
entry = ht_lookup(ht, key, hash);
if (ht_isused(entry)) {
if (ht->isstr) {
free(entry->value);
entry->value = strclone(value);
} else
entry->value = value;
return entry->key;
}
if (ht_isempty(entry))
++ht->fill;
++ht->used;
entry->hash = hash;
entry->key = k = strclone(key);
entry->value = ht->isstr ? strclone(value) : value;
checkfill(ht);
return k;
}
const char *ht_del(ht_t *ht, const char *key)
{
ht_entry_t *entry;
entry = ht_lookup(ht, key, keyhash(key));
if (!ht_isused(entry))
return NULL;
--ht->used;
free(entry->key);
if (ht->isstr)
free(entry->value);
entry->key = ht_deleted_key;
return ht_deleted_key;
}
ht_entry_t *ht_first(const ht_t *ht)
{
ht_entry_t *entry = 0;
if (ht->used)
for (entry = ht->table; !ht_isused(entry); ++entry);
return entry;
}
ht_entry_t *ht_next(const ht_t *ht, ht_entry_t *entry)
{
while (++entry != ht->table + ht->mask + 1)
if (ht_isused(entry))
return entry;
return 0;
}

View File

@ -1,404 +0,0 @@
/*
scconfig - detection of types and type sizes
Copyright (C) 2012 Tibor Palinkas
Copyright (C) 2017-2018 Aron Barath
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
/* assume there is no integer that is at least this wide, in bytes */
#define MAX_INT_WIDTH 9
/* ('long double' can be 16 bytes; see https://en.wikipedia.org/wiki/Long_double) */
#define MAX_FLT_WIDTH 17
static int try_size(int logdepth, char *cflags, char *ldflags, const char *type, int use_stdint, const char *path, const char **sizearr, unsigned char *inc_stdint, const int max_width)
{
char *out = NULL;
const char *test_c_template =
NL "#include <stdio.h>"
NL "int main() {"
NL " printf(\"OK %%d\\n\", sizeof(%s));"
NL " return 0;"
NL "}"
NL;
char test_c[512], *start;
const char *inc = "#include <stdint.h>\n";
int size;
if (use_stdint) {
strcpy(test_c, inc);
start = test_c + strlen(inc);
}
else
start = test_c;
sprintf(start, test_c_template, type);
report("Testing size of type %25s... ", type);
logprintf(logdepth, "trying size with ldflags '%s'\n", ldflags == NULL ? get("cc/ldflags") : ldflags);
if (compile_run(logdepth+1, test_c, NULL, cflags, ldflags, &out) == 0) {
if (target_emu_fail(out)) {
report(" FAIL (emulator)\n");
free(out);
return -1;
}
if (strncmp(out, "OK", 2) == 0) {
size = atoi(out+3);
if ((size > 0) && (size < max_width)) {
sprintf(test_c, "%d", size);
put(path, test_c);
sizearr[size] = type;
if (inc_stdint != NULL)
inc_stdint[size] = use_stdint;
report(" OK, size %d byte%s\n", size, (size > 1) ? "s" : "");
}
else {
report(" FAIL, size %d bytes\n", size);
size = -1;
}
free(out);
return size;
}
free(out);
}
report(" FAIL (compile)\n");
return -1;
}
int find_types_stdint(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <stdint.h>"
NL "int main() {"
NL " if (sizeof(uint8_t) == 1)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for stdint.h... ");
logprintf(logdepth, "find_types_stdint: trying to find stdint.h...\n");
logdepth++;
if (try_icl(logdepth, "libs/types/stdint", test_c, NULL, NULL, NULL))
return 0;
return try_fail(logdepth, "libs/types/stdint");
}
int find_types_sizes(const char *name, int logdepth, int fatal)
{
const char *stdint;
const char *sizearr_u[MAX_INT_WIDTH];
const char *sizearr_s[MAX_INT_WIDTH];
const char *sizearr_f[MAX_FLT_WIDTH];
unsigned char inc_stdint_u[MAX_INT_WIDTH];
unsigned char inc_stdint_s[MAX_INT_WIDTH];
int n;
const char *includes = "";
const char *path_template = "sys/types/size/%d_%c_int";
const char *path_template_f = "sys/types/size/%d_float";
char path[64];
require("cc/cc", logdepth, fatal);
require("libs/types/stdint/presents", logdepth, 0);
stdint = get("libs/types/stdint/presents");
for(n = 0; n < MAX_INT_WIDTH; n++) {
sizearr_u[n] = NULL;
sizearr_s[n] = NULL;
inc_stdint_u[n] = 0;
inc_stdint_s[n] = 0;
}
for(n = 0; n < MAX_FLT_WIDTH; n++)
sizearr_f[n] = NULL;
try_size(logdepth+1, NULL, NULL, "unsigned long long int", 0, "sys/types/size/unsigned_long_long_int", sizearr_u, NULL, MAX_INT_WIDTH);
try_size(logdepth+1, NULL, NULL, "unsigned char", 0, "sys/types/size/unsigned_char", sizearr_u, NULL, MAX_INT_WIDTH);
try_size(logdepth+1, NULL, NULL, "unsigned short int", 0, "sys/types/size/unsigned_short_int", sizearr_u, NULL, MAX_INT_WIDTH);
try_size(logdepth+1, NULL, NULL, "unsigned int", 0, "sys/types/size/unsigned_int", sizearr_u, NULL, MAX_INT_WIDTH);
try_size(logdepth+1, NULL, NULL, "unsigned long int", 0, "sys/types/size/unsigned_long_int", sizearr_u, NULL, MAX_INT_WIDTH);
try_size(logdepth+1, NULL, NULL, "signed long long int", 0, "sys/types/size/signed_long_long_int", sizearr_s, NULL, MAX_INT_WIDTH);
try_size(logdepth+1, NULL, NULL, "signed char", 0, "sys/types/size/signed_char", sizearr_s, NULL, MAX_INT_WIDTH);
try_size(logdepth+1, NULL, NULL, "signed short int", 0, "sys/types/size/signed_short_int", sizearr_s, NULL, MAX_INT_WIDTH);
try_size(logdepth+1, NULL, NULL, "signed int", 0, "sys/types/size/signed_int", sizearr_s, NULL, MAX_INT_WIDTH);
try_size(logdepth+1, NULL, NULL, "signed long int", 0, "sys/types/size/signed_long_int", sizearr_s, NULL, MAX_INT_WIDTH);
if ((stdint != NULL) && (istrue(stdint))) {
try_size(logdepth+1, NULL, NULL, "uint8_t", 1, "sys/types/size/uint8_t", sizearr_u, inc_stdint_u, MAX_INT_WIDTH);
try_size(logdepth+1, NULL, NULL, "uint16_t", 1, "sys/types/size/uint16_t", sizearr_u, inc_stdint_u, MAX_INT_WIDTH);
try_size(logdepth+1, NULL, NULL, "uint32_t", 1, "sys/types/size/uint32_t", sizearr_u, inc_stdint_u, MAX_INT_WIDTH);
try_size(logdepth+1, NULL, NULL, "uint64_t", 1, "sys/types/size/uint64_t", sizearr_u, inc_stdint_u, MAX_INT_WIDTH);
try_size(logdepth+1, NULL, NULL, "int8_t", 1, "sys/types/size/int8_t", sizearr_s, inc_stdint_s, MAX_INT_WIDTH);
try_size(logdepth+1, NULL, NULL, "int16_t", 1, "sys/types/size/int16_t", sizearr_s, inc_stdint_s, MAX_INT_WIDTH);
try_size(logdepth+1, NULL, NULL, "int32_t", 1, "sys/types/size/int32_t", sizearr_s, inc_stdint_s, MAX_INT_WIDTH);
try_size(logdepth+1, NULL, NULL, "int64_t", 1, "sys/types/size/int64_t", sizearr_s, inc_stdint_s, MAX_INT_WIDTH);
}
try_size(logdepth+1, NULL, NULL, "float", 0, "sys/types/size/float", sizearr_f, NULL, MAX_FLT_WIDTH);
try_size(logdepth+1, NULL, NULL, "double", 0, "sys/types/size/double", sizearr_f, NULL, MAX_FLT_WIDTH);
try_size(logdepth+1, NULL, NULL, "long double", 0, "sys/types/size/long_double", sizearr_f, NULL, MAX_FLT_WIDTH);
for(n = 0; n < MAX_INT_WIDTH; n++) {
if (sizearr_u[n] != NULL) {
report("Found best fit %d bytes wide uint: %s\n", n, sizearr_u[n]);
sprintf(path, path_template, n, 'u');
put(path, sizearr_u[n]);
if (inc_stdint_u[n])
includes = "#include <stdint.h>";
}
if (sizearr_s[n] != NULL) {
report("Found best fit %d bytes wide sint: %s\n", n, sizearr_s[n]);
sprintf(path, path_template, n, 's');
put(path, sizearr_s[n]);
if (inc_stdint_s[n])
includes = "#include <stdint.h>";
}
}
for(n = 0; n < MAX_FLT_WIDTH; n++) {
if (sizearr_f[n] != NULL) {
report("Found best fit %d bytes wide float: %s\n", n, sizearr_f[n]);
sprintf(path, path_template_f, n);
put(path, sizearr_f[n]);
}
}
put("sys/types/size/presents", strue); /* to avoid redetection */
put("sys/types/size/includes", includes);
return 0;
}
int find_types_something_t(const char *name, int logdepth, int fatal, const char *prefix, const char *typ, const char *define, const char *try_include)
{
char *out = NULL;
int res;
char test_c[512];
char node[256], *nodeend;
const char **include, *includes[] = {"", "#include <stddef.h>", "#include <sys/types.h>", "#include <sys/types/types.h>", "#include <stdlib.h>", "#include <unistd.h>", "#include <stdio.h>", NULL};
const char ** const first_include = (try_include && *try_include) ? includes : (includes+1);
char *test_c_include =
NL "%s"
NL "int my_puts(const char *s);"
NL "%s"
NL "int main() {"
NL " %s s;"
NL " my_puts(\"OK\");"
NL " return 0;"
NL "}"
NL "#include <stdio.h>"
NL "int my_puts(const char *s)"
NL "{"
NL " return puts(s);"
NL "}"
NL;
char *test_c_size =
NL "%s"
NL "#include <stdio.h>"
NL "%s"
NL "int main() {"
NL " printf(\"%%d\", sizeof(%s));"
NL " return 0;"
NL "}"
NL;
char *test_c_broken =
NL "%s"
NL "int my_puts(const char *s);"
NL "%s"
NL "int main() {"
NL " %s s;"
NL " void *v;"
NL " if (sizeof(v) != sizeof(s)) my_puts(\"yes\");"
NL " else my_puts(\"no\");"
NL " return 0;"
NL "}"
NL "#include <stdio.h>"
NL "int my_puts(const char *s)"
NL "{"
NL " return puts(s);"
NL "}"
NL;
includes[0] = try_include;
require("cc/cc", logdepth, fatal);
report("Checking for type %s... ", typ);
logprintf(logdepth, "find_types_something_t: Checking for %s...\n", typ);
logdepth++;
sprintf(node, "%s/%s", prefix, typ);
nodeend = node + strlen(node);
/* replace '*' at the end of the node path with _ptr so it can be saved in the tree */
if (nodeend[-1] == '*') {
nodeend--;
while((nodeend > node) && (*nodeend == ' ')) nodeend--;
strcpy(nodeend-1, "_ptr");
nodeend+=4;
}
nodeend[0] = '/';
nodeend[1] = '\0';
nodeend++;
if (define == NULL)
define = "";
for(include = first_include; *include != NULL; include++) {
sprintf(test_c, test_c_include, define, *include, typ);
if ((compile_run(logdepth, test_c, NULL, NULL, NULL, &out) == 0) && (strncmp(out, "OK", 2) == 0)) {
report("Found; ");
logprintf(logdepth+1, "include %s works\n", *include);
sprintf(nodeend, "includes");
if (define) {
put(node, define);
append(node, "\\n");
append(node, *include);
} else
put(node, *include);
break;
}
logprintf(logdepth+1, "include %s fails\n", *include);
if (out != NULL)
free(out);
}
if (*include == NULL) {
report("Not found\n");
return 1;
}
sprintf(nodeend, "presents");
put(node, strue);
/* check if typ is broken (smaller than void *) */
sprintf(test_c, test_c_broken, define, *include, typ);
if (compile_run(logdepth, test_c, NULL, NULL, NULL, &out) == 0) {
if ((out != NULL) && (strncmp(out, "yes", 3) == 0)) {
report("(%s is narrower than void *)\n", typ);
sprintf(nodeend, "broken");
put(node, strue);
res = 0;
}
else if ((out != NULL) && (strncmp(out, "no", 2) == 0)) {
report("(%s is not narrower than void *)\n", typ);
sprintf(nodeend, "broken");
put(node, sfalse);
res = 0;
}
else {
report("ERROR: test failed (%s)\n", out);
res = 1;
}
}
if (out != NULL)
free(out);
if (res == 0) {
report("Checking for size of %s... ", typ);
sprintf(test_c, test_c_size, define, *include, typ);
if (compile_run(logdepth, test_c, NULL, NULL, NULL, &out) == 0) {
if (out != NULL) {
report("(sizeof %s is %s)\n", typ, out);
sprintf(nodeend, "size");
put(node, out);
}
}
if (out != NULL)
free(out);
}
return res;
}
int find_types_size_t(const char *name, int logdepth, int fatal)
{
return find_types_something_t(name, logdepth, fatal, "sys/types", "size_t", NULL, NULL);
}
int find_types_off_t(const char *name, int logdepth, int fatal)
{
return find_types_something_t(name, logdepth, fatal, "sys/types", "off_t", NULL, NULL);
}
int find_types_off64_t(const char *name, int logdepth, int fatal)
{
return find_types_something_t(name, logdepth, fatal, "sys/types", "off64_t", NULL, NULL) &&
find_types_something_t(name, logdepth, fatal, "sys/types", "off64_t", "#define _LARGEFILE64_SOURCE", NULL);
}
int find_types_gid_t(const char *name, int logdepth, int fatal)
{
return find_types_something_t(name, logdepth, fatal, "sys/types", "gid_t", NULL, NULL);
}
int find_types_uid_t(const char *name, int logdepth, int fatal)
{
return find_types_something_t(name, logdepth, fatal, "sys/types", "uid_t", NULL, NULL);
}
int find_types_pid_t(const char *name, int logdepth, int fatal)
{
return find_types_something_t(name, logdepth, fatal, "sys/types", "pid_t", NULL, NULL);
}
int find_types_mode_t(const char *name, int logdepth, int fatal)
{
return find_types_something_t(name, logdepth, fatal, "sys/types", "mode_t", NULL, NULL);
}
int find_types_nlink_t(const char *name, int logdepth, int fatal)
{
return find_types_something_t(name, logdepth, fatal, "sys/types", "nlink_t", NULL, NULL);
}
int find_types_ptrdiff_t(const char *name, int logdepth, int fatal)
{
return find_types_something_t(name, logdepth, fatal, "sys/types", "ptrdiff_t", NULL, NULL);
}
int find_types_dev_t(const char *name, int logdepth, int fatal)
{
return find_types_something_t(name, logdepth, fatal, "sys/types", "dev_t", NULL, NULL);
}
int find_types_ino_t(const char *name, int logdepth, int fatal)
{
return find_types_something_t(name, logdepth, fatal, "sys/types", "ino_t", NULL, NULL);
}
int find_types_void_ptr(const char *name, int logdepth, int fatal)
{
return find_types_something_t(name, logdepth, fatal, "sys/types", "void *", NULL, NULL);
}

View File

@ -1,188 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include "log.h"
#include "libs.h"
#include "db.h"
#include "dep.h"
#include "regex.h"
static void zap(char **str)
{
const char *pat = get("/arg/sys/pkg-config-zap");
char *n;
if (pat == NULL)
return;
if (re_comp(pat) != NULL)
return;
while (re_exec(*str)) {
n = re_subs_dup("");
free(*str);
*str = n;
}
}
int run_gen_config(int logdepth, const char *confname, const char *pkgname, char **cflags, char **ldflags)
{
char cmd[256];
assert(strlen(pkgname) < sizeof(cmd) - 64);
if (cflags != NULL) {
sprintf(cmd, "%s --cflags %s", confname, pkgname);
if (run(logdepth, cmd, cflags) != 0) {
report("not found: %s --cflags failed.", confname);
logprintf(logdepth, "not found: %s --cflags failed.\n", confname);
return -1;
}
if (*cflags != NULL) {
zap(cflags);
strip(*cflags);
}
}
if (ldflags != NULL) {
sprintf(cmd, "%s --libs %s", confname, pkgname);
if (run(logdepth, cmd, ldflags) != 0) {
report("not found: %s --libs failed.", confname);
logprintf(logdepth, "not found: %s --libs failed.\n", confname);
if (cflags != NULL)
free(*cflags);
return -1;
}
if (*ldflags != NULL) {
zap(ldflags);
strip(*ldflags);
}
}
return 0;
}
const char *pkg_config_name()
{
const char *name;
name = get("/arg/sys/pkg-config");
if (name != NULL)
return name;
return "pkg-config"; /* fallback */
}
/** run_pkg_config_modversion:
run `pkg-config` on @pkgname:
- with `--modversion` if @modversion is not NULL, storing the result in @modversion (malloc()'d)
Returns 0 on success.
*/
int run_pkg_config_modversion(int logdepth, const char *pkgname, char **modversion)
{
char cmd[256];
const char *confname = pkg_config_name();
assert(strlen(pkgname) < sizeof(cmd) - 64);
if (modversion != NULL) {
sprintf(cmd, "%s --modversion %s", confname, pkgname);
if (run(logdepth, cmd, modversion) != 0) {
/*report("Module version not found: %s --modversion %s failed.", confname, pkgname);
logprintf(logdepth, "Module version not found: %s --modversion %s failed.\n", confname, pkgname); */
return -1;
}
zap(modversion);
strip(*modversion);
}
return 0;
}
/** run_pkg_config_modversion_db:
run `pkg-config --modversion` on @pkgname to find module (or package) version
and store the result in @node/modversion
Returns 0 on success.
*/
int run_pkg_config_modversion_db(int logdepth, const char *node, const char *pkgname /*, char **modversion */ )
{
char *modversion;
char *tmp;
if (run_pkg_config_modversion(logdepth, pkgname, &modversion) != 0) {
return -1;
}
/* Store the module version in node */
tmp = str_concat("/", node, "modversion", NULL);
put(tmp, modversion);
free(tmp);
free(modversion);
return 0;
}
int run_pkg_config(int logdepth, const char *pkgname, char **cflags, char **ldflags)
{
return run_gen_config(logdepth, pkg_config_name(), pkgname, cflags, ldflags);
}
void run_pkg_config_lst(int logdepth, const char *pkgpat, int *argc, char ***argv)
{
char *end, *s, *next;
int n = 0, a = 0;
char **sf = NULL;
static const char *pkg_cfg_cache = NULL;
static char no_pkg_cfg;
char *list;
if (pkg_cfg_cache == &no_pkg_cfg)
goto error;
if (pkg_cfg_cache == NULL) {
char *cmd = str_concat(" ", pkg_config_name(), "--list-all", NULL);
run(logdepth, cmd, (char **) &pkg_cfg_cache);
free(cmd);
if (pkg_cfg_cache == NULL) {
pkg_cfg_cache = &no_pkg_cfg;
goto error;
}
}
if (re_comp(pkgpat) != NULL)
goto error;
s = list = strclone(pkg_cfg_cache);
for (;;) {
while (isspace(*s))
s++;
if (*s == '\0')
break;
next = strpbrk(s, "\r\n");
if (next != NULL)
*next = '\0';
if (re_exec(s)) {
if ((n + 2) >= a) { /* n+2: make sure there's always room for the NULL at the end */
a += 16;
sf = realloc(sf, sizeof(char *) * a);
}
end = strpbrk(s, " \t");
if (end != NULL)
*end = '\0';
sf[n] = strclone(s);
sf[n + 1] = re_subs_dup("");
/* report("\ns='%s' sf='%s'\n", s, sf[n]);*/
n += 2;
}
s = next + 1;
}
if (sf != NULL)
sf[n] = NULL;
free(list);
error:;
*argc = n;
*argv = sf;
return;
}

View File

@ -1,835 +0,0 @@
/*
scconfig - detection of file system tools
Copyright (C) 2009..2012 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
#include "dep.h"
static int test_cp_ln(int logdepth, const char *command, int link)
{
char *src, *dst, *src_esc, *dst_esc;
char *cmd, *result;
char *test_string = "works.";
int ret;
logprintf(logdepth, "trying '%s'\n", command);
src = tempfile_dump(test_string, "");
dst = tempfile_new("");
if (link)
unlink(dst);
src_esc = shell_escape_dup(src);
dst_esc = shell_escape_dup(dst);
cmd = malloc(strlen(command) + strlen(src_esc) + strlen(dst_esc) + 32);
sprintf(cmd, "%s %s %s", command, src_esc, dst_esc);
run_shell(logdepth, cmd, NULL);
free(cmd);
free(src_esc);
free(dst_esc);
result = load_file(dst);
ret = !strcmp(result, test_string);
logprintf(logdepth+1, "result: '%s' == '%s' (%d)\n", result, test_string, ret);
free(result);
unlink(src);
free(src);
result = load_file(dst);
if (link) {
if (strcmp(result, test_string) == 0) {
report("Warning: link is copy (or hard link). ");
logprintf(logdepth+1, "Warning: link is copy (or hard link).\n");
}
}
else {
if (strcmp(result, test_string) != 0) {
report("Warning: copy is symlink. ");
logprintf(logdepth+1, "Warning: copy is symlink.\n");
}
}
free(result);
if (ret) {
if (link)
put("fstools/ln", command);
else
put("fstools/cp", command);
report("OK (%s)\n", command);
}
unlink(dst);
free(dst);
return ret;
}
static int test_mv(int logdepth, const char *command)
{
char *src, *dst, *src_esc, *dst_esc;
char *cmd, *result;
char *test_string = "works.";
int ret;
logprintf(logdepth, "trying '%s'\n", command);
src = tempfile_dump(test_string, "");
dst = tempfile_new("");
unlink(dst);
src_esc = shell_escape_dup(src);
dst_esc = shell_escape_dup(dst);
cmd = malloc(strlen(command) + strlen(src_esc) + strlen(dst_esc) + 32);
sprintf(cmd, "%s %s %s", command, src_esc, dst_esc);
run_shell(logdepth, cmd, NULL);
free(cmd);
free(src_esc);
free(dst_esc);
result = load_file(dst);
ret = !strcmp(result, test_string);
logprintf(logdepth+1, "result: '%s' == '%s' (%d)\n", result, test_string, ret);
free(result);
if (file_size(src) > 0) {
report("Warning: mv is copy. ");
logprintf(logdepth+1, "Warning: mv is copy.\n");
}
if (ret) {
put("fstools/mv", command);
report("OK (%s)\n", command);
}
unlink(dst);
unlink(src);
free(dst);
free(src);
return ret;
}
static int test_mkdir(int logdepth, const char *command)
{
char *dir, *file;
char *dir_esc;
char *cmd, *result;
char *test_string = "works.";
int ret = 0, had_p;
FILE *f;
logprintf(logdepth, "trying '%s'\n", command);
dir = tempfile_new("");
dir_esc = shell_escape_dup(dir);
unlink(dir);
had_p = is_dir("-p");
cmd = malloc(strlen(command) + strlen(dir_esc) + 32);
sprintf(cmd, "%s %s", command, dir_esc);
run_shell(logdepth, cmd, NULL);
free(cmd);
file = malloc(strlen(dir) + 32);
sprintf(file, "%s/test", dir);
f = fopen(file, "w");
if (f != NULL) {
fputs(test_string, f);
fclose(f);
result = load_file(file);
if (strcmp(result, test_string) == 0)
ret = 1;
free(result);
}
unlink(file);
unlink(dir);
cmd = malloc(strlen(dir) + 32);
sprintf(cmd, "rmdir %s", dir_esc);
run_shell(logdepth, cmd, NULL);
free(cmd);
free(file);
free(dir);
free(dir_esc);
/* This is a bit ugly, but on win32 or other systems where mkdir works
but -p doesn't have an effect, a directory called -p may be left over... */
if ((!had_p) && (is_dir("-p"))) {
unlink("-p");
return 0;
}
if (ret != 0) {
put("fstools/mkdir", command);
report("OK (%s)\n", command);
}
return ret;
}
static int test_rm(int logdepth, const char *command)
{
char *src, *src_esc, *cmd, *test_string = "works.";
int ret;
logprintf(logdepth, "trying '%s'\n", command);
src = tempfile_dump(test_string, "");
if (file_size(src) < 0) {
report("error: can't create temp file\n");
free(src);
return 0;
}
src_esc = shell_escape_dup(src);
cmd = malloc(strlen(command) + strlen(src_esc) + 32);
sprintf(cmd, "%s %s", command, src_esc);
run_shell(logdepth, cmd, NULL);
free(cmd);
free(src_esc);
ret = file_size(src) < 0;
if (ret) {
put("fstools/rm", command);
report("OK (%s)\n", command);
}
else
unlink(src);
free(src);
return ret;
}
static int test_ar(int logdepth, const char *command)
{
char *src, *dst, *src_esc, *dst_esc;
char *cmd, *result, *expected;
char *test_string = "works.";
const char *path_sep;
int ret = 0;
logprintf(logdepth, "trying '%s'\n", command);
path_sep = get("sys/path_sep");
src = tempfile_dump(test_string, "");
dst = tempfile_new("");
unlink(dst);
src_esc = shell_escape_dup(src);
dst_esc = shell_escape_dup(dst);
cmd = malloc(strlen(command) + strlen(src_esc) + strlen(dst_esc) + 32);
sprintf(cmd, "%s ru %s %s", command, dst_esc, src_esc);
run_shell(logdepth, cmd, NULL);
sprintf(cmd, "%s t %s", command, dst_esc);
run_shell(logdepth, cmd, &result);
free(cmd);
free(dst_esc);
free(src_esc);
if (result != NULL) {
expected = str_rchr(src, *path_sep);
if (expected == NULL)
expected = src;
else
expected++;
logprintf(logdepth, "test_ar path_sep='%s' expected='%s' result='%s'\n", path_sep, expected, result);
ret = strncmp(expected, result, strlen(expected)) == 0;
if (ret) {
put("fstools/ar", command);
report("OK (%s)\n", command);
}
free(result);
}
unlink(src);
unlink(dst);
free(src);
free(dst);
return ret;
}
static int test_ranlib(int logdepth, const char *command, const char *obj)
{
char *cmd, *archive, *archive_esc, *obj_esc;
const char *ar;
int ret;
ar = get("fstools/ar");
logprintf(logdepth, "trying '%s'\n", command);
archive = tempfile_new(".a");
archive_esc = shell_escape_dup(archive);
obj_esc = shell_escape_dup(obj);
cmd = malloc(strlen(command) + strlen(obj_esc) + strlen(archive_esc) + 64);
sprintf(cmd, "%s r %s %s", ar, archive_esc, obj_esc);
unlink(archive);
ret = run_shell(logdepth, cmd, NULL) == 0;
if (!ret)
goto fin;
sprintf(cmd, "%s %s", command, archive_esc);
ret = run_shell(logdepth, cmd, NULL) == 0;
if (ret) {
put("fstools/ranlib", command);
report("OK (%s)\n", command);
}
fin:;
unlink(archive);
free(archive);
free(cmd);
free(archive_esc);
free(obj_esc);
return ret;
}
static int test_awk(int logdepth, const char *command)
{
char cmd[1024];
char *out;
int ret = 0;
char *script, *script_esc;
/* For some reason windows awk doesn't like the code with NLs */
char *test_awk =
"BEGIN {"
" gsub(\"b\", \"B\", t);"
" print t;"
"}";
logprintf(logdepth, "trying '%s'\n", command);
script = tempfile_dump(test_awk, ".awk");
script_esc = shell_escape_dup(script);
sprintf(cmd, "%s -v \"t=blobb\" -f %s", command, script_esc);
free(script_esc);
run_shell(logdepth, cmd, &out);
unlink(script);
free(script);
if ((out != NULL) && (strncmp(out, "BloBB", 5) == 0)) {
put("fstools/awk", command);
report("OK (%s)\n", command);
ret = 1;
}
free(out);
return ret;
}
static int test_cat(int logdepth, const char *command)
{
char cmd[1024];
char *out;
int ret = 0;
char *fn, *fn_esc;
const char *test_str = "hello world";
logprintf(logdepth, "trying '%s'\n", command);
fn = tempfile_dump(test_str, ".txt");
fn_esc = shell_escape_dup(fn);
sprintf(cmd, "%s %s", command, fn_esc);
run_shell(logdepth, cmd, &out);
unlink(fn);
free(fn);
free(fn_esc);
if ((out != NULL) && (strncmp(out, test_str, strlen(test_str)) == 0)) {
put("fstools/cat", command);
report("OK (%s)\n", command);
ret = 1;
}
free(out);
return ret;
}
static int test_sed(int logdepth, const char *command)
{
char cmd[1024];
char *out;
int ret = 0;
char *fn, *fn_esc;
const char *test_str_in = "hello world";
const char *test_str_out = "he11o wor1d";
logprintf(logdepth, "trying '%s'\n", command);
fn = tempfile_dump(test_str_in, ".txt");
fn_esc = shell_escape_dup(fn);
sprintf(cmd, "%s \"s/l/1/g\" < %s", command, fn_esc);
run_shell(logdepth, cmd, &out);
unlink(fn);
free(fn);
free(fn_esc);
if ((out != NULL) && (strncmp(out, test_str_out, strlen(test_str_out)) == 0)) {
put("fstools/sed", command);
report("OK (%s)\n", command);
ret = 1;
}
free(out);
return ret;
}
static int test_chmodx(int logdepth, const char *command)
{
char *cmd, *tmp, *tmp_esc, *out, *s;
int ret;
logprintf(logdepth, "trying '%s'\n", command);
tmp = tempfile_dump("#!/bin/sh\necho OK\n", ".bat");
tmp_esc = shell_escape_dup(tmp);
cmd = malloc(strlen(command) + strlen(tmp_esc) + 16);
sprintf(cmd, "%s %s", command, tmp_esc);
ret = run_shell(logdepth, cmd, NULL) == 0;
free(cmd);
if (!ret) {
free(tmp_esc);
return ret;
}
ret = run(logdepth+1, tmp_esc, &out);
free(tmp_esc);
if (ret == 0) {
for(s = out; s != NULL; s = str_chr(s, '\n')) {
logprintf(logdepth+1, "chmod line to test: '%s'\n", s);
if ((s[0] == 'O') && (s[1] == 'K')) {
logprintf(logdepth+2, "(OK)\n");
ret = 1;
break;
}
s++;
}
}
else
ret = 0;
free(out);
if (ret) {
put("fstools/chmodx", command);
logprintf(logdepth, "chmodx command validated: '%s'\n", command);
report("OK (%s)\n", command);
}
unlink(tmp);
return ret;
}
static int test_file(int logdepth, const char *node, const char *command)
{
char cmd[1024];
char *out;
int ret = 0;
char *fn, *fn_esc;
logprintf(logdepth, "trying '%s'\n", command);
fn = tempfile_dump("plain text file\r\n", ".txt");
fn_esc = shell_escape_dup(fn);
sprintf(cmd, "%s %s", command, fn_esc);
run_shell(logdepth, cmd, &out);
unlink(fn);
free(fn);
free(fn_esc);
if ((out != NULL) && (strstr(out, "text") != NULL)) {
put(node, command);
report("OK (%s)\n", command);
ret = 1;
}
free(out);
return ret;
}
int find_fstools_cp(const char *name, int logdepth, int fatal)
{
const char *cp;
(void) fatal; /* to suppress compiler warnings about not using fatal */
report("Checking for cp... ");
logprintf(logdepth, "find_fstools_cp: trying to find cp...\n");
logdepth++;
cp = get("/arg/fstools/cp");
if (cp == NULL) {
if (test_cp_ln(logdepth, "cp -rp", 0)) return 0;
if (test_cp_ln(logdepth, "cp -r", 0)) return 0;
if (test_cp_ln(logdepth, "copy /r", 0)) return 0; /* wine */
}
else {
report(" user provided (%s)...", cp);
if (test_cp_ln(logdepth, cp, 0)) return 0;
}
return 1;
}
int find_fstools_ln(const char *name, int logdepth, int fatal)
{
const char *ln;
(void) fatal; /* to suppress compiler warnings about not using fatal */
report("Checking for ln... ");
logprintf(logdepth, "find_fstools_ln: trying to find ln...\n");
logdepth++;
ln = get("/arg/fstools/ln");
if (ln == NULL) {
if (test_cp_ln(logdepth, "ln -sf",1 )) return 0;
if (test_cp_ln(logdepth, "ln -s",1 )) return 0;
if (test_cp_ln(logdepth, "ln", 1)) return 0;
/* "mklink /H" -> win32 equivalent to "ln" */
/* "cp -s" -> same as "ln -s" */
/* "cp -l" -> same as "ln" */
if (test_cp_ln(logdepth, "cp", 1)) return 0;
}
else {
report(" user provided (%s)...", ln);
if (test_cp_ln(logdepth, ln, 1)) return 0;
}
return 1;
}
int find_fstools_mv(const char *name, int logdepth, int fatal)
{
const char *mv;
(void) fatal; /* to suppress compiler warnings about not using fatal */
report("Checking for mv... ");
logprintf(logdepth, "find_fstools_mv: trying to find mv...\n");
logdepth++;
mv = get("/arg/fstools/mv");
if (mv == NULL) {
if (test_mv(logdepth, "mv")) return 0;
if (test_mv(logdepth, "move")) return 0; /* win32 */
if (test_mv(logdepth, "cp")) return 0;
}
else {
report(" user provided (%s)...", mv);
if (test_mv(logdepth, mv)) return 0;
}
return 1;
}
int find_fstools_rm(const char *name, int logdepth, int fatal)
{
const char *rm;
(void) fatal; /* to suppress compiler warnings about not using fatal */
report("Checking for rm... ");
logprintf(logdepth, "find_fstools_rm: trying to find rm...\n");
logdepth++;
rm = get("/arg/fstools/rm");
if (rm == NULL) {
if (test_rm(logdepth, "rm -rf")) return 0;
if (test_rm(logdepth, "rm -f")) return 0;
if (test_rm(logdepth, "rm")) return 0;
if (test_rm(logdepth, "del")) return 0; /* for win32 */
}
else {
report(" user provided (%s)...", rm);
if (test_rm(logdepth, rm)) return 0;
}
return 1;
}
int find_fstools_mkdir(const char *name, int logdepth, int fatal)
{
const char *mkdir;
(void) fatal; /* to suppress compiler warnings about not using fatal */
report("Checking for mkdir... ");
logprintf(logdepth, "find_fstools_mkdir: trying to find mkdir...\n");
logdepth++;
mkdir = get("/arg/fstools/mkdir");
if (mkdir == NULL) {
if (test_mkdir(logdepth, "mkdir -p")) return 0;
if (test_mkdir(logdepth, "md")) return 0; /* for win32 */
}
else {
report(" user provided (%s)...", mkdir);
if (test_mkdir(logdepth, mkdir)) return 0;
}
return 1;
}
int find_fstools_ar(const char *name, int logdepth, int fatal)
{
const char *ar, *target;
char *targetar;
int len;
(void) fatal; /* to suppress compiler warnings about not using fatal */
require("sys/path_sep", logdepth, fatal);
report("Checking for ar... ");
logprintf(logdepth, "find_fstools_ar: trying to find ar...\n");
logdepth++;
ar = get("/arg/fstools/ar");
if (ar == NULL) {
target = get("/arg/sys/target");
if (target != NULL) {
logprintf(logdepth+1, "find_ar: crosscompiling for '%s', looking for target ar\n", target);
len = strlen(target);
targetar = malloc(len + 8);
memcpy(targetar, target, len);
strcpy(targetar + len, "-ar");
if (test_ar(logdepth, targetar)) {
free(targetar);
return 0;
}
free(targetar);
}
if (test_ar(logdepth, "ar")) return 0;
if (test_ar(logdepth, "/usr/bin/ar")) return 0;
}
else {
report(" user provided (%s)...", ar);
if (test_ar(logdepth, ar)) return 0;
}
return 1;
}
int find_fstools_ranlib(const char *name, int logdepth, int fatal)
{
const char *ranlib, *target;
char *targetranlib;
int len;
char *test_code = NL "int zero() { return 0; }" NL;
char *obj = ".o";
(void) fatal; /* to suppress compiler warnings about not using fatal */
require("fstools/ar", logdepth, fatal);
require("cc/cc", logdepth, fatal);
report("Checking for ranlib... ");
logprintf(logdepth, "find_fstools_ranlib: trying to find ranlib...\n");
logdepth++;
logprintf(logdepth, "compiling test object...\n");
if (compile_code(logdepth+1, test_code, &obj, NULL, "-c", NULL) != 0) {
logprintf(logdepth, "ERROR: Can't compile test object\n");
report("ERROR: Can't compile test object\n");
abort();
}
ranlib = get("/arg/fstools/ranlib");
if (ranlib == NULL) {
target = get("/arg/sys/target");
if (target != NULL) {
logprintf(logdepth+1, "find_ranlib: crosscompiling for '%s', looking for target ranlib\n", target);
len = strlen(target);
targetranlib = malloc(len + 16);
memcpy(targetranlib, target, len);
strcpy(targetranlib + len, "-ranlib");
if (test_ranlib(logdepth, targetranlib, obj)) {
free(targetranlib);
return 0;
}
free(targetranlib);
}
if (test_ranlib(logdepth, "ranlib", obj)) goto found;
if (test_ranlib(logdepth, "/usr/bin/ranlib", obj)) goto found;
if (test_ranlib(logdepth, "ar -s", obj)) goto found;
if (test_ranlib(logdepth, "/usr/bin/ar -s", obj)) goto found;
/* some systems (for example IRIX) can't run s without doing
something else; t is harmless */
if (test_ranlib(logdepth, "ar ts", obj)) goto found;
if (test_ranlib(logdepth, "/usr/bin/ar ts", obj)) goto found;
/* final fallback: some systems (for example minix3) simply
do not have ranlib or ar equivalent; it's easier to detect
a dummy command than to force conditions into Makefiles */
if (test_ranlib(logdepth, "true", obj)) goto found;
}
else {
report(" user provided (%s)...", ranlib);
if (test_ranlib(logdepth, ranlib, obj)) goto found;
}
unlink(obj);
free(obj);
return 1;
found:;
unlink(obj);
free(obj);
return 0;
}
int find_fstools_awk(const char *name, int logdepth, int fatal)
{
const char *awk;
(void) fatal; /* to suppress compiler warnings about not using fatal */
report("Checking for awk... ");
logprintf(logdepth, "find_fstools_awk: trying to find awk...\n");
logdepth++;
awk = get("/arg/fstools/awk");
if (awk == NULL) {
if (test_awk(logdepth, "awk")) return 0;
if (test_awk(logdepth, "gawk")) return 0;
if (test_awk(logdepth, "mawk")) return 0;
if (test_awk(logdepth, "nawk")) return 0;
}
else {
report(" user provided (%s)...", awk);
if (test_awk(logdepth, awk)) return 0;
}
return 1;
}
int find_fstools_chmodx(const char *name, int logdepth, int fatal)
{
const char *chmod;
(void) fatal; /* to suppress compiler warnings about not using fatal */
report("Checking for chmod to executable... ");
logprintf(logdepth, "find_fstools_awk: trying to find chmod to executable...\n");
logdepth++;
chmod = get("/arg/fstools/chmodx");
if (chmod == NULL) {
if (test_chmodx(logdepth, "chmod +x")) return 0;
if (test_chmodx(logdepth, "chmod 755")) return 0;
if (test_chmodx(logdepth, "")) return 0; /* on some systems we don't need to do anything */
}
else {
report(" user provided (%s)...", chmod);
if (test_chmodx(logdepth, chmod)) return 0;
}
return 1;
}
int find_fstools_cat(const char *name, int logdepth, int fatal)
{
const char *cat;
(void) fatal; /* to suppress compiler warnings about not using fatal */
report("Checking for cat... ");
logprintf(logdepth, "find_fstools_cat: trying to find cat...\n");
logdepth++;
cat = get("/arg/fstools/cat");
if (cat == NULL) {
if (test_cat(logdepth, "cat")) return 0;
if (test_cat(logdepth, "type")) return 0;
}
else {
report(" user provided (%s)...", cat);
if (test_cat(logdepth, cat)) return 0;
}
return 1;
}
int find_fstools_sed(const char *name, int logdepth, int fatal)
{
const char *sed;
(void) fatal; /* to suppress compiler warnings about not using fatal */
report("Checking for sed... ");
logprintf(logdepth, "find_fstools_sed: trying to find sed...\n");
logdepth++;
sed = get("/arg/fstools/sed");
if (sed == NULL) {
if (test_sed(logdepth, "sed")) return 0;
}
else {
report(" user provided (%s)...", sed);
if (test_sed(logdepth, sed)) return 0;
}
return 1;
}
int find_fstools_file_l(const char *name, int logdepth, int fatal)
{
const char *file;
(void) fatal; /* to suppress compiler warnings about not using fatal */
report("Checking for file... ");
logprintf(logdepth, "find_fstools_file_l: trying to find file -L...\n");
logdepth++;
file = get("/arg/fstools/file_l");
if (file == NULL) {
if (test_file(logdepth, "fstools/file_l", "file -L")) return 0;
if (test_file(logdepth, "fstools/file_l", "file")) return 0;
}
else {
report(" user provided (%s)...", file);
if (test_file(logdepth, "fstools/file_l", file)) return 0;
}
return 1;
}
int find_fstools_file(const char *name, int logdepth, int fatal)
{
const char *file;
(void) fatal; /* to suppress compiler warnings about not using fatal */
report("Checking for file... ");
logprintf(logdepth, "find_fstools_file: trying to find file...\n");
logdepth++;
file = get("/arg/fstools/file");
if (file == NULL) {
if (test_file(logdepth, "fstools/file", "file")) return 0;
}
else {
report(" user provided (%s)...", file);
if (test_file(logdepth, "fstools/file", file)) return 0;
}
return 1;
}

View File

@ -1,204 +0,0 @@
/*
scconfig - helpers for a main()
Copyright (C) 2009..2016 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "db.h"
#include "find.h"
#include "log.h"
#include "arg.h"
#include "dep.h"
#include "deps_default.h"
#include "libs.h"
#include "hooks.h"
#include "regex.h"
#include "main_custom_args.h"
#ifdef PLUGIN_SCRIPTS
#include "../scripts/INIT.h"
#endif
#ifdef PLUGIN_PARSER
#include "../parser/INIT.h"
#endif
#ifdef PLUGIN_C99
#include "../c99/INIT.h"
#endif
#ifdef PLUGIN_PARSGEN
#include "../parsgen/INIT.h"
#endif
#ifdef PLUGIN_MATH
#include "../math/INIT.h"
#endif
#ifdef PLUGIN_SOCKET
#include "../socket/INIT.h"
#endif
#ifdef PLUGIN_USERPASS
#include "../userpass/INIT.h"
#endif
#ifdef PLUGIN_GUI
#include "../gui/INIT.h"
#endif
#ifdef PLUGIN_TTY
#include "../tty/INIT.h"
#endif
#ifdef PLUGIN_SUL
#include "../sul/INIT.h"
#endif
#ifdef PLUGIN_POSIX
#include "../posix/INIT.h"
#endif
#ifdef PLUGIN_GENERATOR
#include "generator.h"
#endif
void init(void)
{
db_init();
log_init();
dep_init();
deps_default_init();
/* common internal directory */
db_mkdir("/internal");
/* We have a host system for sure - also make it the default */
db_mkdir("/host");
db_cd("/host");
/* emulator for the host system is empty string */
put("sys/emu", "");
#ifdef PLUGIN_SCRIPTS
#include "../scripts/INIT.c"
#endif
#ifdef PLUGIN_PARSER
#include "../parser/INIT.c"
#endif
#ifdef PLUGIN_C99
#include "../c99/INIT.c"
#endif
#ifdef PLUGIN_PARSGEN
#include "../parsgen/INIT.c"
#endif
#ifdef PLUGIN_MATH
#include "../math/INIT.c"
#endif
#ifdef PLUGIN_SOCKET
#include "../socket/INIT.c"
#endif
#ifdef PLUGIN_USERPASS
#include "../userpass/INIT.c"
#endif
#ifdef PLUGIN_GUI
#include "../gui/INIT.c"
#endif
#ifdef PLUGIN_TTY
#include "../tty/INIT.c"
#endif
#ifdef PLUGIN_SUL
#include "../sul/INIT.c"
#endif
#ifdef PLUGIN_POSIX
#include "../posix/INIT.c"
#endif
#ifdef PLUGIN_GENERATOR
#include "../generator/INIT.c"
#endif
}
void uninit(void)
{
log_uninit();
dep_uninit();
db_uninit();
}
void run_custom_reqs(void)
{
int n;
if (num_custom_reqs > 0) {
printf("Running custom requirements\n");
for(n = 0; n < num_custom_reqs; n++) {
if (custom_reqs[n] == NULL) {
fprintf(stderr, "Error: requested detection of empty string - please check your command line, syntax is --detect=node\n");
exit(1);
}
require(custom_reqs[n], 1, 1);
}
}
}
int main_init(void)
{
re_modw("./\\");
if (hook_preinit()) {
fprintf(stderr, "hook_preinit failed, exiting\n");
return 1;
}
init();
if (hook_postinit()) {
fprintf(stderr, "hook_postinit failed, exiting\n");
return 1;
}
return 0;
}
int main_process_args(int argc, char *argv[])
{
process_args(argc, argv);
if (hook_postarg()) {
fprintf(stderr, "hook_postarg failed, exiting\n");
return 1;
}
return 0;
}
void main_uninit(void)
{
hook_preuninit();
uninit();
hook_postuninit();
}

View File

@ -1,194 +0,0 @@
/*
scconfig - detection of standard library features
Copyright (C) 2009 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
static int trydlc(int logdepth, const char *test_c_dlc, const char *cflagsf, const char *ldflagsf, const char *dlc)
{
char *cflags, *ldflags;
cflags = malloc(strlen(dlc) + 64);
ldflags = malloc(strlen(dlc)*2 + 256);
sprintf(cflags, cflagsf, dlc);
sprintf(ldflags, ldflagsf, dlc, dlc);
if (try_icl(logdepth, NULL, test_c_dlc, NULL, cflags, ldflags)) {
*cflags = ' ';
append("cc/cflags", cflags);
put("libs/ldl", ldflags);
put("libs/dl-compat", strue);
report("OK (%s and %s)\n", cflags, ldflags);
free(cflags);
free(ldflags);
return 1;
}
free(cflags);
free(ldflags);
return 0;
}
int find_lib_ldl(const char *name, int logdepth, int fatal)
{
const char *ldl, *dlc;
char *s;
char *test_c =
NL "#include <stdio.h>"
NL "#include <dlfcn.h>"
NL "int main() {"
NL " void *handle;"
NL " handle = dlopen(\"/this file does not exist.\", RTLD_NOW);"
NL " if (handle == NULL) printf(\"OK\\n\");"
NL " return 0;"
NL "}"
NL;
char *test_c_dlc =
NL "#include <stdio.h>"
NL "#include <dl-compat.h>"
NL "int main() {"
NL " void *handle;"
NL " handle = dlopen(\"/this file does not exist.\", RTLD_NOW);"
NL " if (handle == NULL) printf(\"OK\\n\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for -ldl... ");
logprintf(logdepth, "find_lib_ldl: trying to find ldl...\n");
logdepth++;
ldl = get("/arg/libs/ldl");
if (ldl == NULL) {
dlc = get("/arg/libs/dl-compat");
if (dlc == NULL) {
/* If dlc is not explicitly requested by the user, try standard
dl (see whether we need -ldl for dlopen()) */
if (try_icl(logdepth, NULL, test_c, NULL, NULL, NULL)) {
put("libs/ldl", "");
put("libs/ldl/includes", "#include <dlfcn.h>\\n");
report("OK ()\n");
return 0;
}
if (try_icl(logdepth, NULL, test_c, NULL, NULL, "-ldl")) {
put("libs/ldl", "-ldl");
put("libs/ldl/includes", "#include <dlfcn.h>\\n");
report("OK (-ldl)\n");
return 0;
}
}
/* try dl-compat (dl compatibility lib) */
if (dlc != NULL) {
/* test at user supplied dlc prefix:
- first assume the linker will find it
- next assume gcc and pass rpath to the linker
- finally try static linking */
if (trydlc(logdepth, test_c_dlc, "-I%s/include", "-L%s/lib -ldl-compat\000%s", dlc)) {
put("libs/ldl/includes", "#include <dl-compat.h>\\n");
return 0;
}
if (trydlc(logdepth, test_c_dlc, "-I%s/include", "-L%s/lib -Wl,-rpath=%s/lib -ldl-compat", dlc)) {
put("libs/ldl/includes", "#include <dl-compat.h>\\n");
return 0;
}
if (trydlc(logdepth, test_c_dlc, "-I%s/include", "%s/lib/libdl-compat.a\000%s", dlc)) {
put("libs/ldl/includes", "#include <dl-compat.h>\\n");
return 0;
}
}
else if (try_icl(logdepth, NULL, test_c_dlc, NULL, NULL, "-ldl-compat")) {
/* check at normal system installation */
put("libs/ldl", "-ldl-compat");
put("libs/ldl/includes", "#include <dl-compat.h>\\n");
report("OK (-ldl-compat)\n");
return 0;
}
}
else {
report("User provided... ");
s = strclone(ldl);
if (try_icl(logdepth, NULL, test_c, NULL, NULL, s)) {
put("libs/ldl", ldl);
put("libs/ldl/includes", "#include <dlfcn.h>\\n");
report("OK (%s)\n", ldl);
free(s);
return 0;
}
free(s);
}
report("Not found\n");
return 1;
}
int find_lib_LoadLibrary(const char *name, int logdepth, int fatal)
{
/*char *s;*/
char *test_c =
NL "#include <stdio.h>"
NL "int main() {"
NL " void *handle;"
NL " handle = LoadLibrary(\"/this file does not exist.\");"
NL " if (handle == NULL) printf(\"OK\\n\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for LoadLibrary... ");
logprintf(logdepth, "find_lib_LoadLibrary: trying to find LoadLibrary...\n");
logdepth++;
if (try_icl(logdepth, "libs/LoadLibrary", test_c, "#include <windows.h>", NULL, NULL))
return 0;
return try_fail(logdepth, "libs/LoadLibrary");
}
int find_lib_errno(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <errno.h>"
NL "int main() {"
NL " errno = 0;"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL ;
require("cc/cc", logdepth, fatal);
report("Checking for errno.h... ");
logprintf(logdepth, "find_lib_errno: trying to find errno...\n");
logdepth++;
if (try_icl(logdepth, "libs/errno", test_c, NULL, NULL, NULL)) return 0;
return try_fail(logdepth, "libs/errno");
}

View File

@ -1,189 +0,0 @@
/*
scconfig - detect I/O features of the system
Copyright (C) 2010 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
int find_io_pipe(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <unistd.h>"
NL "int main() {"
NL " int fd[2];"
NL " if (pipe(fd) == 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for pipe(2)... ");
logprintf(logdepth, "find_io_pipe: trying to find pipe(2)...\n");
logdepth++;
if (try_icl(logdepth, "libs/io/pipe", test_c, NULL, NULL, NULL)) return 0;
return try_fail(logdepth, "libs/io/pipe");
}
int find_io_dup2(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <unistd.h>"
NL "int main() {"
NL " int fd;"
NL " if (dup2(1, 4) == 4)"
NL " write(4, \"OK\\n\", 3); "
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for dup2(2)... ");
logprintf(logdepth, "find_io_dup2: trying to find dup2(2)...\n");
logdepth++;
if (try_icl(logdepth, "libs/io/dup2", test_c, NULL, NULL, NULL)) return 0;
return try_fail(logdepth, "libs/io/dup2");
}
int find_io_fileno(const char *name, int logdepth, int fatal)
{
char test_c[256];
char *test_c_ =
NL "#include <stdio.h>"
NL "int main() {"
NL no_implicit(int, "%s", "%s")
NL " if (%s(stdout) >= 0)"
NL " puts(\"OK\"); "
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for fileno(3)... ");
logprintf(logdepth, "find_io_fileno: trying to find fileno(3)...\n");
logdepth++;
/* UNIX */
sprintf(test_c, test_c_, "fileno", "fileno", "fileno");
if (try_icl(logdepth, "libs/io/fileno", test_c, "#include <unistd.h>\n", NULL, NULL)) {
put("libs/io/fileno/call", "fileno");
return 0;
}
sprintf(test_c, test_c_, "fileno", "fileno", "fileno");
if (try_icl(logdepth, "libs/io/fileno", test_c, "#define _XOPEN_SOURCE\n#include <unistd.h>\n", NULL, NULL)) {
put("libs/io/fileno/call", "fileno");
return 0;
}
/* windows */
sprintf(test_c, test_c_, "_fileno", "_fileno", "_fileno");
if (try_icl(logdepth, "libs/io/fileno", test_c, "#include <stdio.h>\n", NULL, NULL)) {
put("libs/io/fileno/call", "_fileno");
return 0;
}
return try_fail(logdepth, "libs/io/fileno");
}
int find_io_lseek(const char *name, int logdepth, int fatal)
{
#define NODE "libs/io/lseek"
char test_c[3256];
const char *test_c_template =
NL "#include <stdio.h>"
NL "#include <fcntl.h>"
NL "int main() {"
NL " const char *filename = \"%s\";"
NL no_implicit(int, "%s", "%s")
NL " int fd = open(filename, O_WRONLY);"
NL " if (write(fd, \"abc\", 3) == 3 && %s(fd, 1, SEEK_SET) == 1)"
NL " puts(\"OK\"); "
NL " return 0;"
NL "}"
NL;
char *tmpf;
const char *incs[] = {"#include <unistd.h>","#include <io.h>",NULL};
const char *fns[] = {"lseek", "_lseek", NULL};
const char **inc;
const char **fn;
require("cc/cc", logdepth, fatal);
report("Checking for lseek(2)... ");
logprintf(logdepth, "find_io_lseek: trying to find lseek(2)...\n");
logdepth++;
tmpf = tempfile_new(".psx");
for (inc = incs, fn = fns; *fn; ++inc, ++fn) {
sprintf(test_c, test_c_template, tmpf, *fn, *fn, *fn);
if (try_icl(logdepth, NODE, test_c, *inc, NULL, NULL)) {
put(NODE "/call", *fn);
return 0;
}
}
return try_fail(logdepth, NODE);
#undef NODE
}
int find_io_popen(const char *name, int logdepth, int fatal)
{
const char **i, *incs[] = {"#define _XOPEN_SOURCE", "#define _BSD_SOURCE", "#define _POSIX_C_SOURCE 2", NULL};
char *test_c =
NL "#include <stdlib.h>"
NL "#include <stdio.h>"
NL "int main() {"
NL " FILE *f = popen(\"echo OK\", \"r\");"
NL " char line[16];"
NL " if (f == NULL) return 0;"
NL " if (fgets(line, sizeof(line)-1, f) == NULL) return 0;"
NL " puts(line);"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for popen(3)... ");
logprintf(logdepth, "find_io_popen: trying to find popen(3)...\n");
logdepth++;
for(i = incs; *i != NULL; i++)
if (try_icl(logdepth, "libs/io/popen", test_c, *i, NULL, NULL)) return 0;
return try_fail(logdepth, "libs/io/popen");
}

View File

@ -1,424 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
/* Returns true if the first 2 characters of the output is OK */
static int try_icl_accept_ok(char *stdout_str)
{
return (strncmp(stdout_str, "OK", 2) == 0);
}
#define is_ctrl_prefix(ch) (((ch) == '!') || ((ch) == '^'))
static int try_icl__(int logdepth, const char *prefix, const char *test_c_in, const char *includes, const char *cflags, const char *ldflags, const char *db_includes, const char *db_cflags, const char *db_ldflags, int run, int (*accept_res)(char *stdout_str))
{
char *out = NULL;
char *tmp, *inc;
const char *test_c;
char c[1024];
int l, compres;
if (includes != NULL) {
l = strlen(includes);
memcpy(c, includes, l);
c[l] = '\n';
l++;
strcpy(c+l, test_c_in);
test_c = c;
}
else
test_c = test_c_in;
logprintf(logdepth, "trying '%s' and '%s' and '%s', %s\n", str_null(db_includes), str_null(db_cflags), str_null(db_ldflags), run ? "with a run" : "with no run");
if (run)
compres = compile_run(logdepth+1, test_c, NULL, cflags, ldflags, &out);
else {
char *fn_output = NULL;
compres = compile_code(logdepth+1, test_c, &fn_output, NULL, cflags, ldflags);
if (fn_output != NULL) {
unlink(fn_output);
free(fn_output);
}
}
if (compres == 0) {
if (!run || target_emu_fail(out) || accept_res(out)) {
free(out);
/* no prefix: don't modify the database, the caller will do that */
if (prefix == NULL)
return 1;
tmp = malloc(strlen(prefix) + 32);
if ((db_includes == NULL) || (*db_includes == '\0'))
inc = strclone("");
else
inc = uniq_inc_str(db_includes, NULL, "\\n", 0, 0, NULL);
sprintf(tmp, "%s/includes", prefix);
put(tmp, inc);
if (db_cflags == NULL)
db_cflags = "";
sprintf(tmp, "%s/cflags", prefix);
put(tmp, db_cflags);
if (db_ldflags == NULL)
db_ldflags = "";
sprintf(tmp, "%s/ldflags", prefix);
put(tmp, db_ldflags);
if (inc != NULL) {
report("OK ('%s', '%s' and '%s')\n", str_null(inc), str_null(db_cflags), str_null(db_ldflags));
free(inc);
}
else
report("OK ('%s' and '%s')\n", str_null(db_cflags), str_null(db_ldflags));
sprintf(tmp, "%s/presents", prefix);
put(tmp, strue);
free(tmp);
return 1;
}
free(out);
}
return 0;
}
#define LOAD(node) \
do { \
if (u ## node != NULL) break; \
strcpy(apath_end, #node); \
u ## node = get(apath); \
} while(0)
#define SET(dst, src, is_flag) \
do { \
char *__sep__ = is_flag ? " " : "\n"; \
const char *__dst__ = dst == NULL ? "" : dst; \
char *__out__; \
if (is_ctrl_prefix(*__dst__)) __dst__++; \
if (*src == '!') \
__out__ = strclone(src+1); \
else if (*src == '^') {\
if (src[1] != '\0') \
__out__ = str_concat("", src+1, __sep__, __dst__, NULL); \
else \
__out__ = strclone(__dst__); \
} \
else { \
if (*__dst__ != '\0') \
__out__ = str_concat("", __dst__, __sep__, src, NULL); \
else \
__out__ = strclone(src); \
} \
free(dst); \
dst = __out__; \
if (is_flag) { \
char *__s__; \
for(__s__ = dst; *__s__ != '\0'; __s__++) \
if ((*__s__ == '\n') || (*__s__ == '\r')) \
*__s__ = ' '; \
} \
} while(0)
/* Figure user overrides and call try_icl__() accordingly */
int try_icl_(int logdepth, const char *prefix, const char *test_c_in, const char *includes, const char *cflags, const char *ldflags, int run, int (*accept_res)(char *stdout_str))
{
char apath[1024], *apath_end;
int l, res;
const char *uincludes = NULL, *ucflags = NULL, *uldflags = NULL, *uprefix = NULL; /* user specified */
char *rincludes, *rcflags, *rldflags; /* real */
char *dbincludes = NULL, *dbcflags = NULL, *dbldflags = NULL; /* what to add in the db at the end */
if ((prefix == NULL) ? 0 : strlen(prefix) + strlen(db_cwd) > sizeof(apath)-32) {
report("ERROR: no room for try_icl_() - prefix is probably too long.\n");
return -1;
}
/* load uincludes, uclfags, uldflags and uprefix - LOAD() inserts the u */
l = sprintf(apath, "/arg/icl/%s/", prefix); apath_end = apath+l;
LOAD(includes);
LOAD(cflags);
LOAD(ldflags);
LOAD(prefix);
l = sprintf(apath, "/arg/icl/%s/%s/", db_cwd, prefix); apath_end = apath+l;
LOAD(includes);
LOAD(cflags);
LOAD(ldflags);
LOAD(prefix);
/* special case: all three specified by the user - ignore what the detector wanted, but run only once per node prefix */
if ((uincludes != NULL) && (ucflags != NULL) && (uldflags != NULL)) {
const char *am;
sprintf(apath, "%s/icl/all_manual_result", prefix);
am = get(apath);
if (am != NULL)
return istrue(am); /* return cached result if available */
res = try_icl__(logdepth, prefix, test_c_in, uincludes, ucflags, uldflags, uincludes, ucflags, uldflags, run, accept_res);
put(apath, res ? strue : sfalse);
return res;
}
/* TODO: get default cflags here */
rincludes = NULL;
rcflags = strclone(get("cc/cflags"));
rldflags = strclone(get("cc/ldflags"));
/* override base/default values with detection requested ones */
if (includes != NULL) SET(rincludes, includes, 0);
if (cflags != NULL) SET(rcflags, cflags, 1);
if (ldflags != NULL) SET(rldflags, ldflags, 1);
if (includes != NULL) SET(dbincludes, includes, 0);
if (cflags != NULL) SET(dbcflags, cflags, 1);
if (ldflags != NULL) SET(dbldflags, ldflags, 1);
/* override detection with user specified ICL values */
if (uincludes != NULL) SET(rincludes, uincludes, 0);
if (ucflags != NULL) SET(rcflags, ucflags, 1);
if (uldflags != NULL) SET(rldflags, uldflags, 1);
if (uincludes != NULL) SET(dbincludes, uincludes, 0);
if (ucflags != NULL) SET(dbcflags, ucflags, 1);
if (uldflags != NULL) SET(dbldflags, uldflags, 1);
/* insert prefix as needed */
if (uprefix != NULL) {
char *old, *prfx;
old = rcflags;
if ((rcflags != NULL) && (*rcflags == '^')) {
rcflags++;
prfx = "^";
}
else
prfx = "";
rcflags = str_concat("", prfx, "-I", uprefix, "/include ", rcflags, NULL);
if (old != cflags) free(old);
old = rldflags;
if ((rldflags != NULL) && (*rldflags == '^')) {
rldflags++;
prfx = "^";
}
else
prfx = "";
rldflags = str_concat("", prfx, "-L", uprefix, "/lib ", rldflags, NULL);
if (old != ldflags) free(old);
}
res = try_icl__(logdepth, prefix, test_c_in, rincludes, rcflags, rldflags, dbincludes, dbcflags, dbldflags, run, accept_res);
/* if we had to alloc, free here */
free(rincludes);
free(rcflags);
free(rldflags);
free(dbincludes);
free(dbcflags);
free(dbldflags);
return res;
}
#undef LOAD
#undef SET
int try_icl(int logdepth, const char *prefix, const char *test_c_in, const char *includes, const char *cflags, const char *ldflags)
{
return try_icl_(logdepth, prefix, test_c_in, includes, cflags, ldflags, 1, try_icl_accept_ok);
}
int try_icl_with_deps(int logdepth, const char *prefix, const char *test_c_in, const char *includes, const char *cflags, const char *ldflags, const char *dep_includes, const char *dep_cflags, const char *dep_ldflags, int run)
{
int res;
if ((dep_includes != NULL) && (*dep_includes == '\0')) dep_includes = NULL;
if ((dep_cflags != NULL) && (*dep_cflags == '\0')) dep_cflags = NULL;
if ((dep_ldflags != NULL) && (*dep_ldflags == '\0')) dep_ldflags = NULL;
if (dep_includes != NULL) includes = str_concat(" ", dep_includes, includes, NULL);
if (dep_cflags != NULL) cflags = str_concat(" ", dep_cflags, cflags, NULL);
if (dep_ldflags != NULL) ldflags = str_concat(" ", dep_ldflags, ldflags, NULL);
res = try_icl_(logdepth, prefix, test_c_in, includes, cflags, ldflags, run, try_icl_accept_ok);
if (dep_includes != NULL) free((char *)includes);
if (dep_cflags != NULL) free((char *)cflags);
if (dep_ldflags != NULL) free((char *)ldflags);
return res;
}
int try_icl_norun(int logdepth, const char *prefix, const char *test_c_in, const char *includes, const char *cflags, const char *ldflags)
{
return try_icl_(logdepth, prefix, test_c_in, includes, cflags, ldflags, 0, try_icl_accept_ok);
}
int try_fail(int logdepth, const char *prefix)
{
char *tmp;
tmp = malloc(strlen(prefix) + 32);
sprintf(tmp, "%s/presents", prefix);
put(tmp, sfalse);
free(tmp);
report("not found\n");
logprintf(logdepth, "NOT FOUND.");
return 1;
}
static int try_pkg_config_(int logdepth, char *pkgname, const char *prefix, const char *test_c)
{
char *cflags, *ldflags;
int res;
logprintf(logdepth, "Trying pkg-config %s\n", pkgname);
if (run_pkg_config(logdepth+1, pkgname, &cflags, &ldflags) == 0)
res = try_icl(logdepth+1, prefix, test_c, NULL, cflags, ldflags);
else
res = 0;
free(cflags);
free(ldflags);
return res;
}
int try_icl_pkg_config(int logdepth, const char *prefix, const char *test_c, char *includes, const char *pkgpat, const char *reqver)
{
char **pkg_ver, **s;
int num_pkg_ver;
int res = 0;
(void) includes; /* not used */
run_pkg_config_lst(logdepth, pkgpat, &num_pkg_ver, &pkg_ver);
if (pkg_ver == NULL)
return 0;
if (reqver != NULL) {
/* search the list for the preferred version */
for(s = pkg_ver; *s != NULL; s+=2) {
if (strcmp(s[1], reqver) == 0) {
if (try_pkg_config_(logdepth, s[0], prefix, test_c)) {
res = 1;
report("Found version required (%s) using pkg_config.\n", reqver);
goto out;
}
else {
report("The version required (%s) is found (via pkg_config) but does not work\n", reqver);
goto out;
}
}
}
goto out;
}
for(s = pkg_ver; *s != NULL; s+=2) {
if (try_pkg_config_(logdepth, s[0], prefix, test_c)) {
res = 1;
goto out;
}
}
out:;
filelist_free(&num_pkg_ver, &pkg_ver);
return res;
}
int import_icl(const char *key, const char *fn)
{
char path[1024];
if (strlen(key) > sizeof(path)-32) {
report("ERROR: no room for import_icl() - key is probably too long.\n");
return -1;
}
switch(*key) {
case 'l': sprintf(path, "/arg/icl/%s/ldflags", key+8); break;
case 'c': sprintf(path, "/arg/icl/%s/cflags", key+7); break;
case 'i': sprintf(path, "/arg/icl/%s/includes", key+9); break;
case 'p': sprintf(path, "/arg/icl/%s/prefix", key+7); break;
default:
return 1;
}
return put(path, fn) == NULL;
}
static long field_accept_len;
static int field_accept_res(char *stdout_str)
{
char *end;
field_accept_len = strtol(stdout_str, &end, 10);
if (((*end == '\0') || (*end == '\r') || (*end == '\n')) && (field_accept_len > 0))
return 1;
return 0;
}
int try_icl_sfield(int logdepth, const char *prefix, const char *structn, const char *fieldn, const char *includes, const char *cflags, const char *ldflags)
{
int res;
char test_c[512];
char ls[16];
const char *test_c_in =
NL "#include <stdio.h>"
NL "int main()"
NL "{"
NL " %s s;"
NL " printf(\"%%ld\\n\", (long)sizeof(s.%s));"
NL "}"
NL;
if (strlen(fieldn) + strlen(structn) + strlen(test_c_in) + 32 >= sizeof(test_c)) {
report("ERROR: no room for try_icl_sfield() - struct or field name is probably too long.\n");
return -1;
}
sprintf(test_c, test_c_in, structn, fieldn);
res = try_icl_(logdepth, prefix, test_c, includes, cflags, ldflags, 1, field_accept_res);
if (res) {
sprintf(test_c, "%s/sizeof", prefix);
sprintf(ls, "%ld", field_accept_len);
put(test_c, ls);
}
return res;
}
int try_icl_sfields(int logdepth, const char *prefix, const char *structn, const char **fields, const char *includes, const char *cflags, const char *ldflags, int silent_exit_first_fail)
{
int succ = 0, first = 1;
require("cc/cc", logdepth, 1);
for(; *fields != NULL; fields++) {
report("Checking for %s.%s... ", structn, *fields);
logprintf(logdepth, "%s: checking for field %s...\n", structn, *fields);
logdepth++;
if (try_icl_sfield(logdepth, prefix, structn, *fields, includes, cflags, ldflags)) {
succ = 1;
}
else if ((silent_exit_first_fail) && (first)) {
return 1;
}
logdepth--;
first = 0;
}
if (!succ)
try_fail(logdepth, "libs/fsmount/next_dev");
return 0;
}

View File

@ -1,203 +0,0 @@
/*
scconfig - detection of standard library features
Copyright (C) 2009 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
static int trydlc(int logdepth, const char *test_c_dlc, const char *cflagsf, const char *ldflagsf, const char *dlc)
{
char *cflags, *ldflags;
cflags = malloc(strlen(dlc) + 64);
ldflags = malloc(strlen(dlc)*2 + 256);
sprintf(cflags, cflagsf, dlc);
sprintf(ldflags, ldflagsf, dlc, dlc);
if (try_icl(logdepth, NULL, test_c_dlc, NULL, cflags, ldflags)) {
*cflags = ' ';
append("cc/cflags", cflags);
put("libs/ldl", ldflags);
put("libs/dl-compat", strue);
report("OK (%s and %s)\n", cflags, ldflags);
free(cflags);
free(ldflags);
return 1;
}
free(cflags);
free(ldflags);
return 0;
}
int find_lib_ldl(const char *name, int logdepth, int fatal)
{
const char *ldl, *dlc;
char *s;
char *test_c =
NL "#include <stdio.h>"
NL "#include <dlfcn.h>"
NL "int main() {"
NL " void *handle;"
NL " handle = dlopen(\"/this file does not exist.\", RTLD_NOW);"
NL " if (handle == NULL) printf(\"OK\\n\");"
NL " return 0;"
NL "}"
NL;
char *test_c_dlc =
NL "#include <stdio.h>"
NL "#include <dl-compat.h>"
NL "int main() {"
NL " void *handle;"
NL " handle = dlopen(\"/this file does not exist.\", RTLD_NOW);"
NL " if (handle == NULL) printf(\"OK\\n\");"
NL " return 0;"
NL "}"
NL;
s = (char *)get("libs/ldl/presents");
if (s != NULL)
return !istrue(s);
require("cc/cc", logdepth, fatal);
report("Checking for -ldl... ");
logprintf(logdepth, "find_lib_ldl: trying to find ldl...\n");
logdepth++;
ldl = get("/arg/libs/ldl");
if (ldl == NULL) {
dlc = get("/arg/libs/dl-compat");
if (dlc == NULL) {
/* If dlc is not explicitly requested by the user, try standard
dl (see whether we need -ldl for dlopen()) */
if (try_icl(logdepth, NULL, test_c, NULL, NULL, NULL)) {
put("libs/ldl", "");
put("libs/ldl/includes", "#include <dlfcn.h>\\n");
put("libs/ldl/presents", strue);
report("OK ()\n");
return 0;
}
if (try_icl(logdepth, NULL, test_c, NULL, NULL, "-ldl")) {
put("libs/ldl", "-ldl");
put("libs/ldl/includes", "#include <dlfcn.h>\\n");
put("libs/ldl/presents", strue);
report("OK (-ldl)\n");
return 0;
}
}
/* try dl-compat (dl compatibility lib) */
if (dlc != NULL) {
/* test at user supplied dlc prefix:
- first assume the linker will find it
- next assume gcc and pass rpath to the linker
- finally try static linking */
if (trydlc(logdepth, test_c_dlc, "-I%s/include", "-L%s/lib -ldl-compat\000%s", dlc)) {
put("libs/ldl/includes", "#include <dl-compat.h>\\n");
return 0;
}
if (trydlc(logdepth, test_c_dlc, "-I%s/include", "-L%s/lib -Wl,-rpath=%s/lib -ldl-compat", dlc)) {
put("libs/ldl/includes", "#include <dl-compat.h>\\n");
return 0;
}
if (trydlc(logdepth, test_c_dlc, "-I%s/include", "%s/lib/libdl-compat.a\000%s", dlc)) {
put("libs/ldl/includes", "#include <dl-compat.h>\\n");
return 0;
}
}
else if (try_icl(logdepth, NULL, test_c_dlc, NULL, NULL, "-ldl-compat")) {
/* check at normal system installation */
put("libs/ldl", "-ldl-compat");
put("libs/ldl/includes", "#include <dl-compat.h>\\n");
put("libs/ldl/presents", strue);
report("OK (-ldl-compat)\n");
return 0;
}
}
else {
report("User provided... ");
s = strclone(ldl);
if (try_icl(logdepth, NULL, test_c, NULL, NULL, s)) {
put("libs/ldl", ldl);
put("libs/ldl/includes", "#include <dlfcn.h>\\n");
put("libs/ldl/presents", strue);
report("OK (%s)\n", ldl);
free(s);
return 0;
}
free(s);
}
put("libs/ldl/presents", sfalse);
report("Not found\n");
return 1;
}
int find_lib_LoadLibrary(const char *name, int logdepth, int fatal)
{
/*char *s;*/
char *test_c =
NL "#include <stdio.h>"
NL "int main() {"
NL " void *handle;"
NL " handle = LoadLibrary(\"/this file does not exist.\");"
NL " if (handle == NULL) printf(\"OK\\n\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for LoadLibrary... ");
logprintf(logdepth, "find_lib_LoadLibrary: trying to find LoadLibrary...\n");
logdepth++;
if (try_icl(logdepth, "libs/LoadLibrary", test_c, "#include <windows.h>", NULL, NULL))
return 0;
return try_fail(logdepth, "libs/LoadLibrary");
}
int find_lib_errno(const char *name, int logdepth, int fatal)
{
char *test_c =
NL "#include <errno.h>"
NL "int main() {"
NL " errno = 0;"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL ;
require("cc/cc", logdepth, fatal);
report("Checking for errno.h... ");
logprintf(logdepth, "find_lib_errno: trying to find errno...\n");
logdepth++;
if (try_icl(logdepth, "libs/errno", test_c, NULL, NULL, NULL)) return 0;
return try_fail(logdepth, "libs/errno");
}

View File

@ -1,153 +0,0 @@
/*
scconfig - command line argument processing
Copyright (C) 2009..2012 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <string.h>
#include "db.h"
#include "arg.h"
#include "dep.h"
#include "log.h"
#include "libs.h"
argtbl_t main_argument_table[] = {
{"import", NULL, import_args, "Import saved config (sub)tree"},
{"target", "/arg/sys/target", NULL, "set cross compilation target (prefix)"},
{"target-name", "/arg/sys/target-name", NULL, "set cross compilation target (system name)"},
{"target-shell","/arg/sys/target-shell",NULL, "set the shell on cross compilation target"},
{"emu", "/arg/sys/emu", NULL, "emulator for testing cross compiled executables with"},
{"pkg-config", "/arg/sys/pkg-config", NULL, "path to pkg-config to use"},
{"pkg-config-zap","/arg/sys/pkg-config-zap",NULL, "ignore pkg-config results by this regex pattern"},
/* wildcard rules for icl() control */
{"^ldflags/", NULL, import_icl, "force LDFLAGS for a node"},
{"^cflags/", NULL, import_icl, "force CFLAGS for a node"},
{"^includes/", NULL, import_icl, "force #includes for a node"},
{"^prefix/", NULL, import_icl, "force using prefix path for detecting the node"},
/* the followings are autoconf compatibility translations */
{"CC", "/arg/cc/cc", NULL, "Force using a C compiler (command line)"},
{"CFLAGS", "/arg/cc/cflags", NULL, "Force using a CFLAGS for C compilation"},
{"LDFLAGS", "/arg/cc/ldflags", NULL, "Force using a LDFLAGS for linking"},
{"LDL", "/arg/libs/ldl", NULL, "Force using -ldl string"},
{"gpmi-prefix", "/arg/gpmi/prefix", NULL, NULL},
{NULL, NULL, NULL, NULL}
};
void process_args(int argc, char *argv[])
{
int n;
char *key, *value;
argtbl_t *a;
int found, tainted = 0;
db_mkdir("/arg");
logprintf(0, "CLI arg 0: '%s'\n", argv[0]);
for(n = 1; n < argc; n++) {
key = argv[n];
logprintf(0, "CLI arg %d: '%s'\n", n, key);
while(*key == '-') key++;
value = str_chr(key, '=');
found = 0;
if (value != NULL) {
*value = '\0';
value++;
if (strcmp(key, "without") == 0) {
char *tmp, *end;
if (*value != '/') {
const char **r, *roots[] = {"target", "host", "runtime", NULL};
for(r = roots; *r != NULL; r++) {
tmp = str_concat("/", "/arg/without", *r, value, NULL);
put(tmp, strue);
free(tmp);
}
}
else {
tmp = str_concat("/", "/arg/without", value+1, NULL);
put(tmp, strue);
free(tmp);
}
found = 1;
}
else {
/* Look in the argument translate table */
for(a = main_argument_table; a->arg != NULL; a++) {
if (((a->arg[0] == '^') && (strncmp(a->arg+1, key, strlen(a->arg+1)) == 0)) || (strcmp(a->arg, key) == 0)) {
found = 1;
if (a->callback != NULL) {
if (a->callback(key, value) != 0) {
error("Processing argument '%s' failed in the callback\n", argv[n]);
abort();
}
}
if (a->path != NULL)
put(a->path, value);
}
}
}
/* Look in known deps table or /arg */
if (found == 0) {
if ((is_dep_known(key)) || (strncmp(key, "/arg/", 5) == 0)) {
put(key, value);
found = 1;
}
}
}
if (found == 0) {
if (custom_arg(key, value) == 0) {
error("Unknown argument '%s'\n", key);
tainted++;
}
}
}
if (tainted)
exit(1);
}
void help_default_args(FILE *f, const char *prefix)
{
argtbl_t *a;
if (prefix == NULL)
prefix = "";
fprintf(f, "%sscconfig generic command line arguments:\n", prefix);
for(a = main_argument_table; a->arg != NULL; a++) {
char *tmp;
if (a->help == NULL)
continue;
if (*a->arg == '^') {
tmp = str_concat("", a->arg+1, "...=...", NULL);
fprintf(f, "%s --%-22s %s\n", prefix, tmp, a->help);
}
else {
tmp = str_concat("", a->arg, "=...", NULL);
fprintf(f, "%s --%-22s %s\n", prefix, tmp, a->help);
}
free(tmp);
}
}

View File

@ -1 +0,0 @@
void deps_default_init(void);

View File

@ -1,49 +0,0 @@
/*
scconfig - default way to handle custom args (save them in an array)
Copyright (C) 2016 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "libs.h"
#include "log.h"
#include "hooks.h"
#include "main_custom_args.h"
char *custom_reqs[MAX_CUSTOM_REQS];
int num_custom_reqs = 0;
int custom_arg(const char *key, const char *value)
{
if (hook_custom_arg(key, value))
return 1;
if (strcmp(key, "detect") == 0) {
printf("Will detect: %s\n", value);
if (num_custom_reqs >= MAX_CUSTOM_REQS) {
report("Too many custom reqs from the command line, exiting\n");
exit(1);
}
custom_reqs[num_custom_reqs] = strclone(value);
num_custom_reqs++;
return 1;
}
return 0;
}

View File

@ -1,132 +0,0 @@
/*
scconfig - logging
Copyright (C) 2009 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include "log.h"
#include <stdio.h>
#include <assert.h>
#include <stdarg.h>
#include <string.h>
char *spaces = " ";
FILE *logfile = NULL;
char *fn_log = "config.log";
void log_init(void)
{
if (fn_log != NULL) {
/* double open for truncate - for extreme portability, please do not "fix" */
logfile = fopen(fn_log, "w");
assert(logfile != NULL);
fclose(logfile);
logfile = fopen(fn_log, "a");
assert(logfile != NULL);
}
}
void log_uninit(void)
{
if (logfile != NULL)
fclose(logfile);
}
void logprintf(int depth, const char *format, ...)
{
va_list ap;
va_start(ap, format);
if (logfile != NULL) {
fprintf(logfile, "%s", logprefix(depth));
vfprintf(logfile, format, ap);
fflush(logfile);
}
va_end(ap);
}
void error(const char *format, ...)
{
va_list ap;
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
va_start(ap, format);
if (logfile != NULL) {
fprintf(logfile, "###error### ");
vfprintf(logfile, format, ap);
fflush(logfile);
}
va_end(ap);
}
void report(const char *format, ...)
{
va_list ap;
va_start(ap, format);
vprintf(format, ap);
fflush(stdout);
va_end(ap);
va_start(ap, format);
if (logfile != NULL) {
fprintf(logfile, "###report### ");
vfprintf(logfile, format, ap);
fflush(logfile);
}
va_end(ap);
}
void log_merge(int logdepth, const char *fn)
{
FILE *f;
char line[2048];
int lines;
if (logfile == NULL)
return;
f = fopen(fn, "r");
if (f == NULL) {
logprintf(logdepth, "scconfig error: couldn't open %s for merging.\n", fn);
return;
}
lines = 0;
while(!(feof(f))) {
*line = '\0';
fgets(line, sizeof(line), f);
if (*line != '\0') {
if (lines == 0)
logprintf(logdepth, "========= output dump start ============\n");
lines++;
logprintf(logdepth, "%s", line);
/* Make sure we have newline at the end of each line */
if (line[strlen(line)-1] != '\n')
logprintf(0, "\n");
}
}
if (lines == 0)
logprintf(logdepth, "========= empty stderr =================\n");
else
logprintf(logdepth, "========= output dump end ==============\n");
fclose(f);
}

View File

@ -1,332 +0,0 @@
/*
scconfig - library functions for compiling and running test code
Copyright (C) 2009 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include "log.h"
#include "libs.h"
#include "db.h"
#include "dep.h"
/*
#define KEEP_TEST_SRCS
*/
int cross_blind = 0;
static char *clone_flags(const char *input, const char *node)
{
char *output;
const char *s;
int len;
if (input != NULL) {
if (*input == '+') {
s = get(node);
if (s != NULL) {
len = strlen(s);
output = malloc(len + strlen(input) + 4);
memcpy(output, s, len);
output[len] = ' ';
strcpy(output + len + 1, input + 1);
}
else
output = strclone(input);
}
else
output = strclone(input);
}
else {
s = get(node);
if (s != NULL)
output = strclone(s);
else
output = strclone("");
}
return output;
}
int compile_file_raw(int logdepth, const char *fn_input, char **fn_output, const char *cc, const char *cflags, const char *ldflags)
{
char cmd[2048];
char *cc_esc, *fn_input_esc, *fn_output_esc, *temp_out_esc, *temp_out;
int ret;
temp_out = tempfile_new(".out");
if (*fn_output == NULL)
*fn_output = tempfile_new(get("sys/ext_exe"));
else
*fn_output = tempfile_new(*fn_output);
unlink(*fn_output);
cc_esc = shell_escape_dup(cc == NULL ? get("cc/cc") : cc);
fn_input_esc = shell_escape_dup(fn_input);
fn_output_esc = shell_escape_dup(*fn_output);
temp_out_esc = shell_escape_dup(temp_out);
sprintf(cmd, "%s \"%s %s %s %s -o %s 2>&1\" >%s", get("/host/sys/shell"), cc_esc, cflags, fn_input_esc, ldflags, fn_output_esc, temp_out_esc);
free(cc_esc);
free(fn_input_esc);
free(fn_output_esc);
free(temp_out_esc);
logprintf(logdepth, "compile: '%s'\n", cmd);
ret = system(cmd);
log_merge(logdepth + 1, temp_out);
#ifndef KEEP_TEST_SRCS
unlink(temp_out);
#endif
free(temp_out);
logprintf(logdepth, "compile result: %d\n", ret);
return ret;
}
int compile_file(int logdepth, const char *fn_input, char **fn_output, const char *cc, const char *cflags, const char *ldflags)
{
int ret;
char *ldflags_, *cflags_;
cflags_ = clone_flags(cflags, "cc/cflags");
ldflags_ = clone_flags(ldflags, "cc/ldflags");
ret = compile_file_raw(logdepth, fn_input, fn_output, cc, cflags_, ldflags_);
free(cflags_);
free(ldflags_);
return ret;
}
int compile_code(int logdepth, const char *testcode, char **fn_output, const char *cc, const char *cflags, const char *ldflags)
{
char *temp_in;
int ret;
require("sys/ext_exe", logdepth, 1);
assert(testcode != NULL);
assert(fn_output != NULL);
temp_in = tempfile_dump(testcode, ".c");
ret = compile_file(logdepth, temp_in, fn_output, cc, cflags, ldflags);
#ifndef KEEP_TEST_SRCS
unlink(temp_in);
#endif
free(temp_in);
return ret;
}
int compile_code_raw(int logdepth, const char *testcode, char **fn_output, const char *cc, const char *cflags, const char *ldflags)
{
char *temp_in;
int ret;
require("sys/ext_exe", logdepth, 1);
assert(testcode != NULL);
assert(fn_output != NULL);
temp_in = tempfile_dump(testcode, ".c");
ret = compile_file_raw(logdepth, temp_in, fn_output, cc, cflags, ldflags);
#ifndef KEEP_TEST_SRCS
unlink(temp_in);
#endif
free(temp_in);
return ret;
}
char *shell_escape_dup(const char *in)
{
char *o, *out;
const char *i;
const char *esc = get("sys/shell_escape_char");
/* in the early phase, before detecting the shell, this happens */
if (esc == NULL)
return strclone(in);
out = malloc(strlen(in)*2+1);
for(i = in, o = out; *i != '\0'; i++) {
if (*i == *esc) {
*o++ = *esc;
}
else if (!isalnum(*i)) {
switch(*i) {
case '/':
case '_':
case '-':
case '.':
break;
default:
*o++ = *esc;
}
}
*o++ = *i;
}
*o = '\0';
return out;
}
int run(int logdepth, const char *cmd_, char **stdout_saved)
{
char *cmd;
char *fn_out, *temp_out;
char *fn_out_esc, *temp_out_esc;
int ret;
const char *emu;
assert(cmd_ != NULL);
/* blind cross compiling mode means we always assume success */
if (cross_blind) {
if (stdout_saved != NULL)
*stdout_saved = NULL;
return 0;
}
emu = get("sys/emu");
/* emu == NULL means we need an emulator but we don't have one and
we should pretend everything went well (and of course can't provide
output.) */
if (emu == NULL) {
if (stdout_saved != NULL)
*stdout_saved = NULL;
return 0;
}
/* emu == false means we need an emulator and we don't want to pretend -> fatal */
if (strcmp(emu, sfalse) == 0) {
error("Trying to run unavailable emulator (db_cwd='%s')\n", db_cwd);
abort();
}
temp_out = tempfile_new(".out");
fn_out = tempfile_new("");
temp_out_esc = shell_escape_dup(temp_out);
fn_out_esc = shell_escape_dup(fn_out);
cmd = malloc(strlen(emu) + strlen(cmd_) + strlen(fn_out_esc) + strlen(temp_out_esc) + 32);
sprintf(cmd, "%s %s >%s 2>>%s", emu, cmd_, fn_out_esc, temp_out_esc);
free(temp_out_esc);
free(fn_out_esc);
logprintf(logdepth, "run: '%s'\n", cmd);
ret = system(cmd);
log_merge(logdepth + 1, temp_out);
unlink(temp_out);
free(temp_out);
logprintf(logdepth, "run result: %d\n", ret);
free(cmd);
if (stdout_saved != NULL) {
if (ret == 0) {
*stdout_saved = load_file(fn_out);
logprintf(logdepth, "stdout: '%s'\n", *stdout_saved);
}
else
*stdout_saved = NULL;
}
unlink(fn_out);
free(fn_out);
return ret;
}
int run_shell(int logdepth, const char *cmd_, char **stdout_saved)
{
int ret;
char *cmd, *cmd_esc;
const char *emu;
const char *shell;
emu = get("sys/emulator");
if (emu == NULL)
emu = "";
shell = get("sys/shell");
if (shell == NULL) {
error("No shell was specified (db_cwd='%s')\n", db_cwd);
abort();
}
cmd_esc = shell_escape_dup(cmd_);
cmd = malloc(strlen(emu) + strlen(shell) + strlen(cmd_esc) + 16);
if (istrue(get("sys/shell_needs_quote")))
sprintf(cmd, "%s %s \"%s\"", emu, shell, cmd_);
else
sprintf(cmd, "%s %s %s", emu, shell, cmd_);
free(cmd_esc);
ret = run(logdepth, cmd, stdout_saved);
free(cmd);
return ret;
}
int compile_run(int logdepth, const char *testcode, const char *cc, const char *cflags, const char *ldflags, char **stdout_saved)
{
int ret;
char *fn_output = NULL;
ret = compile_code(logdepth+1, testcode, &fn_output, cc, cflags, ldflags);
if (ret == 0) {
char *fn_output_esc = shell_escape_dup(fn_output);
ret = run(logdepth+1, fn_output_esc, stdout_saved);
free(fn_output_esc);
}
if (fn_output != NULL) {
unlink(fn_output);
free(fn_output);
}
return ret;
}
int run_script(int logdepth, const char *interpreter, const char *script, const char *suffix, char **out)
{
char *temp, *cmd;
int res;
temp = tempfile_dump(script, suffix);
cmd = malloc(strlen(temp) + strlen(interpreter) + 4);
sprintf(cmd, "%s %s", interpreter, temp);
res = run(logdepth, cmd, out);
unlink(temp);
free(temp);
free(cmd);
return res;
}

View File

@ -1,173 +0,0 @@
/* cc */
int find_cc(const char *name, int logdepth, int fatal);
int find_cc_argstd(const char *name, int logdepth, int fatal);
int find_cc_argmachine(const char *name, int logdepth, int fatal);
int find_cc_fpie(const char *name, int logdepth, int fatal);
int find_cc_fnopie(const char *name, int logdepth, int fatal);
int find_cc_fnopic(const char *name, int logdepth, int fatal);
int find_inline(const char *name, int logdepth, int fatal);
int find_varargmacro(const char *name, int logdepth, int fatal);
int find_funcmacro(const char *name, int logdepth, int fatal);
int find_constructor(const char *name, int logdepth, int fatal);
int find_destructor(const char *name, int logdepth, int fatal);
int find_fattr_unused(const char *name, int logdepth, int fatal);
int find_declspec_dllimport(const char *name, int logdepth, int fatal);
int find_declspec_dllexport(const char *name, int logdepth, int fatal);
int find_rdynamic(const char *name, int logdepth, int fatal);
int find_soname(const char *name, int logdepth, int fatal);
int find_so_undefined(const char *name, int logdepth, int fatal);
int find_wlrpath(const char *name, int logdepth, int fatal);
int find_cc_wloutimplib(const char *name, int logdepth, int fatal);
int find_cc_wloutputdef(const char *name, int logdepth, int fatal);
int find_fpic(const char *name, int logdepth, int fatal);
int find_ldflags_dynlib(const char *name, int logdepth, int fatal);
int find_ldflags_dll(const char *name, int logdepth, int fatal);
int find_ldflags_so(const char *name, int logdepth, int fatal);
int find_alloca(const char *name, int logdepth, int fatal);
int find__exit(const char *name, int logdepth, int fatal);
int find_cc_pragma_message(const char *name, int logdepth, int fatal);
int find_cc_static_libgcc(const char *name, int logdepth, int fatal);
/* libs */
int find_lib_ldl(const char *name, int logdepth, int fatal);
int find_lib_LoadLibrary(const char *name, int logdepth, int fatal);
int find_lib_errno(const char *name, int logdepth, int fatal);
/* thread */
int find_lib_lpthread(const char *name, int logdepth, int fatal);
int find_thread_semget(const char *name, int logdepth, int fatal);
int find_thread_pthread_create(const char *name, int logdepth, int fatal);
int find_thread_CreateSemaphore(const char *name, int logdepth, int fatal);
int find_thread_CreateThread(const char *name, int logdepth, int fatal);
/* fscalls */
int find_fs_realpath(const char *name, int logdepth, int fatal);
int find_fs__fullpath(const char *name, int logdepth, int fatal);
int find_fs_readdir(const char *name, int logdepth, int fatal);
int find_fs_findnextfile(const char *name, int logdepth, int fatal);
int find_fs_access(const char *name, int logdepth, int fatal);
int find_fs_access_macros(const char *name, int logdepth, int fatal);
int find_fs_stat_macros(const char *name, int logdepth, int fatal);
int find_fs_stat_fields(const char *name, int logdepth, int fatal);
int find_fs_lstat(const char *name, int logdepth, int fatal);
int find_fs_statlstat(const char *name, int logdepth, int fatal);
int find_fs_getcwd(const char *name, int logdepth, int fatal);
int find_fs__getcwd(const char *name, int logdepth, int fatal);
int find_fs_getwd(const char *name, int logdepth, int fatal);
int find_fs_mkdir(const char *name, int logdepth, int fatal);
int find_fs__mkdir(const char *name, int logdepth, int fatal);
int find_fs_mkdtemp(const char *name, int logdepth, int fatal);
int find_fs_mmap(const char *name, int logdepth, int fatal);
int find_fsmount_next_dev(const char *name, int logdepth, int fatal);
int find_fsmount_fsstat_fields(const char *name, int logdepth, int fatal);
int find_fsmount_statfs_fields(const char *name, int logdepth, int fatal);
int find_fsmount_statvfs_fields(const char *name, int logdepth, int fatal);
int find_fs_ustat(const char *name, int logdepth, int fatal);
int find_fs_statfs(const char *name, int logdepth, int fatal);
int find_fs_statvfs(const char *name, int logdepth, int fatal);
int find_fs_flock(const char *name, int logdepth, int fatal);
int find_fs_makedev(const char *name, int logdepth, int fatal);
/* printf */
int find_printf_x(const char *name, int logdepth, int fatal);
int find_printf_ptrcast(const char *name, int logdepth, int fatal);
int find_snprintf(const char *name, int logdepth, int fatal);
int find_dprintf(const char *name, int logdepth, int fatal);
int find_vdprintf(const char *name, int logdepth, int fatal);
int find_vsnprintf(const char *name, int logdepth, int fatal);
/* proc */
int find_proc__spawnvp(const char *name, int logdepth, int fatal);
int find_proc_fork(const char *name, int logdepth, int fatal);
int find_proc_wait(const char *name, int logdepth, int fatal);
int find_proc__getpid(const char *name, int logdepth, int fatal);
int find_proc_CreateProcessA(const char *name, int logdepth, int fatal);
int find_proc_getexecname(const char *name, int logdepth, int fatal);
int find_proc_GetModuleFileNameA(const char *name, int logdepth, int fatal);
int find_proc_shmget(const char *name, int logdepth, int fatal);
int find_proc_CreateFileMappingA(const char *name, int logdepth, int fatal);
/* fstools */
int find_fstools_cp(const char *name, int logdepth, int fatal);
int find_fstools_ln(const char *name, int logdepth, int fatal);
int find_fstools_mv(const char *name, int logdepth, int fatal);
int find_fstools_rm(const char *name, int logdepth, int fatal);
int find_fstools_mkdir(const char *name, int logdepth, int fatal);
int find_fstools_ar(const char *name, int logdepth, int fatal);
int find_fstools_ranlib(const char *name, int logdepth, int fatal);
int find_fstools_awk(const char *name, int logdepth, int fatal);
int find_fstools_cat(const char *name, int logdepth, int fatal);
int find_fstools_sed(const char *name, int logdepth, int fatal);
int find_fstools_file(const char *name, int logdepth, int fatal);
int find_fstools_file_l(const char *name, int logdepth, int fatal);
int find_fstools_chmodx(const char *name, int logdepth, int fatal);
/* uname */
int find_uname(const char *name, int logdepth, int fatal);
int find_triplet(const char *name, int logdepth, int fatal);
int find_sysid(const char *name, int logdepth, int fatal);
/* find_target */
int find_target(const char *name, int logdepth, int fatal);
/* filelist */
int find_filelist(const char *name, int logdepth, int fatal);
/* find_str.c */
int find_strcasecmp(const char *name, int logdepth, int fatal);
int find_strncasecmp(const char *name, int logdepth, int fatal);
int find_stricmp(const char *name, int logdepth, int fatal);
int find_strnicmp(const char *name, int logdepth, int fatal);
/* find_sys.c */
int find_sys_ptrwidth(const char *name, int logdepth, int fatal);
int find_sys_byte_order(const char *name, int logdepth, int fatal);
int find_tmp(const char *name, int logdepth, int fatal);
int find_shell(const char *name, int logdepth, int fatal);
/* find_io.c */
int find_io_pipe(const char *name, int logdepth, int fatal);
int find_io_dup2(const char *name, int logdepth, int fatal);
int find_io_fileno(const char *name, int logdepth, int fatal);
int find_io_lseek(const char *name, int logdepth, int fatal);
int find_io_popen(const char *name, int logdepth, int fatal);
/* find_time.c */
int find_time_usleep(const char *name, int logdepth, int fatal);
int find_time_Sleep(const char *name, int logdepth, int fatal);
int find_time_gettimeofday(const char *name, int logdepth, int fatal);
int find_time_ftime(const char *name, int logdepth, int fatal);
int find_time_timegm(const char *name, int logdepth, int fatal);
int find_time_mkgmtime(const char *name, int logdepth, int fatal);
int find_time_gmtime_s(const char *name, int logdepth, int fatal);
int find_time_gmtime_r(const char *name, int logdepth, int fatal);
int find_time_localtime_s(const char *name, int logdepth, int fatal);
int find_time_localtime_r(const char *name, int logdepth, int fatal);
/* find_types.c */
int find_types_stdint(const char *name, int logdepth, int fatal);
int find_types_sizes(const char *name, int logdepth, int fatal);
int find_types_size_t(const char *name, int logdepth, int fatal);
int find_types_off_t(const char *name, int logdepth, int fatal);
int find_types_off64_t(const char *name, int logdepth, int fatal);
int find_types_gid_t(const char *name, int logdepth, int fatal);
int find_types_uid_t(const char *name, int logdepth, int fatal);
int find_types_pid_t(const char *name, int logdepth, int fatal);
int find_types_dev_t(const char *name, int logdepth, int fatal);
int find_types_dev_t(const char *name, int logdepth, int fatal);
int find_types_mode_t(const char *name, int logdepth, int fatal);
int find_types_nlink_t(const char *name, int logdepth, int fatal);
int find_types_ptrdiff_t(const char *name, int logdepth, int fatal);
int find_types_dev_t(const char *name, int logdepth, int fatal);
int find_types_ino_t(const char *name, int logdepth, int fatal);
int find_types_void_ptr(const char *name, int logdepth, int fatal);
/* find_signal.c */
int find_signal_names(const char *name, int logdepth, int fatal);
int find_signal_raise(const char *name, int logdepth, int fatal);
/* environ.c */
int find_main_arg3(const char *name, int logdepth, int fatal);
int find_putenv(const char *name, int logdepth, int fatal);
int find_setenv(const char *name, int logdepth, int fatal);
int find_environ(const char *name, int logdepth, int fatal);

View File

@ -1,58 +0,0 @@
/*
scconfig - glue layer for proper crosscompiling to target
Copyright (C) 2009 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include "db.h"
#include "libs.h"
int find_target(const char *name, int logdepth, int fatal)
{
const char *target = get("/arg/sys/target");
const char *emu = get("/arg/sys/emu");
(void) logdepth; /* to suppress compiler warnings about not using logdepth */
(void) fatal; /* to suppress compiler warnings about not using fatal */
/* Does target differ from host? */
if (target == NULL) {
db_link("/host", "/target");
#ifdef RUNTIME
db_link("/host", "/runtime");
#endif
put("/target/sys/cross", sfalse);
put("/target/sys/cross_blind", sfalse);
return 0;
}
else
db_mkdir("/target");
put("/target/sys/target", target);
put("/target/sys/cross", strue);
if (emu != NULL)
put("/target/sys/emu", emu);
/* If so, check if emulator is provided */
cross_blind = ((emu == NULL) || (*emu == '\0'));
put("/target/sys/cross_blind", cross_blind ? strue : sfalse);
return 0;
}

View File

@ -1,355 +0,0 @@
/*
scconfig - evaluate uname and classify the system
Copyright (C) 2009 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "regex.h"
#include "log.h"
#include "db.h"
#include "libs.h"
#include "dep.h"
static void sys_unix(void)
{
put("sys/ext_exe", "");
put("sys/ext_dynlib", ".so");
put("sys/ext_stalib", ".a");
put("sys/ext_dynlib_native", ".so");
}
static void sys_netbsd(void)
{
sys_unix();
put("cc/ldflags", "-Wl,-R/usr/pkg/lib -L/usr/pkg/lib"); /* TODO: is this the best way? */
}
static void sys_win32dlc(void)
{
put("sys/ext_exe", ".exe");
put("sys/ext_dynlib", ".dlc");
put("sys/ext_stalib", ".a");
put("sys/ext_dynlib_native", ".dll");
}
typedef void (*callback_t)(void);
typedef struct {
char *uname_regex;
char *name;
char *class;
callback_t callback;
} uname_t;
typedef struct {
char *file_name;
char *name;
char *class;
callback_t callback;
} magic_file_t;
/* Guess system class by uname; class is informative, nothing important
should depend on it.
Order *does* matter */
uname_t unames[] = {
{"[Nn]et[Bb][Ss][Dd]", "NetBSD", "UNIX", sys_netbsd},
{"[Ll]inux", "Linux", "UNIX", sys_unix},
{"[Bb][Ss][Dd]", "BSD", "UNIX", sys_unix},
{"SunOS", "SunOS", "UNIX", sys_unix},
{"OSF1", "OSF", "UNIX", sys_unix}, /* TODO: note the difference in cflags for debugging ("-ms -g") */
{"IRIX", "IRIX", "UNIX", sys_unix},
{"SunOS", "SunOS", "UNIX", sys_unix},
{"[Mm]inix", "Minix", "UNIX", sys_unix},
{"[Aa][Rr][Oo][Ss]", "Aros", "UNIX", sys_unix},
{"^Darwin", "MacOSX", "UNIX", sys_unix},
{"[Th]hreos", "Threos", "UNIX", sys_unix},
{"[Cc]ygwin", "cygwin", "WIN32", sys_win32dlc},
{"[Mm][Ii][Nn][Gg][Ww]", "mingw", "WIN32", sys_win32dlc},
{"win32", "win32", "WIN32", sys_win32dlc}, /* vanilla windows */
{NULL, NULL, NULL, NULL}
};
/* Fallback: extract machine name from uname -a if uname -m fails */
static const char *machine_names[] = {
"i[0-9]86[^ ]*", "x86_[^ ]*", "amd[0-9]*", "armv[0-9][^ ]*", "ppc[0-9]+",
"sparc[0-9]*", "BePC", "ia64", "x86", "IP[0-9]*", "k1om", "sun4u",
"RM600", "R4000", "alpha",
NULL
};
/* Fallback: extract system name from uname -a if uname -s fails */
static const char *system_names[] = {
"[Ll]inux", "sn5[0-9]*", "CYGWIN_NT[^ ]*", "GNU[^ ]*", "DragonFly",
"[^ ]*BSD[^ ]*", "Haiku", "HP-UX", "AIX", "OS4000", "Interix",
"IRIX[0-9]*", "Darwin", "Minix", "MINGW[^ ]*", "ReliantUNIX[^ ]*",
"SunOS", "OSF1", "ULTRIX", "UWIN-W7", "IS/WB", "OS/390",
"SCO[^ ]*", "QNX",
NULL
};
/* Fallback: if uname -a fails, guess system by looking at "magic file names" */
magic_file_t magic_files[] = {
{"/dev/null", "UNIX", "UNIX", sys_unix},
{"c:\\config.sys", "win32", "WIN32", sys_win32dlc},
{"c:\\windows\\system.ini", "win32", "WIN32", sys_win32dlc},
{"c:\\windows\\win.ini", "win32", "WIN32", sys_win32dlc},
{"c:\\windows\\notepad.exe", "win32", "WIN32", sys_win32dlc},
{NULL, NULL, NULL, NULL}
} ;
static int match(const char *regex, const char *str)
{
re_comp(regex);
return re_exec(str);
}
/* match uname against each pattern on the list; on a match, put() the portion
of the string matched in node and return 1 */
int uname_guess(const char *node, const char *uname, const char *list[])
{
const char **l;
if (uname == NULL)
return 0;
for(l = list; *l != NULL; l++) {
if (match(*l, uname)) {
char *s;
int len = eopat[0] - bopat[0];
s = malloc(len+1);
memcpy(s, bopat[0], len);
s[len] = '\0';
put(node, s);
return 1;
}
}
return 0;
}
/* Don't worry about linear search or matching regexes all the time - this
function will be run at most two times */
static callback_t lookup_uname(char **uname, const char **name, const char **class)
{
uname_t *u;
for(u = unames; u->uname_regex != NULL; u++) {
if (
((*uname != NULL) && (match(u->uname_regex, *uname))) /* uname match */
|| ((*name != NULL) && ((strcmp(u->name, *name) == 0))) /* name match */
|| ((*class != NULL) && ((strcmp(u->class, *class) == 0))) /* class match */
) {
if (*name == NULL) *name = u->name;
if (*class == NULL) *class = u->class;
return u->callback;
}
}
return NULL;
}
static callback_t lookup_magic_file(int logdepth, const char **name, const char **class)
{
magic_file_t *u;
for(u = magic_files; u->file_name != NULL; u++) {
if (is_file(u->file_name)) {
logprintf(logdepth, "%s -> %s\n", u->file_name, u->class);
if (*name == NULL) *name = u->name;
if (*class == NULL) *class = u->class;
return u->callback;
}
}
return NULL;
}
int find_uname(const char *rname, int logdepth, int fatal)
{
const char *name, *class, *tname, *uname_orig;
char *s, *uname, *mname, *sname;
void (*callback)(void);
require("sys/tmp", logdepth, fatal);
if (istarget(db_cwd))
require("/target/sys/target", logdepth, fatal);
report("Checking for system type... ");
logprintf(logdepth, "[find_uname] checking for sys/name\n");
logdepth++;
tname = get("/arg/sys/target-name");
if (istarget(db_cwd) && (tname != NULL))
put("sys/name", tname);
tname = get("/arg/sys/target-uname");
if (istarget(db_cwd) && (tname != NULL))
put("sys/uname", tname);
name = get("sys/name");
uname_orig = get("sys/uname");
if (name == NULL) {
if (uname_orig == NULL) {
logprintf(logdepth, "not set, running\n");
run_shell(logdepth, "uname -a", (char **)&uname);
if (uname != NULL) {
for(s = uname; *s != '\0'; s++)
if ((*s == '\n') || (*s == '\r')) *s = ' ';
put("sys/uname", uname);
}
else
put("sys/uname", "");
if (run_shell(logdepth, "uname -m", (char **)&mname) == 0)
put("sys/machine_name", strip(mname));
else
put("sys/machine_name", NULL);
if (mname != NULL)
free(mname);
if (run_shell(logdepth, "uname -o", (char **)&sname) == 0)
put("sys/system_name", strip(sname));
else if (run_shell(logdepth, "uname -s", (char **)&sname) == 0)
put("sys/system_name", strip(sname));
else
put("sys/system_name", NULL);
if (sname != NULL)
free(sname);
}
/* we have uname by now, set sys/name */
name = NULL;
class = NULL;
callback = lookup_uname(&uname, &name, &class);
if (name == NULL) {
/* no uname or unknown system by uname - fallback: check for cross target */
const char *target = get("/arg/sys/target");
if ((target != NULL) && (strstr(target, "mingw") != NULL)) {
name = "WIN32";
report("(detected mingw cross compilation to WIN32)\n");
}
else {
report("Warning: unknown system\n");
name = "unknown";
}
}
put("sys/name", name);
}
else {
/* we had sys/name, that should be enough */
uname = NULL;
class = name;
callback = lookup_uname(&uname, &name, &class);
}
/* predefined and/or detected uname failed, try magic file method */
if (callback == NULL) {
logprintf(logdepth, "System class is unknown by uname, running heuristics...\n");
report("System class is unknown by uname, running heuristics... ");
callback = lookup_magic_file(logdepth + 1, &name, &class);
}
if (callback == NULL) {
/* System unknown. */
error("Unknown system '%s'\n", get("sys/uname"));
abort();
}
callback();
report("OK (name: %s; class: %s)\n", name, class);
put("sys/class", class);
/* fallbacks */
if (get("sys/machine_name") == NULL)
uname_guess("sys/machine_name", uname, machine_names);
if (get("sys/system_name") == NULL)
uname_guess("sys/system_name", uname, system_names);
/* on windows, overwrite the path sep with the right amount of \ (the tmp finder may have left / in it) */
if (strcmp(class, "WIN32") == 0) {
int eats = istrue(get("sys/shell_eats_backslash"));
if (eats)
put("sys/path_sep", "\\\\\\\\");
else
put("sys/path_sep", "\\");
}
return 0;
}
static int find_triplet_(const char *name, int logdepth, int fatal, const char *nodename, int include_vendor, char *sep, char *esc)
{
const char *machine, *vendor, *os;
char *triplet, *s;
char fake_sep[2];
fake_sep[0] = 1;
fake_sep[1] = 0;
require("sys/uname", logdepth, fatal);
machine = get("sys/machine_name");
if (machine == NULL)
machine = "unknown";
vendor = "unknown";
os = get("sys/system_name");
if (os == NULL)
os = "unknown";
if (include_vendor)
triplet = str_concat(fake_sep, machine, vendor, os, NULL);
else
triplet = str_concat(fake_sep, machine, os, NULL);
for(s = triplet; *s != '\0'; s++) {
if ((esc != NULL) && (*s == *sep))
*s = *esc;
if (isalnum(*s))
*s = tolower(*s);
else {
if (*s == *fake_sep)
*s = *sep;
else if (esc != NULL)
*s = *esc;
else
*s = '-';
}
}
put(nodename, triplet);
free(triplet);
return 0;
}
int find_triplet(const char *name, int logdepth, int fatal)
{
return find_triplet_(name, logdepth, fatal, "sys/triplet", 1, "-", NULL);
}
int find_sysid(const char *name, int logdepth, int fatal)
{
return find_triplet_(name, logdepth, fatal, "sys/sysid", 0, "-", "_");
}

View File

@ -1,33 +0,0 @@
/* Runs when a custom command line argument is found
returns true if no further argument processing should be done */
int hook_custom_arg(const char *key, const char *value);
/* If any of the int hooks return non-zero, that means failure and stops
the whole process */
/* Runs before anything else */
int hook_preinit(void);
/* Runs after initialization */
int hook_postinit(void);
/* Runs after all arguments are read and parsed */
int hook_postarg(void);
/* Runs when things should be detected for the host system (tools compiled for and/or run on compilation host) */
int hook_detect_host(void);
/* Runs when things should be detected for the target system (tools compiled on the compilation host but running on the target)*/
int hook_detect_target(void);
/* Runs when things should be detected for the runtime system (tools that will run only on the target, production runtime, not during compilation or installation) */
int hook_detect_runtime(void);
/* Runs after detection hooks, should generate the output (Makefiles, etc.) */
int hook_generate(void);
/* Runs before everything is uninitialized */
void hook_preuninit(void);
/* Runs at the very end, when everything is already uninitialized */
void hook_postuninit(void);

View File

@ -1,19 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#define max_spaces 64
extern char *spaces;
#define logprefix(n) (((n) > max_spaces) ? spaces : (spaces+max_spaces-(n)))
void logprintf(int depth, const char *format, ...);
void error(const char *format, ...);
void report(const char *format, ...);
void log_merge(int logdepth, const char *fn);
extern FILE *logfile;
extern void log_init(void);
void log_uninit(void);
extern char *fn_log;

View File

@ -1,24 +0,0 @@
#include "ht.h"
int is_dep_known(const char *name);
int require(const char *name, int logdepth, int fatal);
const char *dep_add(const char *name, int (*finder)(const char *name, int logdepth, int fatal));
void require_all(int fatal);
/* Returns if dependency is a wildcard one (ending in / *) */
int is_dep_wild(const char *path);
/* Almost 'basename': returns the last portion of the path, which may
be '*'. Returns "<unknown>" on error. */
const char *det_list_target(const char *path);
/* Returns 1 if the user asked for detecting a feature; needtodo is
the first argument passed to the detection function (the target the caller
wants to get detected), cando is the output path of the test that the
detector could do next. */
int asked_for(const char *cando, const char *needtodo);
/* for internal use */
void dep_init(void);
void dep_uninit(void);

View File

@ -1,25 +0,0 @@
#ifndef SCC_ARG_H
#define SCC_ARG_H
#include <stdio.h>
typedef struct {
char *arg;
char *path;
int (*callback)(const char *key, const char *value);
char *help;
} argtbl_t;
extern argtbl_t main_argument_table[];
void process_args(int argc, char *argv[]);
void help_default_args(FILE *f, const char *prefix);
/* main.c: */
extern int custom_arg(const char *key, const char *value);
extern int num_custom_reqs;
#endif

View File

@ -1,22 +0,0 @@
#ifndef SCC_ARG_H
#define SCC_ARG_H
typedef struct {
char *arg;
char *path;
int (*callback)(const char *key, const char *value);
char *help;
} argtbl_t;
extern argtbl_t main_argument_table[];
void process_args(int argc, char *argv[]);
/* main.c: */
extern int custom_arg(const char *key, const char *value);
extern int num_custom_reqs;
#endif

View File

@ -1,77 +0,0 @@
/*
scconfig - library to explore the source tree
Copyright (C) 2015 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "db.h"
#include "libs.h"
#include "log.h"
#include "dep.h"
char *svn_info(int logdepth, const char *dir, const char *key)
{
char *cmd, *stdo = NULL;
char *res = NULL;
int keylen = strlen(key);
cmd = str_concat(" ", "svn info", dir, NULL);
if (run_shell(logdepth, cmd, &stdo) == 0) {
char *line, *nline;
/* check key against each line */
for(line = stdo; line != NULL; line = nline) {
/* split line */
nline = strpbrk(line, "\r\n");
if (nline != NULL) {
*nline = '\0';
nline++;
while((*nline == '\n') || (*nline == '\r')) nline++;
}
/* compare key */
if (strncmp(line, key, keylen) == 0) {
char *val;
/* extract value */
val = strchr(line, ':');
if (val != NULL) {
val++;
while((*val == ' ') || (*val == '\t')) val++;
}
else
val = line;
/* produce output */
res = strclone(val);
goto found;
}
}
}
found:;
if (stdo != NULL)
free(stdo);
free(cmd);
return res;
}

View File

@ -1,491 +0,0 @@
/*
scconfig - detect features of the system or the host/target computer
Copyright (C) 2009..2012 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
int find_sys_ptrwidth(const char *name, int logdepth, int fatal)
{
char *end, W[32];
char *out = NULL;
int w;
char *test_c =
NL "#include <stdio.h>"
NL "int main() {"
NL " void *ptr;"
NL " printf(\"%d\\n\", sizeof(ptr));"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for pointer width... ");
logprintf(logdepth, "find_sys_ptrwidth: trying to find pointer width...\n");
logdepth++;
if (compile_run(logdepth, test_c, NULL, NULL, NULL, &out) == 0) {
w = strtol(out, &end, 10);
if ((*end != '\0') && (*end != '\n') && (*end != '\r')) {
report("FAILED (test code failed)\n");
logprintf(logdepth+1, "FAILED: returned '%s' which is not a valid decimal number (at '%s')\n", out, end);
return 1;
}
sprintf(W, "%d", w * 8);
report("OK (%s bits)\n", W);
put("sys/ptrwidth", W);
logprintf(logdepth+1, "OK (%s bits)\n", W);
}
return 0;
}
int find_sys_byte_order(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <stdio.h>"
NL "int main() {"
NL " long int i = 8;"
NL " char *s = (char *)&i;"
NL " printf(\"%d\\n\", s[0]);"
NL " return 0;"
NL "}"
NL;
const char* test_c_blind_template =
NL "#include <stdio.h>"
NL "#include <endian.h>"
NL "#ifndef __BYTE_ORDER"
NL "#error \"ERROR 1\""
NL "void void *;"
NL "#endif"
NL "#ifndef __%s_ENDIAN"
NL "#error \"ERROR 2\""
NL "char char *;"
NL "#endif"
NL "#if __BYTE_ORDER != __%s_ENDIAN"
NL "#error \"ERROR 3\""
NL "int int *;"
NL "#endif"
NL "int main() {"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char *key = "sys/byte_order";
const char *endians1[] = { "LITTLE", "BIG", NULL };
const char *endians2[] = { "LSB", "MSB", NULL };
int index;
char test_c_blind[1024];
char *end;
const char *W;
char *out = NULL;
int w;
require("cc/cc", logdepth, fatal);
report("Checking for byte order... ");
logprintf(logdepth, "find_sys_byte_order: trying to find byte order...\n");
logdepth++;
if ((!isblind(db_cwd)) && compile_run(logdepth, test_c, NULL, NULL, NULL, &out) == 0) {
w = strtol(out, &end, 10);
if (((*end != '\0') && (*end != '\n') && (*end != '\r')) || ((w != 0) && (w != 8))) {
report("FAILED (test code failed)\n");
logprintf(logdepth+1, "FAILED: returned '%s' which is not a valid decimal number (at '%s')\n", out, end);
return 1;
}
if (w == 0)
W = "MSB";
else
W = "LSB";
report("OK (%s first)\n", W);
put("sys/byte_order", W);
logprintf(logdepth+1, "OK (%s first)\n", W);
return 0;
}
for (index=0; endians1[index]!=NULL; ++index)
{
sprintf(test_c_blind, test_c_blind_template, endians1[index], endians1[index]);
if (compile_run(logdepth, test_c_blind, NULL, NULL, NULL, NULL) == 0)
{
W = endians2[index];
report("OK (%s first)\n", W);
put(key, W);
return 0;
}
}
report("FAILED (cannot determine byte order, you must supply it)\n");
return try_fail(logdepth, key);
}
static int test_shell_eats_backslash(int logdepth)
{
char *test = "echo c:\\n";
char *out;
logprintf(logdepth, "testing if shell eats \\...\n");
run_shell(logdepth+1, test, &out);
if (out == NULL) {
logprintf(logdepth+1, "oops, couldn't run shell?! (returned NULL)\n");
report("ERROR: shell fails.");
abort();
}
if (out[2] == '\\') {
logprintf(logdepth, "shell does NOT eat \\...\n");
put("sys/shell_eats_backslash", sfalse);
free(out);
return 0;
}
free(out);
logprintf(logdepth, "shell eats \\...\n");
put("sys/shell_eats_backslash", strue);
return 1;
}
static int try_get_cwd(int logdepth, const char *cmd)
{
char *cwd, *end;
run_shell(logdepth+1, cmd, &cwd);
if (cwd != NULL) {
end = strpbrk(cwd, "\r\n");
if (end != NULL)
*end = '\0';
if (*cwd != '\0') {
end = cwd + strlen(cwd) - 1;
while((*end == ' ') || (*end == '\t')) { *end = '\0'; end--; }
put("sys/tmp", cwd);
/* ugly hack for win32: paths there start as c:\ */
if ((cwd[1] == ':') && (cwd[2] == '\\'))
append("sys/tmp", "\\");
else
append("sys/tmp", "/");
logprintf(logdepth, "cwd is '%s'\n", get("sys/tmp"));
free(cwd);
return 1;
}
else
free(cwd);
}
return 0;
}
static int try_tmp(int logdepth)
{
char *fn;
logprintf(logdepth, "validating temp dir '%s'\n", get("sys/tmp"));
fn = tempfile_new_noabort("");
if (fn != NULL) {
unlink(fn);
free(fn);
logprintf(logdepth, "temp dir works!\n");
return 1;
}
logprintf(logdepth, "temp dir fails\n");
return 0;
}
/* test temp dir with all sort of workarounds */
static int try_tmp_all(int logdepth)
{
const char *tmp, *si;
char c;
char *t, *so, *old_tmp;
int eats, n;
tmp = get("sys/tmp");
/* path must end in path separator */
c = tmp[strlen(tmp)-1];
if ((c != '/') && (c != '\\')) {
append("sys/tmp", "/");
tmp = get("sys/tmp");
}
logprintf(logdepth, "trying detected temp dir '%s'\n", tmp);
if (try_tmp(logdepth+1)) return 1;
/* try msys-on-windows hack: if path starts with /d/something, try d:/ instead */
if ((tmp[0] == '/') && (isalpha(tmp[1])) && (tmp[2] == '/')) {
/* for the next test we shouldn't use our half-detected tmp path but go with . */
old_tmp = strclone(tmp);
put("sys/tmp", "");
eats = istrue(get("sys/shell_eats_backslash"));
tmp = old_tmp;
logprintf(logdepth, "tmp2='%s' eats=%d\n", tmp, eats);
t = malloc(strlen(tmp) * 2);
t[0] = tmp[1];
t[1] = ':';
for(si = tmp + 2, so = t + 2; *si != '\0'; si++, so++) {
if (*si == '/') {
*so = '\\';
if (eats) {
for(n = 0; n < 3; n++) {
so++;
*so = '\\';
}
}
}
else
*so = *si;
}
*so = '\0';
free(old_tmp);
logprintf(logdepth, "trying windows fix: '%s'\n", t);
put("sys/tmp", t);
free(t);
if (try_tmp(logdepth+1)) {
if (eats)
put("sys/path_sep", "\\\\\\\\");
else
put("sys/path_sep", "\\");
return 1;
}
tmp = get("sys/tmp");
}
/* fail. Set back tmp to empty so next command has a chance to run */
put("sys/tmp", "");
return 0;
}
int find_tmp(const char *name, int logdepth, int fatal)
{
const char *usertmp;
if (in_cross_target) {
report("Temp dir for cross compilation target is the same as for host...");
logprintf(logdepth, "Copying temp dir from host to target\n");
require("/host/sys/tmp", logdepth, fatal);
usertmp = get("/host/sys/tmp");
if (usertmp == NULL) {
report("Host temp dir not found.\n");
logprintf(logdepth, "Host temp dir not found.\n");
return 1;
}
put("sys/tmp", usertmp);
return 0;
}
/* we need shell for later tests; do this detection in . */
put("sys/tmp", "");
require("sys/shell", logdepth, fatal);
put("sys/path_sep", "/");
report("Detecting temp dir...");
logprintf(logdepth, "Finding temp dir (current working directory)...\n");
usertmp = get("/arg/sys/tmp");
/* . as tmp would fail for commands including a "cd" - this would cause
temporary files left in the target dir. We start out with empty
string (which is ., but on windows ./ would fail), and run
pwd (without cd) to find out the current directory (as getcwd() is not
portable). If pwd fails, we stay with ./ */
put("sys/tmp", "");
/* we need to know about shell backslash problem regardless of how
we end up with tmp - currently tmp is ., where the test could run
safely */
test_shell_eats_backslash(logdepth+1);
/* Special case: cross-compilation with emulator; we can not assume
the emulator uses the same paths as the host system, while we mix
accessing files from host and emu. If we stay in ., both emulator
and host system should be (more or less) happy. */
if (istarget(db_cwd) && iscross) {
if (usertmp == NULL) {
report("using temp dir . for cross-compilation\n");
logprintf(logdepth, "staying with . for cross-compilation\n");
}
else {
put("sys/tmp", usertmp);
report("using user supplied temp dir '%s' for cross-compilation\n", usertmp);
logprintf(logdepth, "using user supplied temp dir '%s' for cross-compilation\n", usertmp);
}
return 0;
}
if ((usertmp != NULL))
put("sys/tmp", usertmp);
if (
((usertmp != NULL) && (try_tmp_all(logdepth+2))) || /* try user supplied temp dir */
((try_get_cwd(logdepth+1, "pwd")) && (try_tmp_all(logdepth+2))) || /* try pwd for finding out cwd */
((try_get_cwd(logdepth+1, "echo %cd%") && (try_tmp_all(logdepth+2))))) { /* try windows-specific way for finding out cwd */
report(" validated %s\n", get("sys/tmp"));
logprintf(logdepth, "Detected temp dir '%s'\n", get("sys/tmp"));
return 0;
}
put("sys/tmp", "");
report("using temp dir fallback .\n");
logprintf(logdepth, "all temp directories failed, using . as tmp\n");
return 0;
}
int test_shell(const char *shell, int logdepth, int quote)
{
char *test = "echo hello";
char *cmd;
char *out;
char *q;
if (quote)
q = "\"";
else
q = "";
logprintf(logdepth, "testing '%s' as shell\n", shell);
cmd = malloc(strlen(test) + strlen(shell) + 8);
sprintf(cmd, "%s %s%s%s", shell, q, test, q);
run(logdepth+1, cmd, &out);
free(cmd);
if ((out != NULL) && (strncmp(out, "hello", 5) == 0)) {
put("sys/shell", shell);
if (quote)
put("sys/shell_needs_quote", strue);
else
put("sys/shell_needs_quote", sfalse);
logprintf(logdepth, "accepted.\n");
free(out);
return 1;
}
logprintf(logdepth, "refused.\n");
free(out);
return 0;
}
static int find_shell_escape(const char *name, int logdepth, int fatal, const char *shell)
{
char cmdline[256];
char **t;
char *tests[] = {
"\\", "\\ {}&;|",
"^", "^ &",
NULL, NULL
};
(void) fatal; /* not used */
(void) shell; /* not used */
report("Looking for a shell escape character... ");
logprintf(logdepth, "finding shell escape character...\n");
for(t = tests; *t != NULL; t += 2) {
char *s, *end, *out, *start;
strcpy(cmdline, "echo ");
end = cmdline+5;
for(s = t[1]; *s != '\0'; s++) {
*end++ = *t[0];
*end++ = *s;
}
*end = '\0';
run(logdepth+1, cmdline, &out);
if (out != NULL) {
int res;
if (*out == '\"') /* wine likes to wrap the output in quotes for some reason */
start = out+1;
else
start = out;
res = strncmp(start, t[1], strlen(t[1]));
free(out);
if (res == 0) {
report("found: '%s'\n", t[0]);
logprintf(logdepth, "found shell escape char '%s'\n", t[0]);
put("sys/shell_escape_char", t[0]);
return 0;
}
}
}
report("NOT FOUND\n");
logprintf(logdepth, "shell escape character not found\n");
return 1;
}
int find_shell(const char *name, int logdepth, int fatal)
{
const char *shells[] = {
"/bin/sh -c",
"/bin/bash -c",
"bash -c",
"cmd.exe /c",
"sh -c",
"/bin/dash -c",
"dash -c",
"/bin/ksh -c",
"ksh -c",
NULL
};
const char **s;
if (cross_blind) {
const char *shell = get("/arg/sys/target-shell");
if (shell == NULL) {
report("Need to specify sys/target-shell in blind cross compiling mode, because the shell cannot be detected (note: scconfig will not attempt to run the target shell)\n");
exit(1);
}
put("sys/shell", shell);
report("Blind cross compiling: accepting '%s' as shell\n", shell);
logprintf(logdepth, "Blind cross compiling: accepting '%s' as shell\n", shell);
return 0;
}
report("Looking for a shell... ");
logprintf(logdepth, "finding a shell\n");
for(s = shells; *s != NULL; s++) {
if ((test_shell(*s, logdepth+1, 0)) || (test_shell(*s, logdepth+1, 1))) {
report("%s\n", *s);
logprintf(logdepth, "found a shell '%s', need quote: %s\n", *s, get("sys/shell_needs_quote"));
return find_shell_escape(name, logdepth, fatal, *s);
}
}
report("NOT FOUND\n");
logprintf(logdepth, "shell not found\n");
return 1;
}

View File

@ -1,227 +0,0 @@
/*
scconfig - dependencies
Copyright (C) 2009 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <string.h>
#include "dep.h"
#include "db.h"
#include "log.h"
#include "libs.h"
typedef struct {
int (*fn)(const char *name, int logdepth, int fatal);
} fn_wrap_t;
static ht_t *deps = NULL;
/* find name_ and decide if it was a wildcard request;
NOTE: there are requests and servers, both can be wildcard independently.
- if a request ends with a / *, it is an explicit wildcard request (*wild=1)
- if a request names a "directory" that is wildcard-server, that's a wildcard request (*wild=1)
- else the request is a normal request (*wild=0).
For normal requests, a required node was explicitly named; if that node is
not created by the detection function, that's a failure. For wildcard
requests we don't look for any specific node to be created.
TODO: we may still check if at least the directory is created
*/
fn_wrap_t *get_wrap(const char *name_, int *wild, int *missing)
{
fn_wrap_t *w;
char *name, *sep;
int len;
len = strlen(name_);
*wild = name_[len-1] == '*';
if (*wild) {
char *pres;
pres = malloc(len+16);
memcpy(pres, name_, len-1);
strcpy(pres+len-1, "presents");
*missing = get(pres) == NULL;
if (*missing) { /* if there's no /presents, it may be a non-directory node with an actual non-empty string value */
const char *val;
pres[len-2] = '\0';
val = get(pres);
if (val != NULL)
*missing = !strlen(val);
}
free(pres);
if (!(*missing)) /* already detected, won't be detected again */
return NULL;
}
*missing = 1;
/* try full match first */
w = ht_get(deps, name_);
if (w != NULL)
return w;
/* try substituting the last part of the path with * for wildcard matches */
name = malloc(len+3); /* worst case: ends in a / and we need to append *\0; allocate a bit more */
memcpy(name, name_, len+1); /* make a copy we can modify */
if (name[len-1] != '/') {
name[len] = '/'; /* append a / - if name_ was a "directory", this will result in name/ * */
name[len+1] = '\0';
}
*wild = 1; /* if we append a / *, then it's a wildcard request */
for(;;) {
sep = str_rchr(name, '/');
if (sep == NULL)
goto error;
sep[1] = '*';
sep[2] = '\0';
w = ht_get(deps, name);
if (w != NULL) {
free(name);
return w;
}
*sep = '\0';
*wild = 0; /* cutting back the second layer - not wildcard request anymore, but a request to a specific node served by a wildcard */
}
/* no match, exit with error */
error:;
*wild = 0;
free(name);
return NULL;
}
int require(const char *name, int logdepth, int fatal)
{
fn_wrap_t *w;
int wild, missing;
if (get(name) == NULL) {
w = get_wrap(name, &wild, &missing);
if (!missing)
return 0;
if ((w == NULL) || (w->fn == NULL)) {
error("Node %s is required but I don't know how to detect it.\n", name);
abort();
}
logprintf(logdepth, "(Required node: '%s')\n", name);
if (w->fn(name, logdepth+1, fatal) != 0) {
if (fatal) {
error("Node %s is required but provided detection callback fails to find that feature on that system.\n", name);
abort();
}
else {
logprintf(logdepth, "(Feature not found, but it is not fatal)");
return 1;
}
}
if ((!wild) && (get(name) == NULL)) {
error("Node %s is required but provided detection callback didn't create it (looks like an internal error in scconfig). (db_cwd='%s')\n", name, db_cwd);
abort();
}
}
return 0;
}
const char *dep_add(const char *name, int (*finder)(const char *name, int logdepth, int fatal))
{
fn_wrap_t *w;
w = malloc(sizeof(fn_wrap_t));
w->fn = finder;
return ht_set(deps, name, w);
}
int asked_for(const char *cando, const char *needtodo)
{
int len;
/* foo/bar/baz matches /foo/bar/baz */
if (strcmp(cando, needtodo) == 0)
goto yes;
len = strlen(needtodo);
if (len == 0)
return 0;
/* foo/bar/baz matches /foo/bar/ * */
if ((needtodo[len-1] == '*') && (strncmp(cando, needtodo, len-1) == 0))
goto yes;
return 0;
yes:; /* asked for it, but have to see if it's already detected */
if (get(cando) != NULL)
return 0;
return 1;
}
int is_dep_wild(const char *path)
{
int len = strlen(path);
if (len == 0)
return 0;
return (path[len-1] == '*');
}
const char *det_list_target(const char *path)
{
const char *res;
if (path == NULL)
goto unk;
res = strrchr(path, '/');
if (res == NULL)
goto unk;
return res + 1;
unk:;
return "<unknown>";
}
void dep_init(void)
{
deps = ht_resize(ht_alloc(0), 128);
}
void dep_uninit(void)
{
ht_free(deps);
}
int is_dep_known(const char *name)
{
return (ht_get(deps, name) != NULL);
}
void require_all(int fatal)
{
ht_entry_t *h;
for(h = ht_first(deps); h != NULL; h = ht_next(deps, h))
require(h->key, 0, fatal);
}

View File

@ -1,318 +0,0 @@
/*
scconfig - detection of printf-related features
Copyright (C) 2009 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
static int tryx(int logdepth, const char *test_c, const char *trying, const char *expected)
{
char *out = NULL;
char buff[512];
logprintf(logdepth, "trying '%s'\n", trying);
sprintf(buff, test_c, trying, trying);
if (compile_run(logdepth+1, buff, NULL, NULL, NULL, &out) == 0) {
if (strncmp(out, expected, strlen(expected)) == 0) {
free(out);
return 1;
}
free(out);
}
return 0;
}
static int tryc(int logdepth, const char *test_c, const char *trying)
{
char *out = NULL;
char buff[512];
char *spc, *end;
logprintf(logdepth, "trying '%s'\n", trying);
sprintf(buff, test_c, trying);
if (compile_run(logdepth+1, buff, NULL, NULL, NULL, &out) == 0) {
spc = str_chr(out, ' ');
if (spc == NULL)
return 0;
*spc = '\0';
spc++;
end = str_chr(spc, ' ');
if (end == NULL)
return 0;
*end = '\0';
if (strcmp(out, spc) == 0) {
free(out);
put("libs/printf_ptrcast", trying);
report("OK (%s)\n", trying);
return 1;
}
free(out);
}
return 0;
}
int find_printf_x(const char *name, int logdepth, int fatal)
{
const char *pfx;
char *test_c =
NL "#include <stdlib.h>"
NL "#include <stdio.h>"
NL "int main() {"
NL " printf(\"'%s%%x'/'%s%%x'\\n\", (size_t)0x1234, NULL);"
NL " return 0;"
NL "}"
NL;
char *expected = "'0x1234'/'0x0'";
require("cc/cc", logdepth, fatal);
report("Checking for printf %%x prefix... ");
logprintf(logdepth, "find_printf_x: trying to find printf %%x prefix...\n");
logdepth++;
pfx = get("/arg/libs/printf_x");
if (pfx == NULL) {
if (tryx(logdepth, test_c, "", expected)) {
put("libs/printf_x", "");
report("OK ()\n");
return 0;
}
if (tryx(logdepth, test_c, "0x", expected)) {
put("libs/printf_x", "0x");
report("OK (0x)\n");
return 0;
}
}
else {
report("User provided... ");
if (tryx(logdepth, test_c, pfx, expected)) {
put("libs/printf_x", pfx);
report("OK (%s)\n", pfx);
return 0;
}
}
return 1;
}
int find_printf_ptrcast(const char *name, int logdepth, int fatal)
{
const char *cast;
char *test_c =
NL "#include <stdlib.h>"
NL "#include <stdio.h>"
NL "int main() {"
NL " printf(\"%%d %%d \\n\", sizeof(void *), sizeof(%s));"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for printf %%x pointer cast... ");
logprintf(logdepth, "find_printf_ptrcast: trying to find printf %%x pointer cast...\n");
logdepth++;
cast = get("/arg/libs/printf_ptrcast");
if (cast == NULL) {
if (tryc(logdepth, test_c, "unsigned int")) return 0;
if (tryc(logdepth, test_c, "unsigned long")) return 0;
if (tryc(logdepth, test_c, "unsigned long long")) return 0;
}
else {
report("User provided... ");
if (tryc(logdepth, test_c, cast)) return 0;
}
return 1;
}
int find_snprintf(const char *name, int logdepth, int fatal)
{
char *out;
char *test_c =
NL "#include <stdlib.h>"
NL "#include <stdio.h>"
NL "int main() {"
NL " char buff[9];"
NL " char *s = buff+2;"
NL
NL " /* build a fence */"
NL " buff[0] = 0;"
NL " buff[1] = 65;"
NL " buff[7] = 66;"
NL " buff[8] = 0;"
NL
NL " snprintf(s, 4, \"%d\", 123456);"
NL " if ((buff[0] == 0) && (buff[1] == 65) && (buff[7] == 65) && (buff[8] == 0))"
NL " printf(\"%s\\n\", s);"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for snprintf... ");
logprintf(logdepth, "find_snprintf_works: trying to find snprintf...\n");
logdepth++;
logprintf(logdepth, "trying snprintf...\n");
if (compile_run(logdepth+1, test_c, NULL, NULL, NULL, &out) == 0) {
if (cross_blind) {
put("libs/snprintf", strue);
report("OK (can't check if safe)\n");
free(out);
return 0;
}
if (strcmp(out, "123")) {
put("libs/snprintf", strue);
put("libs/snprintf_safe", strue);
report("OK (safe)\n");
free(out);
return 0;
}
if (strcmp(out, "1234")) {
put("libs/snprintf", strue);
put("libs/snprintf_safe", sfalse);
report("OK (UNSAFE)\n");
free(out);
return 0;
}
free(out);
report("not found (broken output).\n");
}
else {
report("not found (no output).\n");
}
put("libs/snprintf", sfalse);
return 1;
}
int find_dprintf(const char *name, int logdepth, int fatal)
{
char *out;
char *test_c =
NL "#include <stdlib.h>"
NL "#include <stdio.h>"
NL "int main() {"
NL " dprintf(1, \"OK\\n\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for dprintf... ");
logprintf(logdepth, "find_dprintf: trying to find dprintf...\n");
logdepth++;
logprintf(logdepth, "trying dprintf...\n");
if ((compile_run(logdepth+1, test_c, NULL, NULL, NULL, &out) == 0) && (strcmp(out, "OK"))) {
put("libs/dprintf", strue);
report("found\n");
free(out);
return 0;
}
put("libs/dprintf", sfalse);
report("not found\n");
return 1;
}
int find_vdprintf(const char *name, int logdepth, int fatal)
{
char *out;
char *test_c =
NL "#include <stdlib.h>"
NL "#include <stdio.h>"
NL "#include <stdarg.h>"
NL "void local_dprintf(int fd, const char *fmt, ...)"
NL "{"
NL " va_list ap;"
NL " va_start(ap, fmt);"
NL " vdprintf(fd, fmt, ap);"
NL "}"
NL "int main() {"
NL " local_dprintf(1, \"OK\\n\");"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for vdprintf... ");
logprintf(logdepth, "find_vdprintf: trying to find vdprintf...\n");
logdepth++;
logprintf(logdepth, "trying vdprintf...\n");
if ((compile_run(logdepth+1, test_c, NULL, NULL, NULL, &out) == 0) && (strcmp(out, "OK"))) {
put("libs/vdprintf", strue);
report("found\n");
free(out);
return 0;
}
put("libs/vdprintf", sfalse);
report("not found\n");
return 1;
}
int find_vsnprintf(const char *name, int logdepth, int fatal)
{
char *out;
char *test_c =
NL "#include <stdlib.h>"
NL "#include <stdio.h>"
NL "#include <stdarg.h>"
NL "void local_vsnprintf(char *s, int len, const char *fmt, ...)"
NL "{"
NL " va_list ap;"
NL " va_start(ap, fmt);"
NL " vsnprintf(s, len, fmt, ap);"
NL "}"
NL "int main() {"
NL " char s[16];"
NL " *s = '\\0';"
NL " local_vsnprintf(s, 14, \"OK\\n\");"
NL " printf(\"%s\", s);"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for vsnprintf... ");
logprintf(logdepth, "find_vsnprintf: trying to find vsnprintf...\n");
logdepth++;
logprintf(logdepth, "trying vsnprintf...\n");
if ((compile_run(logdepth+1, test_c, NULL, NULL, NULL, &out) == 0) && (strcmp(out, "OK"))) {
put("libs/vsnprintf", strue);
report("found\n");
free(out);
return 0;
}
put("libs/vsnprintf", sfalse);
report("not found\n");
return 1;
}

View File

@ -1,255 +0,0 @@
/*
scconfig - dependencies
Copyright (C) 2009 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <string.h>
#include "dep.h"
#include "db.h"
#include "log.h"
#include "libs.h"
typedef struct {
int (*fn)(const char *name, int logdepth, int fatal);
} fn_wrap_t;
static ht_t *deps = NULL;
static const char *USER_WITHOUT = "";
/* find name_ and decide if it was a wildcard request;
NOTE: there are requests and servers, both can be wildcard independently.
- if a request ends with a / *, it is an explicit wildcard request (*wild=1)
- if a request names a "directory" that is wildcard-server, that's a wildcard request (*wild=1)
- else the request is a normal request (*wild=0).
For normal requests, a required node was explicitly named; if that node is
not created by the detection function, that's a failure. For wildcard
requests we don't look for any specific node to be created.
TODO: we may still check if at least the directory is created
*/
fn_wrap_t *get_wrap(const char *name_, int *wild, int *missing)
{
fn_wrap_t *w;
char *name, *sep, *tmp;
int len, n;
len = strlen(name_);
*wild = name_[len-1] == '*';
if (*wild) {
char *pres;
pres = malloc(len+16);
memcpy(pres, name_, len-1);
strcpy(pres+len-1, "presents");
*missing = get(pres) == NULL;
if (*missing) { /* if there's no /presents, it may be a non-directory node with an actual non-empty string value */
const char *val;
pres[len-2] = '\0';
val = get(pres);
if (val != NULL)
*missing = !strlen(val);
}
free(pres);
if (!(*missing)) /* already detected, won't be detected again */
return NULL;
}
*missing = 1;
/* check for global --without disable */
tmp = str_concat("", "/arg/without", db_cwd, "/", name_, NULL);
sep = tmp + strlen(tmp) - 1;
for(n = 0; n < 4; n++) {
const char *d = get(tmp);
if (sep < tmp+14)
break;
if (istrue(d)) {
free(tmp);
return USER_WITHOUT;
}
while(*sep != '/')
sep--;
*sep = '\0';
}
free(tmp);
/* try full match first */
w = ht_get(deps, name_);
if (w != NULL)
return w;
/* try substituting the last part of the path with * for wildcard matches */
name = malloc(len+3); /* worst case: ends in a / and we need to append *\0; allocate a bit more */
memcpy(name, name_, len+1); /* make a copy we can modify */
if (name[len-1] != '/') {
name[len] = '/'; /* append a / - if name_ was a "directory", this will result in name/ * */
name[len+1] = '\0';
}
*wild = 1; /* if we append a / *, then it's a wildcard request */
for(;;) {
sep = str_rchr(name, '/');
if (sep == NULL)
goto error;
sep[1] = '*';
sep[2] = '\0';
w = ht_get(deps, name);
if (w != NULL) {
free(name);
return w;
}
*sep = '\0';
*wild = 0; /* cutting back the second layer - not wildcard request anymore, but a request to a specific node served by a wildcard */
}
/* no match, exit with error */
error:;
*wild = 0;
free(name);
return NULL;
}
int require(const char *name, int logdepth, int fatal)
{
fn_wrap_t *w;
int wild, missing;
if (get(name) == NULL) {
w = get_wrap(name, &wild, &missing);
if (w == USER_WITHOUT) {
if (fatal) {
error("Node %s is required by the software but disabled by the user using --without\n", name);
abort();
}
else {
logprintf(logdepth, "(disabled using --without)");
return 1;
}
}
if (!missing)
return 0;
if ((w == NULL) || (w->fn == NULL)) {
error("Node %s is required but I don't know how to detect it.\n", name);
abort();
}
logprintf(logdepth, "(Required node: '%s')\n", name);
if (w->fn(name, logdepth+1, fatal) != 0) {
if (fatal) {
error("Node %s is required but provided detection callback fails to find that feature on that system.\n", name);
abort();
}
else {
logprintf(logdepth, "(Feature not found, but it is not fatal)");
return 1;
}
}
if ((!wild) && (get(name) == NULL)) {
error("Node %s is required but provided detection callback didn't create it (looks like an internal error in scconfig). (db_cwd='%s')\n", name, db_cwd);
abort();
}
}
return 0;
}
const char *dep_add(const char *name, int (*finder)(const char *name, int logdepth, int fatal))
{
fn_wrap_t *w;
w = malloc(sizeof(fn_wrap_t));
w->fn = finder;
return ht_set(deps, name, w);
}
int asked_for(const char *cando, const char *needtodo)
{
int len;
/* foo/bar/baz matches /foo/bar/baz */
if (strcmp(cando, needtodo) == 0)
goto yes;
len = strlen(needtodo);
if (len == 0)
return 0;
/* foo/bar/baz matches /foo/bar/ * */
if ((needtodo[len-1] == '*') && (strncmp(cando, needtodo, len-1) == 0))
goto yes;
return 0;
yes:; /* asked for it, but have to see if it's already detected */
if (get(cando) != NULL)
return 0;
return 1;
}
int is_dep_wild(const char *path)
{
int len = strlen(path);
if (len == 0)
return 0;
return (path[len-1] == '*');
}
const char *det_list_target(const char *path)
{
const char *res;
if (path == NULL)
goto unk;
res = strrchr(path, '/');
if (res == NULL)
goto unk;
return res + 1;
unk:;
return "<unknown>";
}
void dep_init(void)
{
deps = ht_resize(ht_alloc(0), 128);
}
void dep_uninit(void)
{
ht_free(deps);
}
int is_dep_known(const char *name)
{
return (ht_get(deps, name) != NULL);
}
void require_all(int fatal)
{
ht_entry_t *h;
for(h = ht_first(deps); h != NULL; h = ht_next(deps, h))
require(h->key, 0, fatal);
}

View File

@ -1,493 +0,0 @@
/*
scconfig - detect features of the system or the host/target computer
Copyright (C) 2009..2012 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
int find_sys_ptrwidth(const char *name, int logdepth, int fatal)
{
char *end, W[32];
char *out = NULL;
int w;
char *test_c =
NL "#include <stdio.h>"
NL "int main() {"
NL " void *ptr;"
NL " printf(\"%d\\n\", sizeof(ptr));"
NL " return 0;"
NL "}"
NL;
require("cc/cc", logdepth, fatal);
report("Checking for pointer width... ");
logprintf(logdepth, "find_sys_ptrwidth: trying to find pointer width...\n");
logdepth++;
if (compile_run(logdepth, test_c, NULL, NULL, NULL, &out) == 0) {
w = strtol(out, &end, 10);
if ((*end != '\0') && (*end != '\n') && (*end != '\r')) {
report("FAILED (test code failed)\n");
logprintf(logdepth+1, "FAILED: returned '%s' which is not a valid decimal number (at '%s')\n", out, end);
return 1;
}
sprintf(W, "%d", w * 8);
report("OK (%s bits)\n", W);
put("sys/ptrwidth", W);
logprintf(logdepth+1, "OK (%s bits)\n", W);
}
return 0;
}
int find_sys_byte_order(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <stdio.h>"
NL "int main() {"
NL " long int i = 8;"
NL " char *s = (char *)&i;"
NL " printf(\"%d\\n\", s[0]);"
NL " return 0;"
NL "}"
NL;
const char* test_c_blind_template =
NL "#include <stdio.h>"
NL "#include <endian.h>"
NL "#ifndef __BYTE_ORDER"
NL "#error \"ERROR 1\""
NL "void void *;"
NL "#endif"
NL "#ifndef __%s_ENDIAN"
NL "#error \"ERROR 2\""
NL "char char *;"
NL "#endif"
NL "#if __BYTE_ORDER != __%s_ENDIAN"
NL "#error \"ERROR 3\""
NL "int int *;"
NL "#endif"
NL "int main() {"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char *key = "sys/byte_order";
const char *endians1[] = { "LITTLE", "BIG", NULL };
const char *endians2[] = { "LSB", "MSB", NULL };
int index;
char test_c_blind[1024];
char *end;
const char *W;
char *out = NULL;
int w;
require("cc/cc", logdepth, fatal);
report("Checking for byte order... ");
logprintf(logdepth, "find_sys_byte_order: trying to find byte order...\n");
logdepth++;
if ((!isblind(db_cwd)) && compile_run(logdepth, test_c, NULL, NULL, NULL, &out) == 0) {
w = strtol(out, &end, 10);
if (((*end != '\0') && (*end != '\n') && (*end != '\r')) || ((w != 0) && (w != 8))) {
report("FAILED (test code failed)\n");
logprintf(logdepth+1, "FAILED: returned '%s' which is not a valid decimal number (at '%s')\n", out, end);
return 1;
}
if (w == 0)
W = "MSB";
else
W = "LSB";
report("OK (%s first)\n", W);
put("sys/byte_order", W);
logprintf(logdepth+1, "OK (%s first)\n", W);
return 0;
}
for (index=0; endians1[index]!=NULL; ++index)
{
sprintf(test_c_blind, test_c_blind_template, endians1[index], endians1[index]);
if (compile_run(logdepth, test_c_blind, NULL, NULL, NULL, NULL) == 0)
{
W = endians2[index];
report("OK (%s first)\n", W);
put(key, W);
return 0;
}
}
report("FAILED (cannot determine byte order, you must supply it)\n");
return try_fail(logdepth, key);
}
static int test_shell_eats_backslash(int logdepth)
{
char *test = "echo c:\\n";
char *out;
logprintf(logdepth, "testing if shell eats \\...\n");
run_shell(logdepth+1, test, &out);
if (out == NULL) {
logprintf(logdepth+1, "oops, couldn't run shell?! (returned NULL)\n");
report("ERROR: shell fails.");
abort();
}
if (out[2] == '\\') {
logprintf(logdepth, "shell does NOT eat \\...\n");
put("sys/shell_eats_backslash", sfalse);
free(out);
return 0;
}
free(out);
logprintf(logdepth, "shell eats \\...\n");
put("sys/shell_eats_backslash", strue);
return 1;
}
static int try_get_cwd(int logdepth, const char *cmd)
{
char *cwd, *end;
run_shell(logdepth+1, cmd, &cwd);
if (cwd != NULL) {
end = strpbrk(cwd, "\r\n");
if (end != NULL)
*end = '\0';
if (*cwd != '\0') {
end = cwd + strlen(cwd) - 1;
while((*end == ' ') || (*end == '\t')) { *end = '\0'; end--; }
put("sys/tmp", cwd);
/* ugly hack for win32: paths there start as c:\ */
if ((cwd[1] == ':') && (cwd[2] == '\\'))
append("sys/tmp", "\\");
else
append("sys/tmp", "/");
logprintf(logdepth, "cwd is '%s'\n", get("sys/tmp"));
free(cwd);
return 1;
}
else
free(cwd);
}
return 0;
}
static int try_tmp(int logdepth)
{
char *fn;
logprintf(logdepth, "validating temp dir '%s'\n", get("sys/tmp"));
fn = tempfile_new_noabort("");
if (fn != NULL) {
unlink(fn);
free(fn);
logprintf(logdepth, "temp dir works!\n");
return 1;
}
logprintf(logdepth, "temp dir fails\n");
return 0;
}
/* test temp dir with all sort of workarounds */
static int try_tmp_all(int logdepth)
{
const char *tmp, *si;
char c;
char *t, *so, *old_tmp;
int eats, n;
tmp = get("sys/tmp");
/* path must end in path separator */
c = tmp[strlen(tmp)-1];
if ((c != '/') && (c != '\\')) {
append("sys/tmp", "/");
tmp = get("sys/tmp");
}
logprintf(logdepth, "trying detected temp dir '%s'\n", tmp);
if (try_tmp(logdepth+1)) return 1;
/* try msys-on-windows hack: if path starts with /d/something, try d:/ instead */
if ((tmp[0] == '/') && (isalpha(tmp[1])) && (tmp[2] == '/')) {
/* for the next test we shouldn't use our half-detected tmp path but go with . */
old_tmp = strclone(tmp);
put("sys/tmp", "");
eats = istrue(get("sys/shell_eats_backslash"));
tmp = old_tmp;
logprintf(logdepth, "tmp2='%s' eats=%d\n", tmp, eats);
t = malloc(strlen(tmp) * 2);
t[0] = tmp[1];
t[1] = ':';
for(si = tmp + 2, so = t + 2; *si != '\0'; si++, so++) {
if (*si == '/') {
*so = '\\';
if (eats) {
for(n = 0; n < 3; n++) {
so++;
*so = '\\';
}
}
}
else
*so = *si;
}
*so = '\0';
free(old_tmp);
logprintf(logdepth, "trying windows fix: '%s'\n", t);
put("sys/tmp", t);
free(t);
if (try_tmp(logdepth+1)) {
if (eats)
put("sys/path_sep", "\\\\\\\\");
else
put("sys/path_sep", "\\");
put("sys/path_sep_escaped", "\\\\");
return 1;
}
tmp = get("sys/tmp");
}
/* fail. Set back tmp to empty so next command has a chance to run */
put("sys/tmp", "");
return 0;
}
int find_tmp(const char *name, int logdepth, int fatal)
{
const char *usertmp;
if (in_cross_target) {
report("Temp dir for cross compilation target is the same as for host...");
logprintf(logdepth, "Copying temp dir from host to target\n");
require("/host/sys/tmp", logdepth, fatal);
usertmp = get("/host/sys/tmp");
if (usertmp == NULL) {
report("Host temp dir not found.\n");
logprintf(logdepth, "Host temp dir not found.\n");
return 1;
}
put("sys/tmp", usertmp);
return 0;
}
/* we need shell for later tests; do this detection in . */
put("sys/tmp", "");
require("sys/shell", logdepth, fatal);
put("sys/path_sep", "/");
put("sys/path_sep_escaped", "/");
report("Detecting temp dir...");
logprintf(logdepth, "Finding temp dir (current working directory)...\n");
usertmp = get("/arg/sys/tmp");
/* . as tmp would fail for commands including a "cd" - this would cause
temporary files left in the target dir. We start out with empty
string (which is ., but on windows ./ would fail), and run
pwd (without cd) to find out the current directory (as getcwd() is not
portable). If pwd fails, we stay with ./ */
put("sys/tmp", "");
/* we need to know about shell backslash problem regardless of how
we end up with tmp - currently tmp is ., where the test could run
safely */
test_shell_eats_backslash(logdepth+1);
/* Special case: cross-compilation with emulator; we can not assume
the emulator uses the same paths as the host system, while we mix
accessing files from host and emu. If we stay in ., both emulator
and host system should be (more or less) happy. */
if (istarget(db_cwd) && iscross) {
if (usertmp == NULL) {
report("using temp dir . for cross-compilation\n");
logprintf(logdepth, "staying with . for cross-compilation\n");
}
else {
put("sys/tmp", usertmp);
report("using user supplied temp dir '%s' for cross-compilation\n", usertmp);
logprintf(logdepth, "using user supplied temp dir '%s' for cross-compilation\n", usertmp);
}
return 0;
}
if ((usertmp != NULL))
put("sys/tmp", usertmp);
if (
((usertmp != NULL) && (try_tmp_all(logdepth+2))) || /* try user supplied temp dir */
((try_get_cwd(logdepth+1, "pwd")) && (try_tmp_all(logdepth+2))) || /* try pwd for finding out cwd */
((try_get_cwd(logdepth+1, "echo %cd%") && (try_tmp_all(logdepth+2))))) { /* try windows-specific way for finding out cwd */
report(" validated %s\n", get("sys/tmp"));
logprintf(logdepth, "Detected temp dir '%s'\n", get("sys/tmp"));
return 0;
}
put("sys/tmp", "");
report("using temp dir fallback .\n");
logprintf(logdepth, "all temp directories failed, using . as tmp\n");
return 0;
}
int test_shell(const char *shell, int logdepth, int quote)
{
char *test = "echo hello";
char *cmd;
char *out;
char *q;
if (quote)
q = "\"";
else
q = "";
logprintf(logdepth, "testing '%s' as shell\n", shell);
cmd = malloc(strlen(test) + strlen(shell) + 8);
sprintf(cmd, "%s %s%s%s", shell, q, test, q);
run(logdepth+1, cmd, &out);
free(cmd);
if ((out != NULL) && (strncmp(out, "hello", 5) == 0)) {
put("sys/shell", shell);
if (quote)
put("sys/shell_needs_quote", strue);
else
put("sys/shell_needs_quote", sfalse);
logprintf(logdepth, "accepted.\n");
free(out);
return 1;
}
logprintf(logdepth, "refused.\n");
free(out);
return 0;
}
static int find_shell_escape(const char *name, int logdepth, int fatal, const char *shell)
{
char cmdline[256];
char **t;
char *tests[] = {
"\\", "\\ {}&;|",
"^", "^ &",
NULL, NULL
};
(void) fatal; /* not used */
(void) shell; /* not used */
report("Looking for a shell escape character... ");
logprintf(logdepth, "finding shell escape character...\n");
for(t = tests; *t != NULL; t += 2) {
char *s, *end, *out, *start;
strcpy(cmdline, "echo ");
end = cmdline+5;
for(s = t[1]; *s != '\0'; s++) {
*end++ = *t[0];
*end++ = *s;
}
*end = '\0';
run(logdepth+1, cmdline, &out);
if (out != NULL) {
int res;
if (*out == '\"') /* wine likes to wrap the output in quotes for some reason */
start = out+1;
else
start = out;
res = strncmp(start, t[1], strlen(t[1]));
free(out);
if (res == 0) {
report("found: '%s'\n", t[0]);
logprintf(logdepth, "found shell escape char '%s'\n", t[0]);
put("sys/shell_escape_char", t[0]);
return 0;
}
}
}
report("NOT FOUND\n");
logprintf(logdepth, "shell escape character not found\n");
return 1;
}
int find_shell(const char *name, int logdepth, int fatal)
{
const char *shells[] = {
"/bin/sh -c",
"/bin/bash -c",
"bash -c",
"cmd.exe /c",
"sh -c",
"/bin/dash -c",
"dash -c",
"/bin/ksh -c",
"ksh -c",
NULL
};
const char **s;
if (cross_blind) {
const char *shell = get("/arg/sys/target-shell");
if (shell == NULL) {
report("Need to specify sys/target-shell in blind cross compiling mode, because the shell cannot be detected (note: scconfig will not attempt to run the target shell)\n");
exit(1);
}
put("sys/shell", shell);
report("Blind cross compiling: accepting '%s' as shell\n", shell);
logprintf(logdepth, "Blind cross compiling: accepting '%s' as shell\n", shell);
return 0;
}
report("Looking for a shell... ");
logprintf(logdepth, "finding a shell\n");
for(s = shells; *s != NULL; s++) {
if ((test_shell(*s, logdepth+1, 0)) || (test_shell(*s, logdepth+1, 1))) {
report("%s\n", *s);
logprintf(logdepth, "found a shell '%s', need quote: %s\n", *s, get("sys/shell_needs_quote"));
return find_shell_escape(name, logdepth, fatal, *s);
}
}
report("NOT FOUND\n");
logprintf(logdepth, "shell not found\n");
return 1;
}

View File

@ -1,141 +0,0 @@
DEFAULT_NOMAIN_OBJS = \
$(BIN)/default/find_cc.o \
$(BIN)/default/lib_compile.o \
$(BIN)/default/lib_uniqinc.o \
$(BIN)/default/lib_file.o \
$(BIN)/default/lib_try.o \
$(BIN)/default/str.o \
$(BIN)/default/ht.o \
$(BIN)/default/log.o \
$(BIN)/default/arg.o \
$(BIN)/default/db.o \
$(BIN)/default/dep.o \
$(BIN)/default/deps_default.o \
$(BIN)/default/find_libs.o \
$(BIN)/default/find_fscalls.o \
$(BIN)/default/find_printf.o \
$(BIN)/default/find_proc.o \
$(BIN)/default/find_fstools.o \
$(BIN)/default/find_uname.o \
$(BIN)/default/find_target.o \
$(BIN)/default/find_thread.o \
$(BIN)/default/find_io.o \
$(BIN)/default/find_time.o \
$(BIN)/default/find_types.o \
$(BIN)/default/find_signal.o \
$(BIN)/default/find_environ.o \
$(BIN)/default/regex.o \
$(BIN)/default/lib_filelist.o \
$(BIN)/default/lib_srctree.o \
$(BIN)/default/lib_pkg_config.o \
$(BIN)/default/find_str.o \
$(BIN)/default/find_sys.o
DEFAULT_MAIN_OBJS = \
$(BIN)/default/main.o \
$(BIN)/default/main_custom_args.o \
$(BIN)/default/main_lib.o
DEFAULT_OBJS = $(DEFAULT_NOMAIN_OBJS) $(DEFAULT_MAIN_OBJS)
$(BIN)/default/lib_compile.o: $(SRC)/default/lib_compile.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/lib_compile.c -o $(BIN)/default/lib_compile.o
$(BIN)/default/lib_file.o: $(SRC)/default/lib_file.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/lib_file.c -o $(BIN)/default/lib_file.o
$(BIN)/default/lib_try.o: $(SRC)/default/lib_try.c $(SRC)/default/log.h $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/lib_try.c -o $(BIN)/default/lib_try.o
$(BIN)/default/str.o: $(SRC)/default/str.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/str.c -o $(BIN)/default/str.o
$(BIN)/default/ht.o: $(SRC)/default/ht.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/ht.c -o $(BIN)/default/ht.o
$(BIN)/default/log.o: $(SRC)/default/log.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/log.c -o $(BIN)/default/log.o
$(BIN)/default/arg.o: $(SRC)/default/arg.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/arg.c -o $(BIN)/default/arg.o
$(BIN)/default/db.o: $(SRC)/default/db.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/db.c -o $(BIN)/default/db.o
$(BIN)/default/dep.o: $(SRC)/default/dep.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/dep.c -o $(BIN)/default/dep.o
$(BIN)/default/deps_default.o: $(SRC)/default/deps_default.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/deps_default.c -o $(BIN)/default/deps_default.o
$(BIN)/default/find_libs.o: $(SRC)/default/find_libs.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/find_libs.c -o $(BIN)/default/find_libs.o
$(BIN)/default/find_fscalls.o: $(SRC)/default/find_fscalls.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/find_fscalls.c -o $(BIN)/default/find_fscalls.o
$(BIN)/default/find_signal.o: $(SRC)/default/find_signal.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/find_signal.c -o $(BIN)/default/find_signal.o
$(BIN)/default/find_printf.o: $(SRC)/default/find_printf.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/find_printf.c -o $(BIN)/default/find_printf.o
$(BIN)/default/find_proc.o: $(SRC)/default/find_proc.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/find_proc.c -o $(BIN)/default/find_proc.o
$(BIN)/default/find_fstools.o: $(SRC)/default/find_fstools.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/find_fstools.c -o $(BIN)/default/find_fstools.o
$(BIN)/default/find_uname.o: $(SRC)/default/find_uname.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/find_uname.c -o $(BIN)/default/find_uname.o
$(BIN)/default/find_target.o: $(SRC)/default/find_target.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/find_target.c -o $(BIN)/default/find_target.o
$(BIN)/default/regex.o: $(SRC)/default/regex.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/regex.c -o $(BIN)/default/regex.o
$(BIN)/default/lib_filelist.o: $(SRC)/default/lib_filelist.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/lib_filelist.c -o $(BIN)/default/lib_filelist.o
$(BIN)/default/lib_srctree.o: $(SRC)/default/lib_srctree.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/lib_srctree.c -o $(BIN)/default/lib_srctree.o
$(BIN)/default/lib_pkg_config.o: $(SRC)/default/lib_pkg_config.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/lib_pkg_config.c -o $(BIN)/default/lib_pkg_config.o
$(BIN)/default/lib_uniqinc.o: $(SRC)/default/lib_uniqinc.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/lib_uniqinc.c -o $(BIN)/default/lib_uniqinc.o
$(BIN)/default/find_sys.o: $(SRC)/default/find_sys.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/find_sys.c -o $(BIN)/default/find_sys.o
$(BIN)/default/find_str.o: $(SRC)/default/find_str.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/find_str.c -o $(BIN)/default/find_str.o
$(BIN)/default/find_cc.o: $(SRC)/default/find_cc.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/find_cc.c -o $(BIN)/default/find_cc.o
$(BIN)/default/find_environ.o: $(SRC)/default/find_environ.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/find_environ.c -o $(BIN)/default/find_environ.o
$(BIN)/default/find_io.o: $(SRC)/default/find_io.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/find_io.c -o $(BIN)/default/find_io.o
$(BIN)/default/find_time.o: $(SRC)/default/find_time.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/find_time.c -o $(BIN)/default/find_time.o
$(BIN)/default/find_types.o: $(SRC)/default/find_types.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/find_types.c -o $(BIN)/default/find_types.o
$(BIN)/default/main.o: $(SRC)/default/main.c $(SRC)/default/dep.h $(SRC)/default/libs.h Makefile
$(CC) $(CFLAGS) -c $(SRC)/default/main.c -o $(BIN)/default/main.o
$(BIN)/default/main_custom_args.o: $(SRC)/default/main_custom_args.c
$(CC) $(CFLAGS) -c $(SRC)/default/main_custom_args.c -o $(BIN)/default/main_custom_args.o
$(BIN)/default/main_lib.o: $(SRC)/default/main_lib.c
$(CC) $(CFLAGS) -c $(SRC)/default/main_lib.c -o $(BIN)/default/main_lib.o
$(BIN)/default/find_thread.o: $(SRC)/default/find_thread.c $(SRC)/default/dep.h $(SRC)/default/libs.h
$(CC) $(CFLAGS) -c $(SRC)/default/find_thread.c -o $(BIN)/default/find_thread.o

View File

@ -1,833 +0,0 @@
/*
scconfig - detection of file system tools
Copyright (C) 2009..2012 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
#include "dep.h"
static int test_cp_ln(int logdepth, const char *command, int link)
{
char *src, *dst, *src_esc, *dst_esc;
char *cmd, *result;
char *test_string = "works.";
int ret;
logprintf(logdepth, "trying '%s'\n", command);
src = tempfile_dump(test_string, "");
dst = tempfile_new("");
if (link)
unlink(dst);
src_esc = shell_escape_dup(src);
dst_esc = shell_escape_dup(dst);
cmd = malloc(strlen(command) + strlen(src_esc) + strlen(dst_esc) + 32);
sprintf(cmd, "%s %s %s", command, src_esc, dst_esc);
run_shell(logdepth, cmd, NULL);
free(cmd);
free(src_esc);
free(dst_esc);
result = load_file(dst);
ret = !strcmp(result, test_string);
logprintf(logdepth+1, "result: '%s' == '%s' (%d)\n", result, test_string, ret);
free(result);
unlink(src);
free(src);
result = load_file(dst);
if (link) {
if (strcmp(result, test_string) == 0) {
report("Warning: link is copy (or hard link). ");
logprintf(logdepth+1, "Warning: link is copy (or hard link).\n");
}
}
else {
if (strcmp(result, test_string) != 0) {
report("Warning: copy is symlink. ");
logprintf(logdepth+1, "Warning: copy is symlink.\n");
}
}
free(result);
if (ret) {
if (link)
put("fstools/ln", command);
else
put("fstools/cp", command);
report("OK (%s)\n", command);
}
unlink(dst);
free(dst);
return ret;
}
static int test_mv(int logdepth, const char *command)
{
char *src, *dst, *src_esc, *dst_esc;
char *cmd, *result;
char *test_string = "works.";
int ret;
logprintf(logdepth, "trying '%s'\n", command);
src = tempfile_dump(test_string, "");
dst = tempfile_new("");
unlink(dst);
src_esc = shell_escape_dup(src);
dst_esc = shell_escape_dup(dst);
cmd = malloc(strlen(command) + strlen(src_esc) + strlen(dst_esc) + 32);
sprintf(cmd, "%s %s %s", command, src_esc, dst_esc);
run_shell(logdepth, cmd, NULL);
free(cmd);
free(src_esc);
free(dst_esc);
result = load_file(dst);
ret = !strcmp(result, test_string);
logprintf(logdepth+1, "result: '%s' == '%s' (%d)\n", result, test_string, ret);
free(result);
if (file_size(src) > 0) {
report("Warning: mv is copy. ");
logprintf(logdepth+1, "Warning: mv is copy.\n");
}
if (ret) {
put("fstools/mv", command);
report("OK (%s)\n", command);
}
unlink(dst);
unlink(src);
free(dst);
free(src);
return ret;
}
static int test_mkdir(int logdepth, const char *command)
{
char *dir, *file;
char *dir_esc;
char *cmd, *result;
char *test_string = "works.";
int ret = 0, had_p;
FILE *f;
logprintf(logdepth, "trying '%s'\n", command);
dir = tempfile_new("");
dir_esc = shell_escape_dup(dir);
unlink(dir);
had_p = is_dir("-p");
cmd = malloc(strlen(command) + strlen(dir_esc) + 32);
sprintf(cmd, "%s %s", command, dir_esc);
run_shell(logdepth, cmd, NULL);
free(cmd);
file = malloc(strlen(dir) + 32);
sprintf(file, "%s/test", dir);
f = fopen(file, "w");
if (f != NULL) {
fputs(test_string, f);
fclose(f);
result = load_file(file);
if (strcmp(result, test_string) == 0)
ret = 1;
free(result);
}
unlink(file);
unlink(dir);
cmd = malloc(strlen(dir) + 32);
sprintf(cmd, "rmdir %s", dir_esc);
run_shell(logdepth, cmd, NULL);
free(cmd);
free(file);
free(dir);
free(dir_esc);
/* This is a bit ugly, but on win32 or other systems where mkdir works
but -p doesn't have an effect, a directory called -p may be left over... */
if ((!had_p) && (is_dir("-p"))) {
unlink("-p");
return 0;
}
if (ret != 0) {
put("fstools/mkdir", command);
report("OK (%s)\n", command);
}
return ret;
}
static int test_rm(int logdepth, const char *command)
{
char *src, *src_esc, *cmd, *test_string = "works.";
int ret;
logprintf(logdepth, "trying '%s'\n", command);
src = tempfile_dump(test_string, "");
if (file_size(src) < 0) {
report("error: can't create temp file\n");
free(src);
return 0;
}
src_esc = shell_escape_dup(src);
cmd = malloc(strlen(command) + strlen(src_esc) + 32);
sprintf(cmd, "%s %s", command, src_esc);
run_shell(logdepth, cmd, NULL);
free(cmd);
free(src_esc);
ret = file_size(src) < 0;
if (ret) {
put("fstools/rm", command);
report("OK (%s)\n", command);
}
else
unlink(src);
free(src);
return ret;
}
static int test_ar(int logdepth, const char *command)
{
char *src, *dst, *src_esc, *dst_esc;
char *cmd, *result, *expected;
char *test_string = "works.";
const char *path_sep;
int ret = 0;
logprintf(logdepth, "trying '%s'\n", command);
path_sep = get("sys/path_sep");
src = tempfile_dump(test_string, "");
dst = tempfile_new("");
unlink(dst);
src_esc = shell_escape_dup(src);
dst_esc = shell_escape_dup(dst);
cmd = malloc(strlen(command) + strlen(src_esc) + strlen(dst_esc) + 32);
sprintf(cmd, "%s ru %s %s", command, dst_esc, src_esc);
run_shell(logdepth, cmd, NULL);
sprintf(cmd, "%s t %s", command, dst_esc);
run_shell(logdepth, cmd, &result);
free(cmd);
free(dst_esc);
free(src_esc);
if (result != NULL) {
expected = str_rchr(src, *path_sep);
if (expected == NULL)
expected = src;
else
expected++;
ret = strncmp(expected, result, strlen(expected)) == 0;
if (ret) {
put("fstools/ar", command);
report("OK (%s)\n", command);
}
free(result);
}
unlink(src);
unlink(dst);
free(src);
free(dst);
return ret;
}
static int test_ranlib(int logdepth, const char *command, const char *obj)
{
char *cmd, *archive, *archive_esc, *obj_esc;
const char *ar;
int ret;
ar = get("fstools/ar");
logprintf(logdepth, "trying '%s'\n", command);
archive = tempfile_new(".a");
archive_esc = shell_escape_dup(archive);
obj_esc = shell_escape_dup(obj);
cmd = malloc(strlen(command) + strlen(obj_esc) + strlen(archive_esc) + 64);
sprintf(cmd, "%s r %s %s", ar, archive_esc, obj_esc);
unlink(archive);
ret = run_shell(logdepth, cmd, NULL) == 0;
if (!ret)
goto fin;
sprintf(cmd, "%s %s", command, archive_esc);
ret = run_shell(logdepth, cmd, NULL) == 0;
if (ret) {
put("fstools/ranlib", command);
report("OK (%s)\n", command);
}
fin:;
unlink(archive);
free(archive);
free(cmd);
free(archive_esc);
free(obj_esc);
return ret;
}
static int test_awk(int logdepth, const char *command)
{
char cmd[1024];
char *out;
int ret = 0;
char *script, *script_esc;
/* For some reason windows awk doesn't like the code with NLs */
char *test_awk =
"BEGIN {"
" gsub(\"b\", \"B\", t);"
" print t;"
"}";
logprintf(logdepth, "trying '%s'\n", command);
script = tempfile_dump(test_awk, ".awk");
script_esc = shell_escape_dup(script);
sprintf(cmd, "%s -v \"t=blobb\" -f %s", command, script_esc);
free(script_esc);
run_shell(logdepth, cmd, &out);
unlink(script);
free(script);
if ((out != NULL) && (strncmp(out, "BloBB", 5) == 0)) {
put("fstools/awk", command);
report("OK (%s)\n", command);
ret = 1;
}
free(out);
return ret;
}
static int test_cat(int logdepth, const char *command)
{
char cmd[1024];
char *out;
int ret = 0;
char *fn, *fn_esc;
const char *test_str = "hello world";
logprintf(logdepth, "trying '%s'\n", command);
fn = tempfile_dump(test_str, ".txt");
fn_esc = shell_escape_dup(fn);
sprintf(cmd, "%s %s", command, fn_esc);
run_shell(logdepth, cmd, &out);
unlink(fn);
free(fn);
free(fn_esc);
if ((out != NULL) && (strncmp(out, test_str, strlen(test_str)) == 0)) {
put("fstools/cat", command);
report("OK (%s)\n", command);
ret = 1;
}
free(out);
return ret;
}
static int test_sed(int logdepth, const char *command)
{
char cmd[1024];
char *out;
int ret = 0;
char *fn, *fn_esc;
const char *test_str_in = "hello world";
const char *test_str_out = "he11o wor1d";
logprintf(logdepth, "trying '%s'\n", command);
fn = tempfile_dump(test_str_in, ".txt");
fn_esc = shell_escape_dup(fn);
sprintf(cmd, "%s \"s/l/1/g\" < %s", command, fn_esc);
run_shell(logdepth, cmd, &out);
unlink(fn);
free(fn);
free(fn_esc);
if ((out != NULL) && (strncmp(out, test_str_out, strlen(test_str_out)) == 0)) {
put("fstools/sed", command);
report("OK (%s)\n", command);
ret = 1;
}
free(out);
return ret;
}
static int test_chmodx(int logdepth, const char *command)
{
char *cmd, *tmp, *tmp_esc, *out, *s;
int ret;
logprintf(logdepth, "trying '%s'\n", command);
tmp = tempfile_dump("#!/bin/sh\necho OK\n", ".bat");
tmp_esc = shell_escape_dup(tmp);
cmd = malloc(strlen(command) + strlen(tmp_esc) + 16);
sprintf(cmd, "%s %s", command, tmp_esc);
ret = run_shell(logdepth, cmd, NULL) == 0;
free(cmd);
if (!ret) {
free(tmp_esc);
return ret;
}
ret = run(logdepth+1, tmp_esc, &out);
free(tmp_esc);
if (ret == 0) {
for(s = out; s != NULL; s = str_chr(s, '\n')) {
logprintf(logdepth+1, "chmod line to test: '%s'\n", s);
if ((s[0] == 'O') && (s[1] == 'K')) {
logprintf(logdepth+2, "(OK)\n");
ret = 1;
break;
}
s++;
}
}
else
ret = 0;
free(out);
if (ret) {
put("fstools/chmodx", command);
logprintf(logdepth, "chmodx command validated: '%s'\n", command);
report("OK (%s)\n", command);
}
unlink(tmp);
return ret;
}
static int test_file(int logdepth, const char *node, const char *command)
{
char cmd[1024];
char *out;
int ret = 0;
char *fn, *fn_esc;
logprintf(logdepth, "trying '%s'\n", command);
fn = tempfile_dump("plain text file\r\n", ".txt");
fn_esc = shell_escape_dup(fn);
sprintf(cmd, "%s %s", command, fn_esc);
run_shell(logdepth, cmd, &out);
unlink(fn);
free(fn);
free(fn_esc);
if ((out != NULL) && (strstr(out, "text") != NULL)) {
put(node, command);
report("OK (%s)\n", command);
ret = 1;
}
free(out);
return ret;
}
int find_fstools_cp(const char *name, int logdepth, int fatal)
{
const char *cp;
(void) fatal; /* to suppress compiler warnings about not using fatal */
report("Checking for cp... ");
logprintf(logdepth, "find_fstools_cp: trying to find cp...\n");
logdepth++;
cp = get("/arg/fstools/cp");
if (cp == NULL) {
if (test_cp_ln(logdepth, "cp -rp", 0)) return 0;
if (test_cp_ln(logdepth, "cp -r", 0)) return 0;
if (test_cp_ln(logdepth, "copy /r", 0)) return 0; /* wine */
}
else {
report(" user provided (%s)...", cp);
if (test_cp_ln(logdepth, cp, 0)) return 0;
}
return 1;
}
int find_fstools_ln(const char *name, int logdepth, int fatal)
{
const char *ln;
(void) fatal; /* to suppress compiler warnings about not using fatal */
report("Checking for ln... ");
logprintf(logdepth, "find_fstools_ln: trying to find ln...\n");
logdepth++;
ln = get("/arg/fstools/ln");
if (ln == NULL) {
if (test_cp_ln(logdepth, "ln -sf",1 )) return 0;
if (test_cp_ln(logdepth, "ln -s",1 )) return 0;
if (test_cp_ln(logdepth, "ln", 1)) return 0;
/* "mklink /H" -> win32 equivalent to "ln" */
/* "cp -s" -> same as "ln -s" */
/* "cp -l" -> same as "ln" */
if (test_cp_ln(logdepth, "cp", 1)) return 0;
}
else {
report(" user provided (%s)...", ln);
if (test_cp_ln(logdepth, ln, 1)) return 0;
}
return 1;
}
int find_fstools_mv(const char *name, int logdepth, int fatal)
{
const char *mv;
(void) fatal; /* to suppress compiler warnings about not using fatal */
report("Checking for mv... ");
logprintf(logdepth, "find_fstools_mv: trying to find mv...\n");
logdepth++;
mv = get("/arg/fstools/mv");
if (mv == NULL) {
if (test_mv(logdepth, "mv")) return 0;
if (test_mv(logdepth, "move")) return 0; /* win32 */
if (test_mv(logdepth, "cp")) return 0;
}
else {
report(" user provided (%s)...", mv);
if (test_mv(logdepth, mv)) return 0;
}
return 1;
}
int find_fstools_rm(const char *name, int logdepth, int fatal)
{
const char *rm;
(void) fatal; /* to suppress compiler warnings about not using fatal */
report("Checking for rm... ");
logprintf(logdepth, "find_fstools_rm: trying to find rm...\n");
logdepth++;
rm = get("/arg/fstools/rm");
if (rm == NULL) {
if (test_rm(logdepth, "rm -rf")) return 0;
if (test_rm(logdepth, "rm -f")) return 0;
if (test_rm(logdepth, "rm")) return 0;
if (test_rm(logdepth, "del")) return 0; /* for win32 */
}
else {
report(" user provided (%s)...", rm);
if (test_rm(logdepth, rm)) return 0;
}
return 1;
}
int find_fstools_mkdir(const char *name, int logdepth, int fatal)
{
const char *mkdir;
(void) fatal; /* to suppress compiler warnings about not using fatal */
report("Checking for mkdir... ");
logprintf(logdepth, "find_fstools_mkdir: trying to find mkdir...\n");
logdepth++;
mkdir = get("/arg/fstools/mkdir");
if (mkdir == NULL) {
if (test_mkdir(logdepth, "mkdir -p")) return 0;
if (test_mkdir(logdepth, "md")) return 0; /* for win32 */
}
else {
report(" user provided (%s)...", mkdir);
if (test_mkdir(logdepth, mkdir)) return 0;
}
return 1;
}
int find_fstools_ar(const char *name, int logdepth, int fatal)
{
const char *ar, *target;
char *targetar;
int len;
(void) fatal; /* to suppress compiler warnings about not using fatal */
require("sys/path_sep", logdepth, fatal);
report("Checking for ar... ");
logprintf(logdepth, "find_fstools_ar: trying to find ar...\n");
logdepth++;
ar = get("/arg/fstools/ar");
if (ar == NULL) {
target = get("/arg/sys/target");
if (target != NULL) {
logprintf(logdepth+1, "find_ar: crosscompiling for '%s', looking for target ar\n", target);
len = strlen(target);
targetar = malloc(len + 8);
memcpy(targetar, target, len);
strcpy(targetar + len, "-ar");
if (test_ar(logdepth, targetar)) {
free(targetar);
return 0;
}
free(targetar);
}
if (test_ar(logdepth, "ar")) return 0;
if (test_ar(logdepth, "/usr/bin/ar")) return 0;
}
else {
report(" user provided (%s)...", ar);
if (test_ar(logdepth, ar)) return 0;
}
return 1;
}
int find_fstools_ranlib(const char *name, int logdepth, int fatal)
{
const char *ranlib, *target;
char *targetranlib;
int len;
char *test_code = NL "int zero() { return 0; }" NL;
char *obj = ".o";
(void) fatal; /* to suppress compiler warnings about not using fatal */
require("fstools/ar", logdepth, fatal);
require("cc/cc", logdepth, fatal);
report("Checking for ranlib... ");
logprintf(logdepth, "find_fstools_ranlib: trying to find ranlib...\n");
logdepth++;
logprintf(logdepth, "compiling test object...\n");
if (compile_code(logdepth+1, test_code, &obj, NULL, "-c", NULL) != 0) {
logprintf(logdepth, "ERROR: Can't compile test object\n");
report("ERROR: Can't compile test object\n");
abort();
}
ranlib = get("/arg/fstools/ranlib");
if (ranlib == NULL) {
target = get("/arg/sys/target");
if (target != NULL) {
logprintf(logdepth+1, "find_ranlib: crosscompiling for '%s', looking for target ranlib\n", target);
len = strlen(target);
targetranlib = malloc(len + 16);
memcpy(targetranlib, target, len);
strcpy(targetranlib + len, "-ranlib");
if (test_ranlib(logdepth, targetranlib, obj)) {
free(targetranlib);
return 0;
}
free(targetranlib);
}
if (test_ranlib(logdepth, "ranlib", obj)) goto found;
if (test_ranlib(logdepth, "/usr/bin/ranlib", obj)) goto found;
if (test_ranlib(logdepth, "ar -s", obj)) goto found;
if (test_ranlib(logdepth, "/usr/bin/ar -s", obj)) goto found;
/* some systems (for example IRIX) can't run s without doing
something else; t is harmless */
if (test_ranlib(logdepth, "ar ts", obj)) goto found;
if (test_ranlib(logdepth, "/usr/bin/ar ts", obj)) goto found;
/* final fallback: some systems (for example minix3) simply
do not have ranlib or ar equivalent; it's easier to detect
a dummy command than to force conditions into Makefiles */
if (test_ranlib(logdepth, "true", obj)) goto found;
}
else {
report(" user provided (%s)...", ranlib);
if (test_ranlib(logdepth, ranlib, obj)) goto found;
}
unlink(obj);
free(obj);
return 1;
found:;
unlink(obj);
free(obj);
return 0;
}
int find_fstools_awk(const char *name, int logdepth, int fatal)
{
const char *awk;
(void) fatal; /* to suppress compiler warnings about not using fatal */
report("Checking for awk... ");
logprintf(logdepth, "find_fstools_awk: trying to find awk...\n");
logdepth++;
awk = get("/arg/fstools/awk");
if (awk == NULL) {
if (test_awk(logdepth, "awk")) return 0;
if (test_awk(logdepth, "gawk")) return 0;
if (test_awk(logdepth, "mawk")) return 0;
if (test_awk(logdepth, "nawk")) return 0;
}
else {
report(" user provided (%s)...", awk);
if (test_awk(logdepth, awk)) return 0;
}
return 1;
}
int find_fstools_chmodx(const char *name, int logdepth, int fatal)
{
const char *chmod;
(void) fatal; /* to suppress compiler warnings about not using fatal */
report("Checking for chmod to executable... ");
logprintf(logdepth, "find_fstools_awk: trying to find chmod to executable...\n");
logdepth++;
chmod = get("/arg/fstools/chmodx");
if (chmod == NULL) {
if (test_chmodx(logdepth, "chmod +x")) return 0;
if (test_chmodx(logdepth, "chmod 755")) return 0;
if (test_chmodx(logdepth, "")) return 0; /* on some systems we don't need to do anything */
}
else {
report(" user provided (%s)...", chmod);
if (test_chmodx(logdepth, chmod)) return 0;
}
return 1;
}
int find_fstools_cat(const char *name, int logdepth, int fatal)
{
const char *cat;
(void) fatal; /* to suppress compiler warnings about not using fatal */
report("Checking for cat... ");
logprintf(logdepth, "find_fstools_cat: trying to find cat...\n");
logdepth++;
cat = get("/arg/fstools/cat");
if (cat == NULL) {
if (test_cat(logdepth, "cat")) return 0;
if (test_cat(logdepth, "type")) return 0;
}
else {
report(" user provided (%s)...", cat);
if (test_cat(logdepth, cat)) return 0;
}
return 1;
}
int find_fstools_sed(const char *name, int logdepth, int fatal)
{
const char *sed;
(void) fatal; /* to suppress compiler warnings about not using fatal */
report("Checking for sed... ");
logprintf(logdepth, "find_fstools_sed: trying to find sed...\n");
logdepth++;
sed = get("/arg/fstools/sed");
if (sed == NULL) {
if (test_sed(logdepth, "sed")) return 0;
}
else {
report(" user provided (%s)...", sed);
if (test_sed(logdepth, sed)) return 0;
}
return 1;
}
int find_fstools_file_l(const char *name, int logdepth, int fatal)
{
const char *file;
(void) fatal; /* to suppress compiler warnings about not using fatal */
report("Checking for file... ");
logprintf(logdepth, "find_fstools_file_l: trying to find file -L...\n");
logdepth++;
file = get("/arg/fstools/file_l");
if (file == NULL) {
if (test_file(logdepth, "fstools/file_l", "file -L")) return 0;
if (test_file(logdepth, "fstools/file_l", "file")) return 0;
}
else {
report(" user provided (%s)...", file);
if (test_file(logdepth, "fstools/file_l", file)) return 0;
}
return 1;
}
int find_fstools_file(const char *name, int logdepth, int fatal)
{
const char *file;
(void) fatal; /* to suppress compiler warnings about not using fatal */
report("Checking for file... ");
logprintf(logdepth, "find_fstools_file: trying to find file...\n");
logdepth++;
file = get("/arg/fstools/file");
if (file == NULL) {
if (test_file(logdepth, "fstools/file", "file")) return 0;
}
else {
report(" user provided (%s)...", file);
if (test_file(logdepth, "fstools/file", file)) return 0;
}
return 1;
}

View File

@ -1,338 +0,0 @@
/*
scconfig - library for listing files in a directory
Copyright (C) 2009..2012 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "db.h"
#include "libs.h"
#include "log.h"
#include "dep.h"
static void destroy_testdir(int logdepth, char *dir)
{
const char *rm;
char *cmd, *dir_esc;
rm = get("fstools/rm");
if (rm == NULL) {
logprintf(logdepth, "CAN NOT delete test directory '%s': no rm available\n", dir);
return;
}
if (dir == NULL)
return;
logprintf(logdepth, "deleting test directory '%s'\n", dir);
cmd = malloc(strlen(dir) + strlen(rm) + 4);
dir_esc = shell_escape_dup(dir);
sprintf(cmd, "%s %s", rm, dir_esc);
run_shell(0, cmd, NULL);
free(cmd);
free(dir);
free(dir_esc);
}
static char *create_testdir(int logdepth)
{
char *dir, *fn, *cmd;
const char *mkdir;
int n;
logprintf(logdepth, "creating test directory\n");
dir = tempdir_new(logdepth+1, "");
logprintf(logdepth, "sandbox is: '%s'\n", dir);
fn = malloc(strlen(dir) + 32);
for(n = 0; n < 2; n++) {
FILE *f;
sprintf(fn, "%s%sfile%d", dir, get("sys/path_sep"), n+1);
f = fopen(fn, "w");
if (f != NULL) {
fclose(f);
if (!is_file(fn)) {
logprintf(logdepth, "Can not create file %s\n", fn);
free(fn);
destroy_testdir(logdepth, dir);
return NULL;
}
}
}
mkdir = get("fstools/mkdir");
cmd = malloc(strlen(dir) + 64);
for(n = 0; n < 2; n++) {
char *fn_esc;
sprintf(fn, "%s%sdir%d", dir, get("sys/path_sep"), n+1);
fn_esc = shell_escape_dup(fn);
sprintf(cmd, "%s %s", mkdir, fn_esc);
free(fn_esc);
if (run_shell(logdepth+1, cmd, NULL) || (!is_dir(fn))) {
logprintf(logdepth, "Can not create directory %s\n", fn);
free(fn);
free(cmd);
destroy_testdir(logdepth, dir);
return NULL;
}
}
free(cmd);
free(fn);
return dir;
}
static int test(int logdepth, int argc, char *argv[])
{
int dir[2], file[2], n;
int *arr, idx;
for(n = 0; n < 2; n++) {
dir[n] = 0;
file[n] = 0;
}
/* count the list of files, increase arrays by hit */
for(n = 0; n < argc; n++) {
arr = NULL;
if (strncmp(argv[n], "dir", 3) == 0) { arr = dir; idx = atoi(argv[n]+3); }
if (strncmp(argv[n], "file", 4) == 0) { arr = file; idx = atoi(argv[n]+4); }
if (arr == NULL) {
logprintf(logdepth, "test fails: unknown existing file on the list: '%s'\n", argv[n]);
return 0;
}
idx--;
if ((idx < 0) || (idx > 1)) {
logprintf(logdepth, "test fails: file name changed: '%s'\n", argv[n]);
return 0;
}
arr[idx]++;
}
/* check if every item was found exactly once */
for(n = 0; n < 2; n++) {
if ((dir[n] != 1) || (file[n] != 1)) {
logprintf(logdepth, "test fails: %s%d not found \n", dir[n] ? "file" : "dir", n);
return 0;
}
}
return 1;
}
static void filelist_extract(char *out, const char *dir, const char *method, int *argc, char ***argv)
{
char *s, sep, *start, *end;
int len, allocated = 0, count = 0;
char **arr = NULL;
const char *psep;
psep = get("sys/path_sep");
len = strlen(dir);
/* uniform separator */
if (*method == 'w') {
/* if word splitting then convert newlines to spaces and convert tabs to spaces */
for(s = out; *s != '\0'; s++) {
if ((*s == '\n') || (*s == '\r') || (*s == '\t'))
*s = ' ';
}
sep = ' ';
}
else {
for(s = out; *s != '\0'; s++) {
if (*s == '\r')
*s = '\n';
}
sep = '\n';
}
start = out;
while((s = str_chr(start, sep)) != NULL) {
*s = '\0';
if (strncmp(dir, start, len) == 0)
start += len;
while(*start == *psep)
start++;
if (*start != '\0') {
end = str_chr(start, *psep);
if (end != NULL)
*end = '\0';
/* add only if not the same as previous and exists */
if ((!((count > 0) && (strcmp(arr[count - 1], start) == 0))) && (exists_in(dir, start))) {
if (count >= allocated) {
allocated = count + 32;
arr = realloc(arr, sizeof(char *) * allocated);
}
arr[count] = strclone(start);
count++;
}
}
start = s+1;
while(*start == sep) start++;
}
*argc = count;
*argv = arr;
}
void filelist_free(int *argc, char ***argv)
{
int n;
if (*argv == NULL)
return;
for(n = 0; n < *argc; n++)
free((*argv)[n]);
free(*argv);
*argc = 0;
}
static char *filelist_asmcmd(const char *dir, const char *list_cmd)
{
char *cmd;
cmd = malloc(strlen(dir) + strlen(list_cmd) + 32);
sprintf(cmd, list_cmd, dir);
return cmd;
}
static int try(int logdepth, const char *dir, const char *list_cmd, const char *method)
{
char *cmd, *out, *dir_esc;
int argc, res;
char **argv;
dir_esc = shell_escape_dup(dir);
cmd = filelist_asmcmd(dir_esc, list_cmd);
free(dir_esc);
logprintf(logdepth, "trying '%s'...\n", cmd);
run_shell(logdepth+1, cmd, &out);
if (out != NULL) {
filelist_extract(out, dir, method, &argc, &argv);
res = test(logdepth+1, argc, argv);
filelist_free(&argc, &argv);
free(out);
}
if (res) {
logprintf(logdepth+1, "Works.", cmd);
put("/internal/filelist/cmd", list_cmd);
put("/internal/filelist/method", method);
report("OK ('%s' with %s split)\n", list_cmd, method);
}
free(cmd);
return res;
}
int find_filelist(const char *name, int logdepth, int fatal)
{
char *dir;
char *old_cwd;
int ret;
old_cwd = strclone(db_cwd);
db_cd("/host");
require("fstools/mkdir", logdepth, fatal);
require("fstools/rm", logdepth, fatal);
report("Checking for filelist... ");
logprintf(logdepth, "find_filelist: trying to find file listing...\n");
logdepth++;
dir = create_testdir(logdepth);
if (dir == NULL) {
report("Failed to creat sandbox\n");
ret = 1;
goto end;
}
if (
try(logdepth, dir, "ls %s", "line") || /* should return one file name per line since the output is redirected */
try(logdepth, dir, "ls -1 %s", "line") || /* try to force one file name per line */
try(logdepth, dir, "ls --format=single-column %s", "line") || /* for gnu ls */
try(logdepth, dir, "find %s", "line") || /* if ls fails, we try find */
try(logdepth, dir, "ls %s", "word") || /* if that fails too, ls may still have a list in multiple columns */
try(logdepth, dir, "dir %s", "word") || /* or we are on windows where we need to use dir maybe */
try(logdepth, dir, "echo %s/*", "word")) { /* or on a system without ls, dir or anything alike, but shell globbing may still work */
destroy_testdir(logdepth, dir);
ret = 0;
goto end;
}
destroy_testdir(logdepth, dir);
ret = 1;
end:;
db_cd(old_cwd);
free(old_cwd);
return ret;
}
void filelist(int logdepth, const char *dir, int *argc, char ***argv)
{
const char *list_cmd, *method;
char *cmd, *out, *dir_esc;
char *old_cwd;
old_cwd = strclone(db_cwd);
db_cd("/host");
/* make sure these are set to invalid for easier return in case we fail anywhere later */
*argc = -1;
*argv = NULL;
if (!is_dir(dir))
goto end;
require("/internal/filelist/cmd", logdepth, 1);
require("/internal/filelist/method", logdepth, 1);
list_cmd = get("/internal/filelist/cmd");
method = get("/internal/filelist/method");
dir_esc = shell_escape_dup(dir);
cmd = filelist_asmcmd(dir_esc, list_cmd);
free(dir_esc);
run_shell(logdepth+1, cmd, &out);
if (out != NULL) {
filelist_extract(out, dir, method, argc, argv);
logprintf(logdepth, "filelist: Getting list of files in %s\n", dir);
free(out);
}
free(cmd);
end:;
db_cd(old_cwd);
free(old_cwd);
}

View File

@ -1,255 +0,0 @@
/*
scconfig - dependencies
Copyright (C) 2009 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <string.h>
#include "dep.h"
#include "db.h"
#include "log.h"
#include "libs.h"
typedef struct {
int (*fn)(const char *name, int logdepth, int fatal);
} fn_wrap_t;
static ht_t *deps = NULL;
static const char *USER_WITHOUT = "";
/* find name_ and decide if it was a wildcard request;
NOTE: there are requests and servers, both can be wildcard independently.
- if a request ends with a / *, it is an explicit wildcard request (*wild=1)
- if a request names a "directory" that is wildcard-server, that's a wildcard request (*wild=1)
- else the request is a normal request (*wild=0).
For normal requests, a required node was explicitly named; if that node is
not created by the detection function, that's a failure. For wildcard
requests we don't look for any specific node to be created.
TODO: we may still check if at least the directory is created
*/
fn_wrap_t *get_wrap(const char *name_, int *wild, int *missing)
{
fn_wrap_t *w;
char *name, *sep, *tmp;
int len, n;
len = strlen(name_);
*wild = name_[len-1] == '*';
if (*wild) {
char *pres;
pres = malloc(len+16);
memcpy(pres, name_, len-1);
strcpy(pres+len-1, "presents");
*missing = get(pres) == NULL;
if (*missing) { /* if there's no /presents, it may be a non-directory node with an actual non-empty string value */
const char *val;
pres[len-2] = '\0';
val = get(pres);
if (val != NULL)
*missing = !strlen(val);
}
free(pres);
if (!(*missing)) /* already detected, won't be detected again */
return NULL;
}
*missing = 1;
/* check for global --without disable */
tmp = str_concat("", "/arg/without", db_cwd, "/", name_, NULL);
sep = tmp + strlen(tmp) - 1;
for(n = 0; n < 4; n++) {
const char *d = get(tmp);
if (sep < tmp+14)
break;
if (istrue(d)) {
free(tmp);
return (fn_wrap_t *)USER_WITHOUT;
}
while(*sep != '/')
sep--;
*sep = '\0';
}
free(tmp);
/* try full match first */
w = ht_get(deps, name_);
if (w != NULL)
return w;
/* try substituting the last part of the path with * for wildcard matches */
name = malloc(len+3); /* worst case: ends in a / and we need to append *\0; allocate a bit more */
memcpy(name, name_, len+1); /* make a copy we can modify */
if (name[len-1] != '/') {
name[len] = '/'; /* append a / - if name_ was a "directory", this will result in name/ * */
name[len+1] = '\0';
}
*wild = 1; /* if we append a / *, then it's a wildcard request */
for(;;) {
sep = str_rchr(name, '/');
if (sep == NULL)
goto error;
sep[1] = '*';
sep[2] = '\0';
w = ht_get(deps, name);
if (w != NULL) {
free(name);
return w;
}
*sep = '\0';
*wild = 0; /* cutting back the second layer - not wildcard request anymore, but a request to a specific node served by a wildcard */
}
/* no match, exit with error */
error:;
*wild = 0;
free(name);
return NULL;
}
int require(const char *name, int logdepth, int fatal)
{
fn_wrap_t *w;
int wild, missing;
if (get(name) == NULL) {
w = get_wrap(name, &wild, &missing);
if (w == (fn_wrap_t *)USER_WITHOUT) {
if (fatal) {
error("Node %s is required by the software but disabled by the user using --without\n", name);
abort();
}
else {
logprintf(logdepth, "(disabled using --without)");
return 1;
}
}
if (!missing)
return 0;
if ((w == NULL) || (w->fn == NULL)) {
error("Node %s is required but I don't know how to detect it.\n", name);
abort();
}
logprintf(logdepth, "(Required node: '%s')\n", name);
if (w->fn(name, logdepth+1, fatal) != 0) {
if (fatal) {
error("Node %s is required but provided detection callback fails to find that feature on that system.\n", name);
abort();
}
else {
logprintf(logdepth, "(Feature not found, but it is not fatal)");
return 1;
}
}
if ((!wild) && (get(name) == NULL)) {
error("Node %s is required but provided detection callback didn't create it (looks like an internal error in scconfig). (db_cwd='%s')\n", name, db_cwd);
abort();
}
}
return 0;
}
const char *dep_add(const char *name, int (*finder)(const char *name, int logdepth, int fatal))
{
fn_wrap_t *w;
w = malloc(sizeof(fn_wrap_t));
w->fn = finder;
return ht_set(deps, name, w);
}
int asked_for(const char *cando, const char *needtodo)
{
int len;
/* foo/bar/baz matches /foo/bar/baz */
if (strcmp(cando, needtodo) == 0)
goto yes;
len = strlen(needtodo);
if (len == 0)
return 0;
/* foo/bar/baz matches /foo/bar/ * */
if ((needtodo[len-1] == '*') && (strncmp(cando, needtodo, len-1) == 0))
goto yes;
return 0;
yes:; /* asked for it, but have to see if it's already detected */
if (get(cando) != NULL)
return 0;
return 1;
}
int is_dep_wild(const char *path)
{
int len = strlen(path);
if (len == 0)
return 0;
return (path[len-1] == '*');
}
const char *det_list_target(const char *path)
{
const char *res;
if (path == NULL)
goto unk;
res = strrchr(path, '/');
if (res == NULL)
goto unk;
return res + 1;
unk:;
return "<unknown>";
}
void dep_init(void)
{
deps = ht_resize(ht_alloc(0), 128);
}
void dep_uninit(void)
{
ht_free(deps);
}
int is_dep_known(const char *name)
{
return (ht_get(deps, name) != NULL);
}
void require_all(int fatal)
{
ht_entry_t *h;
for(h = ht_first(deps); h != NULL; h = ht_next(deps, h))
require(h->key, 0, fatal);
}

View File

@ -1,611 +0,0 @@
/*
* regex - Regular expression pattern matching and replacement
*
* By: Ozan S. Yigit (oz)
* Dept. of Computer Science
* York University
*
* These routines are the PUBLIC DOMAIN equivalents of regex
* routines as found in 4.nBSD UN*X, with minor extensions.
*
* These routines are derived from various implementations found
* in software tools books, and Conroy's grep. They are NOT derived
* from licensed/restricted software.
* For more interesting/academic/complicated implementations,
* see Henry Spencer's regexp routines, or GNU Emacs pattern
* matching module.
*
* const correctness patch by Tibor 'Igor2' Palinkas in 2009..2010
* new subs code by Tibor 'Igor2' Palinkas in 2015
*/
#include <stdlib.h>
#include <string.h>
#include "regex.h"
#define MAXNFA 1024
#define MAXTAG 10
#define OKP 1
#define NOP 0
#define CHR 1
#define ANY 2
#define CCL 3
#define BOL 4
#define EOL 5
#define BOT 6
#define EOT 7
#define BOW 8
#define EOW 9
#define REF 10
#define CLO 11
#define END 0
/*
* The following defines are not meant to be changeable.
* They are for readability only.
*/
#define MAXCHR 128
#define CHRBIT 8
#define BITBLK MAXCHR/CHRBIT
#define BLKIND 0170
#define BITIND 07
#define ASCIIB 0177
#ifdef NO_UCHAR
typedef char CHAR;
#else
typedef unsigned char CHAR;
#endif
static int tagstk[MAXTAG]; /* subpat tag stack..*/
static CHAR nfa[MAXNFA]; /* automaton.. */
static int sta = NOP; /* status of lastpat */
static CHAR bittab[BITBLK]; /* bit table for CCL */
/* pre-set bits... */
static CHAR bitarr[] = {1,2,4,8,16,32,64,128};
static void
chset(CHAR c)
{
bittab[(CHAR) ((c) & BLKIND) >> 3] |= bitarr[(c) & BITIND];
}
#define badpat(x) (*nfa = END, x)
#define store(x) *mp++ = x
char *
re_comp(const char *pat)
{
register const char *p; /* pattern pointer */
register CHAR *mp=nfa; /* nfa pointer */
register CHAR *lp; /* saved pointer.. */
register CHAR *sp=nfa; /* another one.. */
register int tagi = 0; /* tag stack index */
register int tagc = 1; /* actual tag count */
register int n;
register CHAR mask; /* xor mask -CCL/NCL */
int c1, c2;
if (!pat || !*pat) {
if (sta)
return 0;
else
return badpat("No previous regular expression");
}
sta = NOP;
for (p = pat; *p; p++) {
lp = mp;
switch(*p) {
case '.': /* match any char.. */
store(ANY);
break;
case '^': /* match beginning.. */
if (p == pat)
store(BOL);
else {
store(CHR);
store(*p);
}
break;
case '$': /* match endofline.. */
if (!*(p+1))
store(EOL);
else {
store(CHR);
store(*p);
}
break;
case '[': /* match char class..*/
store(CCL);
if (*++p == '^') {
mask = 0377;
p++;
}
else
mask = 0;
if (*p == '-') /* real dash */
chset(*p++);
if (*p == ']') /* real brac */
chset(*p++);
while (*p && *p != ']') {
if (*p == '-' && *(p+1) && *(p+1) != ']') {
p++;
c1 = *(p-2) + 1;
c2 = *p++;
while (c1 <= c2)
chset((CHAR)c1++);
}
#ifdef EXTEND
else if (*p == '\\' && *(p+1)) {
p++;
chset(*p++);
}
#endif
else
chset(*p++);
}
if (!*p)
return badpat("Missing ]");
for (n = 0; n < BITBLK; bittab[n++] = (char) 0)
store(mask ^ bittab[n]);
break;
case '*': /* match 0 or more.. */
case '+': /* match 1 or more.. */
if (p == pat)
return badpat("Empty closure");
lp = sp; /* previous opcode */
if (*lp == CLO) /* equivalence.. */
break;
switch(*lp) {
case BOL:
case BOT:
case EOT:
case BOW:
case EOW:
case REF:
return badpat("Illegal closure");
default:
break;
}
if (*p == '+')
for (sp = mp; lp < sp; lp++)
store(*lp);
store(END);
store(END);
sp = mp;
while (--mp > lp)
*mp = mp[-1];
store(CLO);
mp = sp;
break;
case '\\': /* tags, backrefs .. */
switch(*++p) {
case '(':
if (tagc < MAXTAG) {
tagstk[++tagi] = tagc;
store(BOT);
store(tagc++);
}
else
return badpat("Too many \\(\\) pairs");
break;
case ')':
if (*sp == BOT)
return badpat("Null pattern inside \\(\\)");
if (tagi > 0) {
store(EOT);
store(tagstk[tagi--]);
}
else
return badpat("Unmatched \\)");
break;
case '<':
store(BOW);
break;
case '>':
if (*sp == BOW)
return badpat("Null pattern inside \\<\\>");
store(EOW);
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
n = *p-'0';
if (tagi > 0 && tagstk[tagi] == n)
return badpat("Cyclical reference");
if (tagc > n) {
store(REF);
store(n);
}
else
return badpat("Undetermined reference");
break;
#ifdef EXTEND
case 'b':
store(CHR);
store('\b');
break;
case 'n':
store(CHR);
store('\n');
break;
case 'f':
store(CHR);
store('\f');
break;
case 'r':
store(CHR);
store('\r');
break;
case 't':
store(CHR);
store('\t');
break;
#endif
default:
store(CHR);
store(*p);
}
break;
default : /* an ordinary char */
store(CHR);
store(*p);
break;
}
sp = lp;
}
if (tagi > 0)
return badpat("Unmatched \\(");
store(END);
sta = OKP;
return 0;
}
static const char *bol;
const char *bopat[MAXTAG];
const char *eopat[MAXTAG];
static const char *pmatch(const char *, CHAR *, int *);
/*
* re_exec:
* execute nfa to find a match.
*
* special cases: (nfa[0])
* BOL
* Match only once, starting from the
* beginning.
* CHR
* First locate the character without
* calling pmatch, and if found, call
* pmatch for the remaining string.
* END
* re_comp failed, poor luser did not
* check for it. Fail fast.
*
* If a match is found, bopat[0] and eopat[0] are set
* to the beginning and the end of the matched fragment,
* respectively.
*
*/
int
re_exec(const char *lp)
{
register CHAR c;
register const char *ep = 0;
register CHAR *ap = nfa;
int score = 1;
bol = lp;
bopat[0] = 0;
bopat[1] = 0;
bopat[2] = 0;
bopat[3] = 0;
bopat[4] = 0;
bopat[5] = 0;
bopat[6] = 0;
bopat[7] = 0;
bopat[8] = 0;
bopat[9] = 0;
switch(*ap) {
case BOL: /* anchored: match from BOL only */
ep = pmatch(lp,ap, &score);
break;
case CHR: /* ordinary char: locate it fast */
c = *(ap+1);
while (*lp && *lp != c)
lp++;
if (!*lp) /* if EOS, fail, else fall thru. */
return 0;
default: /* regular matching all the way. */
#ifdef OLD
while (*lp) {
if ((ep = pmatch(lp,ap, &score)))
break;
lp++;
}
#else /* match null string */
do {
if ((ep = pmatch(lp,ap, &score)))
break;
} while (*lp++);
#endif
break;
case END: /* munged automaton. fail always */
return 0;
}
if (!ep)
return 0;
bopat[0] = lp;
eopat[0] = ep;
return score;
}
/*
* pmatch: internal routine for the hard part
*
* This code is partly snarfed from an early grep written by
* David Conroy. The backref and tag stuff, and various other
* innovations are by oz.
*
* special case optimizations: (nfa[n], nfa[n+1])
* CLO ANY
* We KNOW .* will match everything up to the
* end of line. Thus, directly go to the end of
* line, without recursive pmatch calls. As in
* the other closure cases, the remaining pattern
* must be matched by moving backwards on the
* string recursively, to find a match for xy
* (x is ".*" and y is the remaining pattern)
* where the match satisfies the LONGEST match for
* x followed by a match for y.
* CLO CHR
* We can again scan the string forward for the
* single char and at the point of failure, we
* execute the remaining nfa recursively, same as
* above.
*
* At the end of a successful match, bopat[n] and eopat[n]
* are set to the beginning and end of subpatterns matched
* by tagged expressions (n = 1 to 9).
*
*/
#ifndef re_fail
extern void re_fail(char *, unsigned char);
#endif
/*
* character classification table for word boundary operators BOW
* and EOW. the reason for not using ctype macros is that we can
* let the user add into our own table. see re_modw. This table
* is not in the bitset form, since we may wish to extend it in the
* future for other character classifications.
*
* TRUE for 0-9 A-Z a-z _
*/
static CHAR chrtyp[MAXCHR] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 1, 0, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 0, 0, 0, 0
};
#define inascii(x) (0177&(x))
#define iswordc(x) chrtyp[inascii(x)]
#define isinset(x,y) ((x)[((y)&BLKIND)>>3] & bitarr[(y)&BITIND])
/*
* skip values for CLO XXX to skip past the closure
*/
#define ANYSKIP 2 /* [CLO] ANY END ... */
#define CHRSKIP 3 /* [CLO] CHR chr END ... */
#define CCLSKIP 18 /* [CLO] CCL 16bytes END ... */
static const char *
pmatch(const char *lp, CHAR *ap, int *score)
{
register int op, c, n;
register const char *e; /* extra pointer for CLO */
register const char *bp; /* beginning of subpat.. */
register const char *ep; /* ending of subpat.. */
const char *are; /* to save the line ptr. */
while ((op = *ap++) != END)
switch(op) {
case CHR:
if (*lp++ != *ap++)
return 0;
(*score) += 100;
break;
case ANY:
if (!*lp++)
return 0;
(*score)++;
break;
case CCL:
c = *lp++;
if (!isinset(ap,c))
return 0;
ap += BITBLK;
(*score) += 2;
break;
case BOL:
if (lp != bol)
return 0;
(*score) += 10;
break;
case EOL:
if (*lp)
return 0;
(*score) += 10;
break;
case BOT:
bopat[*ap++] = lp;
break;
case EOT:
eopat[*ap++] = lp;
break;
case BOW:
if ((lp!=bol && iswordc(lp[-1])) || !iswordc(*lp))
return 0;
(*score) += 5;
break;
case EOW:
if (lp==bol || !iswordc(lp[-1]) || iswordc(*lp))
return 0;
(*score) += 5;
break;
case REF:
n = *ap++;
bp = bopat[n];
ep = eopat[n];
while (bp < ep) {
if (*bp++ != *lp++)
return 0;
(*score) += 2;
}
break;
case CLO:
are = lp;
switch(*ap) {
case ANY:
while (*lp)
lp++;
n = ANYSKIP;
(*score)++;
break;
case CHR:
c = *(ap+1);
while (*lp && c == *lp)
lp++;
n = CHRSKIP;
(*score) += 100;
break;
case CCL:
while ((c = *lp) && isinset(ap+1,c))
lp++;
n = CCLSKIP;
(*score) += 2;
break;
default:
re_fail("closure: bad nfa.", *ap);
return 0;
}
ap += n;
while (lp >= are) {
e = pmatch(lp, ap, score);
if (e)
return e;
--lp;
}
return 0;
default:
re_fail("re_exec: bad nfa.", op);
return 0;
}
return lp;
}
/*
* re_modw:
* add new characters into the word table to change re_exec's
* understanding of what a word should look like. Note that we
* only accept additions into the word definition.
*
* If the string parameter is 0 or null string, the table is
* reset back to the default containing A-Z a-z 0-9 _. [We use
* the compact bitset representation for the default table]
*/
static CHAR deftab[16] = {
0, 0, 0, 0, 0, 0, 0377, 003, 0376, 0377, 0377, 0207,
0376, 0377, 0377, 007
};
void
re_modw(char *s)
{
register int i;
if (!s || !*s) {
for (i = 0; i < MAXCHR; i++)
if (!isinset(deftab,i))
iswordc(i) = 0;
}
else
while(*s)
iswordc(*s++) = 1;
}
/* Substitute the matching part in the last re_exec call with sub. The
result is returned in a newly allocated string. */
char *re_subs_dup(char *sub)
{
char *dst;
const char *end;
int l1, l2, l3;
end = bol + strlen(bol);
l1 = bopat[0] - bol;
if (sub != NULL)
l2 = strlen(sub);
else
l2 = 0;
l3 = end - eopat[0];
if (l3 < 0)
l3 = 0;
dst = malloc(l1+l2+l3+1);
memcpy(dst, bol, l1);
if (l2 != 0)
memcpy(dst+l1, sub, l2);
memcpy(dst+l1+l2, eopat[0], l3+1);
return dst;
}

View File

@ -1,8 +0,0 @@
int main_init(void);
int main_process_args(int argc, char *argv[]);
void main_uninit(void);
/* internal */
void init(void);
void uninit(void);
void run_custom_reqs(void);

Binary file not shown.

View File

@ -1 +0,0 @@
12

View File

@ -1 +0,0 @@
12

View File

@ -1,125 +0,0 @@
/*
scconfig - gui lib detection - gtk2
Copyright (C) 2013 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
static const char *node = "libs/gui/gtk2";
static const char *nodegl = "libs/gui/gtk2gl";
static const char *pkgname = "gtk+-2.0";
static const char *pkgnamegl = "gtkglext-x11-1.0";
int find_gtk2(const char *name, int logdepth, int fatal, const char *call, const char *arg)
{
const char *test_c =
NL "#include <gtk/gtk.h>"
NL "#include <stdlib.h>"
NL
NL "int main(int argc, char *argv[])"
NL "{"
NL " GtkWidget* mainWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);"
NL " gtk_window_set_default_size(GTK_WINDOW(mainWindow), 500, 500);"
NL " gtk_window_set_title(GTK_WINDOW(mainWindow), \"foobar\");"
NL " gtk_widget_show_all(mainWindow);"
NL " gtk_main();"
NL " return EXIT_SUCCESS;"
NL "}"
NL;
char *cflags;
char *ldflags;
(void) call; /* not used */
(void) arg; /* not used */
if (require("cc/cc", logdepth, fatal))
return try_fail(logdepth, node);
report("Checking for gtk+2... ");
logprintf(logdepth, "find_gtk2: running pkg-config...\n");
logdepth++;
if (run_pkg_config(logdepth, pkgname, &cflags, &ldflags) != 0) {
return try_fail(logdepth, node);
}
if (try_icl_norun(logdepth, node, test_c, NULL, cflags, ldflags) == 0) {
free(cflags);
free(ldflags);
return try_fail(logdepth, node);
}
free(cflags);
free(ldflags);
return 0;
}
int find_gtk2gl(const char *name, int logdepth, int fatal, const char *call, const char *arg)
{
const char *test_c =
NL "#include <gtk/gtk.h>"
NL "#include <gtk/gtkgl.h>"
NL "#include <stdlib.h>"
NL
NL "int main(int argc, char *argv[])"
NL "{"
NL " gtk_gl_init(&argc, &argv);"
NL " return EXIT_SUCCESS;"
NL "}"
NL;
char *cflags;
char *ldflags;
(void) call; /* not used */
(void) arg; /* not used */
if (require("cc/cc", logdepth, fatal))
return try_fail(logdepth, nodegl);
report("Checking for gtk+2 with GL... ");
logprintf(logdepth, "find_gtk2gl: running pkg-config...\n");
logdepth++;
if (run_pkg_config(logdepth, pkgnamegl, &cflags, &ldflags) != 0) {
return try_fail(logdepth, nodegl);
}
if (try_icl_norun(logdepth, nodegl, test_c, NULL, cflags, ldflags) == 0) {
free(cflags);
free(ldflags);
return try_fail(logdepth, nodegl);
}
free(cflags);
free(ldflags);
return 0;
}
int find_gtk2_modversion(const char *name, int logdepth, int fatal)
{
if (run_pkg_config_modversion_db(logdepth, node, pkgname) != 0)
return try_fail(logdepth, node);
return 0;
}

View File

@ -1,100 +0,0 @@
/*
scconfig - gui lib detection - cairo
Copyright (C) 2017 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
int find_cairo(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <stdlib.h>"
NL "#include <stdio.h>"
NL "#include \"cairo.h\""
NL "int main() {"
NL " cairo_t *ctx;"
NL " cairo_surface_t *surf;"
NL
NL " if (cairo_image_surface_create(CAIRO_FORMAT_RGB24, 100, 100) != NULL)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char *node = "libs/gui/cairo";
char *cflags = NULL;
char *ldflags = NULL;
if (require("cc/cc", logdepth, fatal))
return try_fail(logdepth, node);
report("Checking for cairo... ");
logprintf(logdepth, "find_cairo: running pkg-config...\n");
logdepth++;
if (run_pkg_config(logdepth, "cairo", &cflags, &ldflags) == 0) {
if (try_icl(logdepth, node, test_c, NULL, cflags, ldflags) != 0)
goto success;
}
return try_fail(logdepth, node);
success:;
if (cflags != NULL)
free(cflags);
if (ldflags != NULL)
free(ldflags);
return 0;
}
int find_cairo_xcb(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <stdlib.h>"
NL "#include <stdio.h>"
NL "int main()"
NL "{"
NL " if (cairo_xcb_device_debug_get_precision(NULL) == -1)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char *node = "libs/gui/cairo-xcb", *cflags, *ldflags;
if (require("libs/gui/cairo", logdepth, fatal))
return try_fail(logdepth, node);
report("Checking for cairo-xcb... ");
logprintf(logdepth, "find_cairo-xcb: \n");
logdepth++;
cflags = get("libs/gui/cairo/cflags");
ldflags = get("libs/gui/cairo/ldflags");
if (try_icl(logdepth, node, test_c, "#include <cairo-xcb.h>", cflags, ldflags) != 0)
return 0;
return try_fail(logdepth, node);
}

View File

@ -1,2 +0,0 @@
int find_cairo(const char *name, int logdepth, int fatal);

View File

@ -1,8 +0,0 @@
int find_xinerama(const char *name, int logdepth, int fatal);
int find_xrender(const char *name, int logdepth, int fatal);
int find_xopendisplay(const char *name, int logdepth, int fatal);
int find_xcb(const char *name, int logdepth, int fatal);
int find_xcb_render(const char *name, int logdepth, int fatal);
int find_xgetxcbconnection(const char *name, int logdepth, int fatal);
int find_xpm(const char *name, int logdepth, int fatal);

View File

@ -1 +0,0 @@
int find_libstroke(const char *name, int logdepth, int fatal);

View File

@ -1,2 +0,0 @@
int find_gtk3(const char *name, int logdepth, int fatal);

View File

@ -1,40 +0,0 @@
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
#include "find_x.h"
#include "find_gtk2.h"
#include "find_gtk3.h"
#include "find_lesstif2.h"
#include "find_gd.h"
#include "find_cairo.h"
#include "find_misc.h"
#include "find_gl.h"
void deps_gui_init()
{
dep_add("libs/gui/xopendisplay/*", find_xopendisplay);
dep_add("libs/gui/xinerama/*", find_xinerama);
dep_add("libs/gui/xrender/*", find_xrender);
dep_add("libs/gui/xcb/*", find_xcb);
dep_add("libs/gui/xcb_render/*", find_xcb_render);
dep_add("libs/gui/xgetxcbconnection/*", find_xgetxcbconnection);
dep_add("libs/gui/xpm/*", find_xpm);
dep_add("libs/gui/gtk2/*", find_gtk2);
dep_add("libs/gui/gtk2gl/*", find_gtk2gl);
dep_add("libs/gui/gtk2/modversion", find_gtk2_modversion);
dep_add("libs/gui/gtk3/*", find_gtk3);
dep_add("libs/gui/lesstif2/*", find_lesstif2);
dep_add("libs/gui/libstroke/*", find_libstroke);
dep_add("libs/gui/gd/gdImagePng/*", find_gdimagepng);
dep_add("libs/gui/gd/gdImageGif/*", find_gdimagegif);
dep_add("libs/gui/gd/gdImageJpeg/*", find_gdimagejpeg);
dep_add("libs/gui/gd/gdImageSetResolution/*", find_gdimagesetresolution);
dep_add("libs/gui/gd/*", find_gd);
dep_add("libs/gui/cairo/*", find_cairo);
dep_add("libs/gui/gl/*", find_gl);
dep_add("libs/gui/glu/*", find_glu);
dep_add("libs/gui/glut/*", find_glut);
dep_add("libs/gui/wgl/*", find_gui_wgl);
}

View File

@ -1,70 +0,0 @@
/*
scconfig - gui lib detection - cairo
Copyright (C) 2017 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
int find_cairo(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <stdlib.h>"
NL "#include <stdio.h>"
NL "#include \"cairo.h\""
NL "int main() {"
NL " cairo_t *ctx;"
NL " cairo_surface_t *surf;"
NL
NL " if (cairo_image_surface_create(CAIRO_FORMAT_RGB24, 100, 100) != NULL)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char *node = "libs/gui/cairo";
char *cflags = NULL;
char *ldflags = NULL;
if (require("cc/cc", logdepth, fatal))
return try_fail(logdepth, node);
report("Checking for cairo... ");
logprintf(logdepth, "find_cairo: running pkg-config...\n");
logdepth++;
if (run_pkg_config(logdepth, "cairo", &cflags, &ldflags) == 0) {
if (try_icl(logdepth, node, test_c, NULL, cflags, ldflags) != 0)
goto success;
}
return try_fail(logdepth, node);
success:;
if (cflags != NULL)
free(cflags);
if (ldflags != NULL)
free(ldflags);
return 0;
}

View File

@ -1,171 +0,0 @@
/*
scconfig - gui lib detection - gtk2
Copyright (C) 2013 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
static const char *node = "libs/gui/gtk2";
static const char *nodegl = "libs/gui/gtk2gl";
static const char *pkgname = "gtk+-2.0";
static const char *pkgnamegl = "gtkglext-x11-1.0";
int find_gtk2(const char *name, int logdepth, int fatal, const char *call, const char *arg)
{
const char *test_c =
NL "#include <gtk/gtk.h>"
NL "#include <stdlib.h>"
NL
NL "int main(int argc, char *argv[])"
NL "{"
NL " GtkWidget* mainWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);"
NL " gtk_window_set_default_size(GTK_WINDOW(mainWindow), 500, 500);"
NL " gtk_window_set_title(GTK_WINDOW(mainWindow), \"foobar\");"
NL " gtk_widget_show_all(mainWindow);"
NL " gtk_main();"
NL " return EXIT_SUCCESS;"
NL "}"
NL;
char *cflags;
char *ldflags;
(void) call; /* not used */
(void) arg; /* not used */
if (require("cc/cc", logdepth, fatal))
return try_fail(logdepth, node);
report("Checking for gtk+2... ");
logprintf(logdepth, "find_gtk2: running pkg-config...\n");
logdepth++;
if (run_pkg_config(logdepth, pkgname, &cflags, &ldflags) != 0) {
return try_fail(logdepth, node);
}
if (try_icl_norun(logdepth, node, test_c, NULL, cflags, ldflags) == 0) {
free(cflags);
free(ldflags);
return try_fail(logdepth, node);
}
free(cflags);
free(ldflags);
return 0;
}
int find_gtk2gl(const char *name, int logdepth, int fatal, const char *call, const char *arg)
{
const char *test_c =
NL "#include <gtk/gtk.h>"
NL "#include <gtk/gtkgl.h>"
NL "#include <stdlib.h>"
NL
NL "int main(int argc, char *argv[])"
NL "{"
NL " gtk_gl_init(&argc, &argv);"
NL " return EXIT_SUCCESS;"
NL "}"
NL;
char *cflags;
char *ldflags;
(void) call; /* not used */
(void) arg; /* not used */
if (require("cc/cc", logdepth, fatal))
return try_fail(logdepth, nodegl);
report("Checking for gtk+2 with GL... ");
logprintf(logdepth, "find_gtk2gl: running pkg-config...\n");
logdepth++;
if (run_pkg_config(logdepth, pkgnamegl, &cflags, &ldflags) != 0) {
return try_fail(logdepth, nodegl);
}
if (try_icl_norun(logdepth, nodegl, test_c, NULL, cflags, ldflags) == 0) {
free(cflags);
free(ldflags);
return try_fail(logdepth, nodegl);
}
free(cflags);
free(ldflags);
return 0;
}
int find_gtk2_key_prefix(const char *name, int logdepth, int fatal)
{
const char *node = "libs/gui/gtk2/key_prefix";
char test_c[512];
const char *test_c_ =
NL "#include <gdk/gdkkeysyms.h>"
NL "#include <stdlib.h>"
NL
NL "int main(int argc, char *argv[])"
NL "{"
NL " if (%s != 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char *includes, *cflags, *ldflags;
if (require("libs/gui/gtk2/cflags", logdepth, fatal))
return try_fail(logdepth, node);
report("Checking for gtk+2 key prefix... ");
logprintf(logdepth, "Checking for gtk+2 key prefix...\n");
logdepth++;
includes = get("libs/gui/gtk2/includes");
cflags = get("libs/gui/gtk2/cflags");
ldflags = get("libs/gui/gtk2/ldflags");
sprintf(test_c, test_c_, "GDK_KEY_Tab");
if (try_icl(logdepth, node, test_c, includes, cflags, ldflags)) {
report("GDK_KEY_\n");
put(node, "GDK_KEY_");
return 0;
}
sprintf(test_c, test_c_, "GDK_Tab");
if (try_icl(logdepth, node, test_c, includes, cflags, ldflags)) {
report("GDK_\n");
put(node, "GDK_");
return 0;
}
return try_fail(logdepth, node);
}
int find_gtk2_modversion(const char *name, int logdepth, int fatal)
{
if (run_pkg_config_modversion_db(logdepth, node, pkgname) != 0)
return try_fail(logdepth, node);
return 0;
}

View File

@ -1,39 +0,0 @@
GUI_CFLAGS = -DPLUGIN_GUI
GUI_OBJS = \
$(BIN)/gui/find_gtk2.o \
$(BIN)/gui/find_gtk3.o \
$(BIN)/gui/find_lesstif2.o \
$(BIN)/gui/find_x.o \
$(BIN)/gui/find_gd.o \
$(BIN)/gui/find_cairo.o \
$(BIN)/gui/find_misc.o \
$(BIN)/gui/find_gl.o \
$(BIN)/gui/gui.o
$(BIN)/gui/find_gtk2.o: $(SRC)/gui/find_gtk2.c
$(CC) $(CFLAGS) -c $(SRC)/gui/find_gtk2.c -o $(BIN)/gui/find_gtk2.o
$(BIN)/gui/find_gtk3.o: $(SRC)/gui/find_gtk3.c
$(CC) $(CFLAGS) -c $(SRC)/gui/find_gtk3.c -o $(BIN)/gui/find_gtk3.o
$(BIN)/gui/find_lesstif2.o: $(SRC)/gui/find_lesstif2.c
$(CC) $(CFLAGS) -c $(SRC)/gui/find_lesstif2.c -o $(BIN)/gui/find_lesstif2.o
$(BIN)/gui/find_x.o: $(SRC)/gui/find_x.c
$(CC) $(CFLAGS) -c $(SRC)/gui/find_x.c -o $(BIN)/gui/find_x.o
$(BIN)/gui/find_gd.o: $(SRC)/gui/find_gd.c
$(CC) $(CFLAGS) -c $(SRC)/gui/find_gd.c -o $(BIN)/gui/find_gd.o
$(BIN)/gui/find_misc.o: $(SRC)/gui/find_misc.c
$(CC) $(CFLAGS) -c $(SRC)/gui/find_misc.c -o $(BIN)/gui/find_misc.o
$(BIN)/gui/find_gl.o: $(SRC)/gui/find_gl.c
$(CC) $(CFLAGS) -c $(SRC)/gui/find_gl.c -o $(BIN)/gui/find_gl.o
$(BIN)/gui/find_cairo.o: $(SRC)/gui/find_cairo.c
$(CC) $(CFLAGS) -c $(SRC)/gui/find_cairo.c -o $(BIN)/gui/find_cairo.o
$(BIN)/gui/gui.o: $(SRC)/gui/gui.c
$(CC) $(CFLAGS) -c $(SRC)/gui/gui.c -o $(BIN)/gui/gui.o

View File

@ -1,6 +0,0 @@
int find_gd(const char *name, int logdepth, int fatal);
int find_gdimagepng(const char *name, int logdepth, int fatal);
int find_gdimagegif(const char *name, int logdepth, int fatal);
int find_gdimagejpeg(const char *name, int logdepth, int fatal);
int find_gdimagesetresolution(const char *name, int logdepth, int fatal);

View File

@ -1,67 +0,0 @@
/*
scconfig - gui lib detection - misc libs
Copyright (C) 2016 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
int find_libstroke(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <stdlib.h>"
NL "#include <stroke.h>"
NL "int main()"
NL "{"
NL " char msg[256];"
NL " int n;"
NL " stroke_init();"
NL " for(n = 1000; n < 2000; n+=123)"
NL " stroke_record(n, 1000);"
NL " stroke_trans(msg);"
NL " return !(atoi(msg) == 456);"
NL "}"
NL;
const char *node = "libs/gui/libstroke";
char **cflags, *cflags_arr[] = {"", NULL};
char **ldflags, *ldflags_arr[] = {"-lstroke", NULL};
if (require("cc/cc", logdepth, fatal))
return 1;
report("Checking for libstroke... ");
logprintf(logdepth, "find_libstroke:\n");
logdepth++;
for(cflags = cflags_arr; *cflags != NULL; cflags++) {
for(ldflags = ldflags_arr; *ldflags != NULL; ldflags++) {
if (try_icl_norun(logdepth, node, test_c, NULL, *cflags, *ldflags) != 0) {
return 0;
}
}
}
return try_fail(logdepth, node);
}

View File

@ -1,240 +0,0 @@
/*
scconfig - gui lib detection - libgd
Copyright (C) 2013 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
int find_gd(const char *name, int logdepth, int fatal, const char *call, const char *arg)
{
const char *test_c =
NL "#include \"gd.h\""
NL "int main() {"
NL " gdImagePtr imtype;"
NL
NL " if (gdImageCreateTrueColor(32, 32) != NULL)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char *node = "libs/gui/gd";
char *cflags = NULL;
char *ldflags = NULL;
(void) call; /* not used */
(void) arg; /* not used */
if (require("cc/cc", logdepth, fatal))
return try_fail(logdepth, node);
report("Checking for gd... ");
logprintf(logdepth, "find_gd: running pkg-config...\n");
logdepth++;
if (run_pkg_config(logdepth, "gdlib", &cflags, &ldflags) == 0) {
if (try_icl(logdepth, node, test_c, NULL, cflags, ldflags) != 0)
goto success;
}
if ((run_gen_config(logdepth, "gdlib-config", "", &cflags, &ldflags) == 0) || (run_pkg_config(logdepth, "gdlib", &cflags, &ldflags) == 0)) {
char *tmp;
if (try_icl(logdepth, node, test_c, NULL, cflags, ldflags) != 0)
goto success;
/* Some versions of gdlib-config --libs is broken and does not return -lgd */
tmp = ldflags;
ldflags = str_concat(" ", ldflags, "-lgd", NULL);
free(tmp);
if (try_icl(logdepth, node, test_c, NULL, cflags, ldflags) != 0)
goto success;
/* none of the above worked, fail */
free(cflags);
free(ldflags);
return try_fail(logdepth, node);
}
return try_fail(logdepth, node);
success:;
if (cflags != NULL)
free(cflags);
if (ldflags != NULL)
free(ldflags);
return 0;
}
int find_gdimagepng(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <stdio.h>"
NL "#include \"gd.h\""
NL "int main() {"
NL " gdImagePtr img;"
NL
NL " if ((img = gdImageCreateTrueColor(32, 32)) == NULL)"
NL " return 1;"
NL " gdImagePng(img, stderr);"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char *node = "libs/gui/gd/gdImagePng";
const char *cflags, *ldflags;
if (require("cc/cc", logdepth, fatal))
return 1;
if (require("libs/gui/gd/presents", logdepth, fatal))
return 1;
if (!istrue(get("libs/gui/gd/presents")))
return 1;
cflags = get("libs/gui/gd/cflags");
ldflags = get("libs/gui/gd/ldflags");
report("Checking for gdImagePng... ");
logprintf(logdepth, "find_gdimagepng: running pkg-config...\n");
logdepth++;
if (try_icl(logdepth, node, test_c, NULL, cflags, ldflags) == 0)
return try_fail(logdepth, node);
return 0;
}
int find_gdimagejpeg(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <stdio.h>"
NL "#include \"gd.h\""
NL "int main() {"
NL " gdImagePtr img;"
NL
NL " if ((img = gdImageCreateTrueColor(32, 32)) == NULL)"
NL " return 1;"
NL " gdImageJpeg(img, stderr, 0.5);"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char *node = "libs/gui/gd/gdImageJpeg";
const char *cflags, *ldflags;
if (require("cc/cc", logdepth, fatal))
return 1;
if (require("libs/gui/gd/presents", logdepth, fatal))
return 1;
if (!istrue(get("libs/gui/gd/presents")))
return 1;
cflags = get("libs/gui/gd/cflags");
ldflags = get("libs/gui/gd/ldflags");
report("Checking for gdImageJpeg... ");
logprintf(logdepth, "find_gdimagejpeg: running pkg-config...\n");
logdepth++;
if (try_icl(logdepth, node, test_c, NULL, cflags, ldflags) == 0)
return try_fail(logdepth, node);
return 0;
}
int find_gdimagegif(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <stdio.h>"
NL "#include \"gd.h\""
NL "int main() {"
NL " gdImagePtr img;"
NL
NL " if ((img = gdImageCreateTrueColor(32, 32)) == NULL)"
NL " return 1;"
NL " gdImageGif(img, stderr);"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char *node = "libs/gui/gd/gdImageGif";
const char *cflags, *ldflags;
if (require("cc/cc", logdepth, fatal))
return 1;
if (require("libs/gui/gd/presents", logdepth, fatal))
return 1;
if (!istrue(get("libs/gui/gd/presents")))
return 1;
cflags = get("libs/gui/gd/cflags");
ldflags = get("libs/gui/gd/ldflags");
report("Checking for gdImageGif... ");
logprintf(logdepth, "find_gdimagesetresolution: running pkg-config...\n");
logdepth++;
if (try_icl(logdepth, node, test_c, NULL, cflags, ldflags) == 0)
return try_fail(logdepth, node);
return 0;
}
int find_gdimagesetresolution(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <stdio.h>"
NL "#include \"gd.h\""
NL "int main() {"
NL " gdImagePtr img;"
NL
NL " if ((img = gdImageCreateTrueColor(32, 32)) == NULL)"
NL " return 1;"
NL " gdImageSetResolution(img, 100, 100);"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char *node = "libs/gui/gd/gdImageSetResolution";
const char *cflags, *ldflags;
if (require("cc/cc", logdepth, fatal))
return 1;
if (require("libs/gui/gd/presents", logdepth, fatal))
return 1;
if (!istrue(get("libs/gui/gd/presents")))
return 1;
cflags = get("libs/gui/gd/cflags");
ldflags = get("libs/gui/gd/ldflags");
report("Checking for gdImageSetResolution... ");
logprintf(logdepth, "find_gdimagesetresolution: running pkg-config...\n");
logdepth++;
if (try_icl(logdepth, node, test_c, NULL, cflags, ldflags) == 0)
return try_fail(logdepth, node);
return 0;
}

View File

@ -1,69 +0,0 @@
/*
scconfig - gui lib detection - lesstif
Copyright (C) 2015 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
int find_lesstif2(const char *name, int logdepth, int fatal, const char *call, const char *arg)
{
const char *test_c =
NL "#include <Xm/MainW.h>"
NL "int main(int argc, char *argv[])"
NL "{"
NL " XtAppContext context;"
NL " Display *dsp;"
NL " Colormap cmap;"
NL " XColor color;"
NL " Widget toplevel;"
NL " toplevel = XtAppInitialize(& context, \"\", NULL, 0, &argc, argv, NULL, NULL, 0);"
NL " XAllocColor(dsp, cmap, &color);"
NL " return toplevel != NULL;"
NL "}"
NL;
const char *node = "libs/gui/lesstif2";
char **cflags, *cflags_arr[] = {"", "-I/opt/X11/include", NULL};
char **ldflags, *ldflags_arr[] = {"-lXm -lX11", "-lXm -lXt", "-L/opt/X11/lib -lXm -lXt -lX11", NULL}; /* note: -lXt must be after -lXm else lesstif fails to init with runtime error */
(void) call; /* not used */
(void) arg; /* not used */
if (require("cc/cc", logdepth, fatal))
return 1;
report("Checking for lesstif2... ");
logprintf(logdepth, "find_lesstif:\n");
logdepth++;
for(cflags = cflags_arr; *cflags != NULL; cflags++) {
for(ldflags = ldflags_arr; *ldflags != NULL; ldflags++) {
if (try_icl_norun(logdepth, node, test_c, NULL, *cflags, *ldflags) != 0) {
return 0;
}
}
}
return try_fail(logdepth, node);
}

View File

@ -1,41 +0,0 @@
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
#include "find_x.h"
#include "find_gtk2.h"
#include "find_gtk3.h"
#include "find_lesstif2.h"
#include "find_gd.h"
#include "find_cairo.h"
#include "find_misc.h"
#include "find_gl.h"
void deps_gui_init()
{
dep_add("libs/gui/xopendisplay/*", find_xopendisplay);
dep_add("libs/gui/xinerama/*", find_xinerama);
dep_add("libs/gui/xrender/*", find_xrender);
dep_add("libs/gui/xcb/*", find_xcb);
dep_add("libs/gui/xcb_render/*", find_xcb_render);
dep_add("libs/gui/xgetxcbconnection/*", find_xgetxcbconnection);
dep_add("libs/gui/xpm/*", find_xpm);
dep_add("libs/gui/gtk2/*", find_gtk2);
dep_add("libs/gui/gtk2gl/*", find_gtk2gl);
dep_add("libs/gui/gtk2/modversion", find_gtk2_modversion);
dep_add("libs/gui/gtk3/*", find_gtk3);
dep_add("libs/gui/lesstif2/*", find_lesstif2);
dep_add("libs/gui/libstroke/*", find_libstroke);
dep_add("libs/gui/gd/gdImagePng/*", find_gdimagepng);
dep_add("libs/gui/gd/gdImageGif/*", find_gdimagegif);
dep_add("libs/gui/gd/gdImageJpeg/*", find_gdimagejpeg);
dep_add("libs/gui/gd/gdImageSetResolution/*", find_gdimagesetresolution);
dep_add("libs/gui/gd/*", find_gd);
dep_add("libs/gui/cairo/*", find_cairo);
dep_add("libs/gui/cairo-xcb/*", find_cairo_xcb);
dep_add("libs/gui/gl/*", find_gl);
dep_add("libs/gui/glu/*", find_glu);
dep_add("libs/gui/glut/*", find_glut);
dep_add("libs/gui/wgl/*", find_gui_wgl);
}

View File

@ -1,322 +0,0 @@
/*
scconfig - gui lib detection - lesstif
Copyright (C) 2015 Tibor Palinkas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Project page: http://repo.hu/projects/scconfig
Contact via email: scconfig [at] igor2.repo.hu
*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
int find_xopendisplay(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <X11/Xlib.h>"
NL "#include <stdlib.h>"
NL "int main()"
NL "{"
NL " Display *d = XOpenDisplay(NULL);"
NL " return 0;"
NL "}"
NL;
const char *node = "libs/gui/xopendisplay";
char **cflags, *cflags_arr[] = {"", "-I/opt/X11/include", "-I/usr/X11R6/include", NULL};
char **ldflags, *ldflags_arr[] = {"-lX11", "-L/opt/X11/lib -lX11", "-L/usr/X11R6/lib -lX11", NULL};
char **Lflags, *Lflags_arr[] = {"", "-L/opt/X11/lib", "-L/usr/X11R6/lib", NULL};
if (require("cc/cc", logdepth, fatal))
return 1;
report("Checking for XOpenDisplay... ");
logprintf(logdepth, "find_xopendisplay:\n");
logdepth++;
for(cflags = cflags_arr; *cflags != NULL; cflags++) {
for(ldflags = ldflags_arr, Lflags = Lflags_arr; *ldflags != NULL; ldflags++,Lflags++) {
if (try_icl_norun(logdepth, node, test_c, NULL, *cflags, *ldflags) != 0) {
put("libs/gui/xopendisplay/Lflags", *Lflags);
return 0;
}
}
}
return try_fail(logdepth, node);
}
int find_xinerama(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <X11/Xlib.h>"
NL "#include <stdlib.h>"
NL "int main()"
NL "{"
NL " Display *d = XOpenDisplay(NULL);"
NL " if (d != NULL)"
NL " XineramaIsActive(d);"
NL " return 0;"
NL "}"
NL;
const char *node = "libs/gui/xinerama";
char **cflags, *cflags_arr[] = {"", NULL};
char **ldflags, *ldflags_arr[] = {"-lXinerama", NULL};
const char *xincludes, *xcflags, *xldflags;
if (require("cc/cc", logdepth, fatal))
return 1;
if (require("libs/gui/xopendisplay/*", logdepth, fatal))
return 1;
xincludes = get("libs/gui/xopendisplay/includes");
xcflags = get("libs/gui/xopendisplay/cflags");
xldflags = get("libs/gui/xopendisplay/ldflags");
report("Checking for Xinerama... ");
logprintf(logdepth, "find_xinerama:\n");
logdepth++;
for(cflags = cflags_arr; *cflags != NULL; cflags++) {
for(ldflags = ldflags_arr; *ldflags != NULL; ldflags++) {
if (try_icl_with_deps(logdepth, node, test_c, NULL, *cflags, *ldflags, xincludes, xcflags, xldflags, 0) != 0) {
return 0;
}
}
}
return try_fail(logdepth, node);
}
int find_xrender(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <X11/Xlib.h>"
NL "#include <X11/extensions/Xrender.h>"
NL "#include <stdlib.h>"
NL "int main()"
NL "{"
NL " Display *d = XOpenDisplay(NULL);"
NL " XRenderFreePicture (d, 0);"
NL " return 0;"
NL "}"
NL;
const char *node = "libs/gui/xrender";
char **cflags, *cflags_arr[] = {"", NULL};
char **ldflags, *ldflags_arr[] = {"-lXrender", NULL};
const char *xincludes, *xcflags, *xldflags;
if (require("cc/cc", logdepth, fatal))
return 1;
if (require("libs/gui/xopendisplay/*", logdepth, fatal))
return 1;
xincludes = get("libs/gui/xopendisplay/includes");
xcflags = get("libs/gui/xopendisplay/cflags");
xldflags = get("libs/gui/xopendisplay/ldflags");
report("Checking for Xrender... ");
logprintf(logdepth, "find_xrender:\n");
logdepth++;
for(cflags = cflags_arr; *cflags != NULL; cflags++) {
for(ldflags = ldflags_arr; *ldflags != NULL; ldflags++) {
if (try_icl_with_deps(logdepth, node, test_c, NULL, *cflags, *ldflags, xincludes, xcflags, xldflags, 0) != 0) {
return 0;
}
}
}
return try_fail(logdepth, node);
}
int find_xcb(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <stdio.h>"
NL "#include <string.h>"
NL "#include <X11/Xlib-xcb.h>"
NL "int main()"
NL "{"
NL " char *host;"
NL " int display, screen;"
NL " if (xcb_parse_display(\"ford:42.8\", &host, &display, &screen) == 0) return 0;"
NL " if ((strcmp(host, \"ford\") == 0) && (display == 42) && (screen == 8))"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char *node = "libs/gui/xcb";
char **cflags, *cflags_arr[] = {"", NULL};
char **ldflags, *ldflags_arr[] = {"-lxcb", NULL};
const char *xincludes, *xcflags, *xldflags;
if (require("cc/cc", logdepth, fatal))
return 1;
if (require("libs/gui/xopendisplay/*", logdepth, fatal))
return 1;
xincludes = get("libs/gui/xopendisplay/includes");
xcflags = get("libs/gui/xopendisplay/cflags");
xldflags = get("libs/gui/xopendisplay/ldflags");
report("Checking for xcb... ");
logprintf(logdepth, "find_xcb:\n");
logdepth++;
for(cflags = cflags_arr; *cflags != NULL; cflags++) {
for(ldflags = ldflags_arr; *ldflags != NULL; ldflags++) {
if (try_icl_with_deps(logdepth, node, test_c, NULL, *cflags, *ldflags, xincludes, xcflags, xldflags, 1) != 0) {
return 0;
}
}
}
return try_fail(logdepth, node);
}
int find_xgetxcbconnection(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <stdio.h>"
NL "#include <string.h>"
NL "#include <X11/Xlib-xcb.h>"
NL "int main()"
NL "{"
NL " XGetXCBConnection(NULL);"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char *node = "libs/gui/xgetxcbconnection";
char **cflags, *cflags_arr[] = {"", NULL};
char **ldflags, *ldflags_arr[] = {"-lX11-xcb", NULL};
const char *xincludes, *xcflags, *xldflags;
if (require("cc/cc", logdepth, fatal))
return 1;
if (require("libs/gui/xopendisplay/*", logdepth, fatal))
return 1;
xincludes = get("libs/gui/xopendisplay/includes");
xcflags = get("libs/gui/xopendisplay/cflags");
xldflags = get("libs/gui/xopendisplay/ldflags");
report("Checking for xgetxcbconnection... ");
logprintf(logdepth, "find_xgetxcbconnection:\n");
logdepth++;
for(cflags = cflags_arr; *cflags != NULL; cflags++) {
for(ldflags = ldflags_arr; *ldflags != NULL; ldflags++) {
if (try_icl_with_deps(logdepth, node, test_c, NULL, *cflags, *ldflags, xincludes, xcflags, xldflags, 0) != 0) {
return 0;
}
}
}
return try_fail(logdepth, node);
}
int find_xcb_render(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <stdio.h>"
NL "#include <string.h>"
NL "#include <xcb/render.h>"
NL "int main()"
NL "{"
NL " xcb_render_query_pict_formats_formats(NULL);"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char *node = "libs/gui/xcb_render";
char **cflags, *cflags_arr[] = {"", NULL};
char **ldflags, *ldflags_arr[] = {"-lxcb-render", NULL};
const char *xincludes, *xcflags, *xldflags;
if (require("cc/cc", logdepth, fatal))
return 1;
if (require("libs/gui/xopendisplay/*", logdepth, fatal))
return 1;
xincludes = get("libs/gui/xopendisplay/includes");
xcflags = get("libs/gui/xopendisplay/cflags");
xldflags = get("libs/gui/xopendisplay/ldflags");
report("Checking for xcb_render... ");
logprintf(logdepth, "find_xcb_render:\n");
logdepth++;
for(cflags = cflags_arr; *cflags != NULL; cflags++) {
for(ldflags = ldflags_arr; *ldflags != NULL; ldflags++) {
if (try_icl_with_deps(logdepth, node, test_c, NULL, *cflags, *ldflags, xincludes, xcflags, xldflags, 0) != 0) {
return 0;
}
}
}
return try_fail(logdepth, node);
}
int find_xpm(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <stdio.h>"
NL "#include <X11/xpm.h>"
NL "int main()"
NL "{"
NL " if (XpmLibraryVersion() == XpmIncludeVersion)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char *node = "libs/gui/xpm";
char **cflags, *cflags_arr[] = {"", NULL};
char **ldflags, *ldflags_arr[] = {"-lXpm", NULL};
const char *xincludes, *xcflags, *xldflags;
if (require("cc/cc", logdepth, fatal))
return 1;
if (require("libs/gui/xopendisplay/*", logdepth, fatal))
return 1;
xincludes = get("libs/gui/xopendisplay/includes");
xcflags = get("libs/gui/xopendisplay/cflags");
xldflags = get("libs/gui/xopendisplay/ldflags");
report("Checking for xpm... ");
logprintf(logdepth, "find_xpm:\n");
logdepth++;
for(cflags = cflags_arr; *cflags != NULL; cflags++) {
for(ldflags = ldflags_arr; *ldflags != NULL; ldflags++) {
if (try_icl_with_deps(logdepth, node, test_c, NULL, *cflags, *ldflags, xincludes, xcflags, xldflags, 1) != 0) {
return 0;
}
}
}
return try_fail(logdepth, node);
}

View File

@ -1,2 +0,0 @@
int find_lesstif2(const char *name, int logdepth, int fatal);

View File

@ -1,4 +0,0 @@
int find_gl(const char *name, int logdepth, int fatal);
int find_glu(const char *name, int logdepth, int fatal);
int find_glut(const char *name, int logdepth, int fatal);
int find_gui_wgl(const char *name, int logdepth, int fatal);

View File

@ -1,3 +0,0 @@
int find_gtk2(const char *name, int logdepth, int fatal);
int find_gtk2gl(const char *name, int logdepth, int fatal);
int find_gtk2_modversion(const char *name, int logdepth, int fatal);

View File

@ -1,42 +0,0 @@
#include "libs.h"
#include "log.h"
#include "db.h"
#include "dep.h"
#include "find_x.h"
#include "find_gtk2.h"
#include "find_gtk3.h"
#include "find_lesstif2.h"
#include "find_gd.h"
#include "find_cairo.h"
#include "find_misc.h"
#include "find_gl.h"
void deps_gui_init()
{
dep_add("libs/gui/xopendisplay/*", find_xopendisplay);
dep_add("libs/gui/xinerama/*", find_xinerama);
dep_add("libs/gui/xrender/*", find_xrender);
dep_add("libs/gui/xcb/*", find_xcb);
dep_add("libs/gui/xcb_render/*", find_xcb_render);
dep_add("libs/gui/xgetxcbconnection/*", find_xgetxcbconnection);
dep_add("libs/gui/xpm/*", find_xpm);
dep_add("libs/gui/gtk2/*", find_gtk2);
dep_add("libs/gui/gtk2gl/*", find_gtk2gl);
dep_add("libs/gui/gtk2/key_prefix", find_gtk2_key_prefix);
dep_add("libs/gui/gtk2/modversion", find_gtk2_modversion);
dep_add("libs/gui/gtk3/*", find_gtk3);
dep_add("libs/gui/lesstif2/*", find_lesstif2);
dep_add("libs/gui/libstroke/*", find_libstroke);
dep_add("libs/gui/gd/gdImagePng/*", find_gdimagepng);
dep_add("libs/gui/gd/gdImageGif/*", find_gdimagegif);
dep_add("libs/gui/gd/gdImageJpeg/*", find_gdimagejpeg);
dep_add("libs/gui/gd/gdImageSetResolution/*", find_gdimagesetresolution);
dep_add("libs/gui/gd/*", find_gd);
dep_add("libs/gui/cairo/*", find_cairo);
dep_add("libs/gui/cairo-xcb/*", find_cairo_xcb);
dep_add("libs/gui/gl/*", find_gl);
dep_add("libs/gui/glu/*", find_glu);
dep_add("libs/gui/glut/*", find_glut);
dep_add("libs/gui/wgl/*", find_gui_wgl);
}

View File

@ -1,4 +0,0 @@
int find_gtk2(const char *name, int logdepth, int fatal);
int find_gtk2gl(const char *name, int logdepth, int fatal);
int find_gtk2_modversion(const char *name, int logdepth, int fatal);
int find_gtk2_key_prefix(const char *name, int logdepth, int fatal);

Some files were not shown because too many files have changed in this diff Show More