aboutsummaryrefslogtreecommitdiff
path: root/src/lib/cfuns-c.c
diff options
context:
space:
mode:
authorGabriel Dos Reis <gdr@axiomatics.org>2017-01-02 14:03:55 -0800
committerGabriel Dos Reis <gdr@axiomatics.org>2017-01-02 14:03:55 -0800
commitb56562693a88f88e7c290de9e1dc18d96a0da792 (patch)
tree63944417087417292c9d3e41972fa7ac89dea0bc /src/lib/cfuns-c.c
parent2bd3cc876cc90b8e28e0e8d88a5982f69729f867 (diff)
downloadopen-axiom-b56562693a88f88e7c290de9e1dc18d96a0da792.tar.gz
Include a native entry point for parsing Boot source files, and for
transpiling to Lisp.
Diffstat (limited to 'src/lib/cfuns-c.c')
-rw-r--r--src/lib/cfuns-c.c914
1 files changed, 0 insertions, 914 deletions
diff --git a/src/lib/cfuns-c.c b/src/lib/cfuns-c.c
deleted file mode 100644
index 11c28691..00000000
--- a/src/lib/cfuns-c.c
+++ /dev/null
@@ -1,914 +0,0 @@
-/*
- Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd.
- All rights reserved.
-
- Copyright (C) 2007-2013, Gabriel Dos Reis.
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
- - Neither the name of The Numerical Algorithms Group Ltd. nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include "openaxiom-c-macros.h"
-
-#include <errno.h>
-#include <limits.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <assert.h>
-#include <math.h>
-#include <unistd.h>
-
-
-#ifdef OPENAXIOM_MS_WINDOWS_HOST
-# include <windows.h>
-#else
-# include <dirent.h>
-# include <fcntl.h>
-#endif
-
-#include "cfuns.h"
-
-/* Most versions of Windows don't have the POSIX functions getuid(),
- geteuid(), getgid(), and getegid(). The following definitions are
- approximations, to patch for the deficiencies of Windows
- POSIX interface. */
-
-#if !HAVE_DECL_GETUID
-# define getuid() 0
-#endif
-
-#if !HAVE_DECL_GETGID
-# define getgid() 0
-#endif
-
-#if !HAVE_DECL_GETEUID
-# define geteuid() getuid()
-#endif
-
-#if !HAVE_DECL_GETEGID
-# define getegid() getgid()
-#endif
-
-namespace OpenAxiom {
- // Make a copy of string data on free store.
- static char*
- copy_c_str(const std::string& s) {
- return strdup(s.c_str());
- }
-
-OPENAXIOM_C_EXPORT int
-addtopath(char *dir)
-{
- char *path, *newpath;
-
- path = oa_getenv("PATH");
- if (path == NULL)
- return -1;
-
- newpath = (char *) malloc(1 + strlen(path) + strlen(dir) + strlen("PATH=:"));
- if (newpath == NULL)
- return -1;
-
- sprintf(newpath, "PATH=%s:%s", path, dir);
-
- return putenv(newpath);
-}
-
-
-
-/* Returns 1 if `c' designates a path separator, 0 otherwise. */
-static inline int
-openaxiom_is_path_separator(char c)
-{
-#ifdef OPENAXIOM_MS_WINDOWS_HOST
- return c == '\\' || c == '/';
-#else
- return c == '/';
-#endif
-}
-
-/*
- Returns a the dirname of `path'. If `path' has no separator, then
- returns ".". The returned value if malloc-allocated. */
-
-OPENAXIOM_C_EXPORT char*
-oa_dirname(const char* path)
-{
- const int n = strlen(path);
- const char* mark = path + n;
-
- if (n == 0)
- return strdup(".");
- else if (n == 1 && openaxiom_is_path_separator(*path))
- return strdup("/");
-
- /* For "/banana/space/", we want "/banana". */
- if (openaxiom_is_path_separator(*--mark))
- --mark;
- while (path < mark && !openaxiom_is_path_separator(*mark))
- --mark;
-
- if (path == mark)
- return strdup(openaxiom_is_path_separator(*path) ? "/" : ".");
- else {
- const int l = mark - path;
- char* dir = (char*) malloc(l + 1);
- memcpy(dir, path, l);
- dir[l] = '\0';
- return dir;
- }
-}
-
-/*
- * Test whether the path is the name of a directory. Returns 1 if so, 0 if
- * not, -1 if it doesn't exist.
- */
-
-
-OPENAXIOM_C_EXPORT int
-directoryp(char *path)
-{
- struct stat buf;
- int code = stat(path, &buf);
-
- return code == -1 ? -1 : S_ISDIR(buf.st_mode);
-}
-
-OPENAXIOM_C_EXPORT int
-make_path_from_file(char *s, char *t)
-{
- char *pos = NULL;
- char *c;
-
- /** simply copies the path name from t into s **/
- for (c = t + strlen(t); c != s; c--)
- if (*c == '/') {
- pos = c;
- break;
- }
- /** Check to see if the path was actually present **/
- if (c == t) { /** No Path, so return the pwd **/
- return (-1);
- }
- /** now just do the copying **/
- strncpy(s, t, pos - t);
- return 1;
-}
-
-/* The functions writeablep() and readablep() determine write and
- read access of a file designated by its name. The function
- axiom_has_write_access is a sub-routine of writeablep.
-
- The access is determined based on the POSIX semantics; see
- "Advanced Programming in the UNIX Environement", section 4.5.
-
- 1. If the effective user ID of the process is 0 (the superuser),
- access is allowed. This gives the superuser free rein throughout
- the entire file system.
-
- 2. If the effective user ID of the process equals the owner ID of
- the file (i.e., the process owns the file), access is allowed
- if the appropriate user access permission bit is set. [...]
-
- 3. If the effective group ID of the process or one of the
- supplementary group IDs of the process equals the group ID
- of the file, access is allowed if the appropriate
- group access permission bit is set. Otherwise, permission
- is denied.
-
- 4. If the appropriate other access permission bit is set, access is
- allowed. Otherwise, permission is defined. */
-
-
-/* Return 1 if the process has write access of file as explained above.
- Otherwise, return 0. */
-
-static inline int
-axiom_has_write_access(const struct stat* file_info)
-{
- uid_t effetive_uid = geteuid();
-
- if (effetive_uid == 0)
- return 1;
-
- if (effetive_uid == file_info->st_uid)
- return (file_info->st_mode & S_IWUSR) ? 1 : 0;
-
-#ifdef S_IWGRP
- if (getegid() == file_info->st_gid)
- return (file_info->st_mode & S_IWGRP) ? 1 : 0;
-#endif
-
-#ifdef S_IWOTH
- return (file_info->st_mode & S_IWOTH) ? 1 : 0;
-#else
- return 0;
-#endif
-}
-
-
-/* Return
- -1 if the file designated by PATH is inexistent.
- 0 if the file exists but write access is denied.
- 1 if the file exists and process has write access.
- 2 if the file does not exists but process has write
- has write access to the dirname of path. */
-
-OPENAXIOM_C_EXPORT int
-writeablep(const char *path)
-{
- struct stat buf;
- int code;
-
- code = stat(path, &buf);
- if (code == -1) {
- /* The file does not exist, so check to see if the directory
- is writable. */
- char* dir = oa_dirname(path);
- code = stat(dir, &buf);
- /* FIXME: Work around MinGW/MSYS bug.
- The string pointed to by `dir' was strdup'd. According to
- the C standard, that means the the string was allocated
- by `malloc', therefore can be disposed of by `free'. However,
- the MinGW/MSYS port appears to use MS' StrDup as the real
- worker. Consequently, the guarantee that the the string can
- free'd no longer holds. We have to use MS's LocalFree. */
-#ifdef OPENAXIOM_MS_WINDOWS_HOST
- LocalFree(dir);
-#else
- free(dir);
-#endif
- return (code == 0) && axiom_has_write_access(&buf) ? 2 : -1;
- }
-
- return axiom_has_write_access(&buf);
-}
-
-
-/* Return
- -1 if the file designated by PATH is inexistent.
- 0 if the file exists but process has no read access.
- 1 if the file exists and read access is granted. */
-
-OPENAXIOM_C_EXPORT int
-readablep(const char *path)
-{
- struct stat buf;
- int code;
-
- code = stat(path, &buf);
- if (code == -1)
- return -1;
-
- if (geteuid() == buf.st_uid)
- return ((buf.st_mode & S_IREAD) != 0);
-
-#ifdef S_IRGRP
- if (getegid() == buf.st_gid)
- return ((buf.st_mode & S_IRGRP) != 0);
-#endif
-
-#ifdef S_IROTH
- return ((buf.st_mode & S_IROTH) != 0);
-#else
- return 0;
-#endif
-}
-
-
-
-OPENAXIOM_C_EXPORT long
-findString(char *file, char *string)
-{
- int nstring, charpos;
- FILE *fn;
- char buffer[1024];
-
- if ((fn = fopen(file, "r")) == NULL)
- return -1;
-
- for (charpos = 0, nstring = strlen(string);
- fgets(buffer, sizeof buffer, fn) != NULL;
- charpos += strlen(buffer)
- )
- if (!strncmp(buffer, string, nstring))
- return charpos;
- return -1;
-
-}
-
-OPENAXIOM_C_EXPORT int
-copyEnvValue(char *varName, char *buffer)
-{
- char *s;
-
- s = oa_getenv(varName);
- if (s == NULL)
- return 0;
- strcpy(buffer, s);
- return strlen(s);
-}
-
-/* Return 1 if the file descriptor FD, as viewed by the Core Executable,
- is attached to a terminal. */
-OPENAXIOM_C_EXPORT int
-std_stream_is_terminal(int fd)
-{
- assert(fd > -1 && fd < 3);
-#ifdef OPENAXIOM_MS_WINDOWS_HOST
- DWORD handle;
- switch (fd) {
- case 0: handle = STD_INPUT_HANDLE; break;
- case 1: handle = STD_OUTPUT_HANDLE; break;
- case 2: handle = STD_ERROR_HANDLE; break;
- /* Next code is never executed but it makes the compiler happy. */
- default: return 0;
- }
- /* The MS documentation suggests `GetFileType' for determining
- the nature of the file handle. The return value, in our case,
- is an over approximation of what we are interested in: Are we
- dealing with a stream connected to a terminal? The constant
- FILE_TYPE_CHAR characterises character files; in particular
- a console terminal, or a printer. There is an undocumented
- function `VerifyConsoleIoHandle' to deal precisely with the case
- we are interested in. However, while availale in Wine, it is
- not available in the MinGW headers. Consequently, we cannot
- rely on it for the moment.
- So, we may still get garbage out of this function on MS platforms. */
- return GetFileType(GetStdHandle(handle)) == FILE_TYPE_CHAR;
-#else
- return isatty(fd);
-#endif
-}
-
-/* Change the process' curretnt directory. Return zero on success,
- and -1 on failure. */
-OPENAXIOM_C_EXPORT int
-oa_chdir(const char* path)
-{
-#ifdef OPENAXIOM_MS_WINDOWS_HOST
- return SetCurrentDirectory(path) ? 0 : -1;
-#else
- return chdir(path);
-#endif /* OPENAXIOM_MS_WINDOWS_HOST */
-}
-
-
-/* return true if path is `.' or `..'. */
-static inline int
-is_dot_or_dotdot(const char* path)
-{
- return strcmp(path, ".") == 0 || strcmp(path, "..") == 0;
-}
-
-/* Remove a directory entry. Files are removed, directories are
- recursively walked and removed.
- Return 0 on success, and -1 on falure.
- In practice, OpenAxiom does not remove directories with
- non-trivial recursive structues. */
-OPENAXIOM_C_EXPORT int
-oa_unlink(const char* path)
-{
- const char* curdir;
- int status = -1;
-#ifdef OPENAXIOM_MS_WINDOWS_HOST
- WIN32_FIND_DATA findData;
- HANDLE walkHandle;
-
- if (is_dot_or_dotdot(path))
- return -1;
-
- walkHandle = FindFirstFile(path, &findData);
- if (walkHandle == INVALID_HANDLE_VALUE)
- return -1;
-
- /* Remember where we are so we can return back properly. */
- curdir = oa_getcwd();
-
- do {
- if (is_dot_or_dotdot(findData.cFileName))
- continue;
- if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- if ((status = oa_chdir(findData.cFileName)) < 0)
- goto sortie;
- if ((status = oa_unlink("*")) < 0)
- goto sortie;
- if ((status = oa_chdir("..")) < 0)
- goto sortie;
- if(!RemoveDirectory(findData.cFileName)) {
- status = -1;
- goto sortie;
- }
- }
- else if (!DeleteFile(findData.cFileName)) {
- status = -1;
- goto sortie;
- }
- status = 0;
- } while (FindNextFile(walkHandle, &findData));
- if (!FindClose(walkHandle)) {
- status = -1;
- goto sortie;
- }
-#else
- struct stat pathstat;
- DIR* dir;
- struct dirent* entry;
-
- /* Don't ever try to remove `.' or `..'. */
- if (is_dot_or_dotdot(path))
- return -1;
-
- if (stat(path, &pathstat) < 0)
- return -1;
-
- /* handle non directories first. */
- if (!S_ISDIR(pathstat.st_mode))
- return unlink(path);
-
- /* change into the path so that we don't have to form full
- pathnames. */
- curdir = oa_getcwd();
- if ((dir = opendir(path)) == NULL || oa_chdir(path) < 0)
- goto sortie;
-
- while (errno = 0, (entry = readdir(dir)) != NULL) {
- struct stat s;
- if (is_dot_or_dotdot(entry->d_name))
- continue;
- if ((status = stat(entry->d_name, &s)) < 0)
- goto sortie;
- if (S_ISDIR(s.st_mode)) {
- if ((status = oa_unlink(entry->d_name)) < 0)
- goto sortie;
- }
- else if ((status = unlink(entry->d_name)) < 0)
- goto sortie;
- }
- if (errno != 0) {
- status = -1;
- goto sortie;
- }
-
- /* Now, get one level up, and remove the empty directory. */
- if (oa_chdir("..") < 0 || closedir(dir) < 0 || rmdir(path) < 0)
- status = -1;
- else
- status = 0;
-#endif /* OPENAXIOM_MS_WINDOWS_HOST */
-
- sortie:
- oa_chdir(curdir);
- free((char*) curdir);
- return status;
-}
-
-OPENAXIOM_C_EXPORT const char*
-oa_acquire_temporary_pathname() {
-#if OPENAXIOM_MS_WINDOWS_HOST
- char buf[MAX_PATH];
- const char* tmpdir = oa_get_tmpdir();
- auto n = GetTempFileName(tmpdir, "oa-", random() % SHRT_MAX, buf);
- /* tmpdir was malloc()ed when OPENAXIOM_MS_WINDOWS_HOST. */
- free(const_cast<char*>(tmpdir));
- if (n == 0) {
- perror("oa_acquire_temporary_pathname");
- exit(1);
- }
- return strdup(buf);
-#elif HAVE_DECL_MKTEMP
- return mktemp(copy_c_str(std::string{ oa_get_tmpdir() } + "/oa-XXXXXX"));
-#elif HAVE_DECL_TEMPNAM
- return tempnam(oa_get_tmpdir(), "oa-");
-#else
- return copy_c_str("oa-" + std::to_string(random()));
-#endif
-}
-
-OPENAXIOM_C_EXPORT void
-oa_release_temporary_pathname(const char* s)
-{
- free(const_cast<char*>(s)); // yuck!
-}
-
-/* Rename a file or directory. */
-OPENAXIOM_C_EXPORT int
-oa_rename(const char* old_path, const char* new_path)
-{
-#ifdef OPENAXIOM_MS_WINDOWS_HOST
- return MoveFile(old_path, new_path) ? 0 : -1;
-#else
- return rename(old_path, new_path);
-#endif
-}
-
-/* Create a new directory named `path'. Return 0 on success,
- and -1 on failure. */
-OPENAXIOM_C_EXPORT int
-oa_mkdir(const char* path)
-{
-#ifdef OPENAXIOM_MS_WINDOWS_HOST
- return CreateDirectory(path, NULL) ? 0 : -1;
-#else
-# define DIRECTORY_PERM ((S_IRWXU|S_IRWXG|S_IRWXO) & ~(S_IWGRP|S_IWOTH))
- return mkdir (path, DIRECTORY_PERM);
-# undef DIRECTORY_PERM
-#endif
-}
-
-/* Run a shell command. Effectively forward to C's system(). */
-OPENAXIOM_C_EXPORT int
-oa_system(const char* cmd)
-{
- return system(cmd);
-}
-
-OPENAXIOM_C_EXPORT int
-oa_getpid(void)
-{
-#ifdef OPENAXIOM_MS_WINDOWS_HOST
- return GetCurrentProcessId();
-#else
- return getpid();
-#endif
-}
-
-/* Concatenate two strings and return a pointer to the
- newly allocate resulting string. */
-OPENAXIOM_C_EXPORT const char*
-oa_concatenate_string(const char* lhs, const char* rhs)
-{
- if (lhs == NULL)
- return rhs;
- else if (rhs == NULL)
- return lhs;
- else {
- const int lhs_length = strlen(lhs);
- char* result = (char*) malloc(lhs_length + strlen(rhs) + 1);
- strcpy(result, lhs);
- strcpy(result + lhs_length, rhs);
- return result;
- }
-}
-
-/* Return a string object that is the result of catenating the strings
- designated by `left' and `right'. */
-OPENAXIOM_C_EXPORT const char*
-oa_strcat(const char* left, const char* right)
-{
- int left_size = strlen(left);
- int right_size = strlen(right);
- int size = left_size + right_size;
- char* buffer = (char*) malloc(size + 1);
-
- memcpy(buffer, left, left_size);
- memcpy(buffer + left_size, right, right_size);
- buffer[size] = '\0';
- return buffer;
-}
-
-/* Return the value of an environment variable. */
-OPENAXIOM_C_EXPORT char*
-oa_getenv(const char* var)
-{
-#ifdef OPENAXIOM_MS_WINDOWS_HOST
-#define BUFSIZE 128
- char* buf = (char*) malloc(BUFSIZE);
- int len = GetEnvironmentVariable(var, buf, BUFSIZE);
- if (len == 0) {
- free(buf);
- return NULL;
- }
- else if (len > BUFSIZE) {
- buf = (char*) realloc(buf,len);
- len = GetEnvironmentVariable(var, buf, len);
- if (len == 0) {
- free(buf);
- return NULL;
- }
- }
- return buf;
-#else
- return getenv(var);
-#endif
-}
-
-/* Set the value of environment variable VAR to VAL.
- Return 1 on success, and 0 otherwise. */
-OPENAXIOM_C_EXPORT int
-oa_setenv(const char* var, const char* val)
-{
-#ifdef OPENAXIOM_MS_WINDOWS_HOST
- return SetEnvironmentVariable(var, val);
-#elif HAVE_DECL_SETENV
- return !setenv(var, val, true);
-#else
- const int var_length = strlen(var);
- const int val_length = strlen(val);
- char* str = (char*) malloc(var_length + 1 + val_length + 1);
- strcpy(str, var);
- str[var_length] = '=';
- strcpy(str + var_length + 1, val);
- str[var_length + 1 + val_length] = '\0';
- return !putenv(str);
-#endif
-}
-
-
-OPENAXIOM_C_EXPORT char*
-oa_getcwd(void)
-{
- size_t bufsz = 256;
- char* buf = (char*) malloc(bufsz);
-#ifdef OPENAXIOM_MS_WINDOWS_HOST
- DWORD n = GetCurrentDirectory(bufsz, buf);
- if (n == 0) {
- perror("oa_getcwd");
- exit(-1);
- }
- else if (n > bufsz) {
- buf = (char*) realloc(buf,n);
- if (GetCurrentDirectory(n, buf) != n) {
- perror("oa_getcwd");
- exit(-1);
- }
- }
- return buf;
-#else /* OPENAXIOM_MS_WINDOWS_HOST */
- errno = 0;
- while (getcwd(buf,bufsz) == 0) {
- if (errno == ERANGE) {
- errno = 0;
- bufsz *= 2;
- buf = (char*) realloc(buf, bufsz);
- }
- else {
- perror("oa_getcwd");
- exit(-1);
- }
- }
- return buf;
-#endif
-}
-
-OPENAXIOM_C_EXPORT int
-oa_access_file_for_read(const char* path)
-{
-#ifdef OPENAXIOM_MS_WINDOWS_HOST
- return GetFileAttributes(path) == INVALID_FILE_ATTRIBUTES ? -1 : 1;
-#else
- return access(path, R_OK);
-#endif
-}
-
-
-OPENAXIOM_C_EXPORT const char*
-oa_get_tmpdir(void)
-{
-#ifdef OPENAXIOM_MS_WINDOWS_HOST
- char* buf;
- /* First, probe. */
- int bufsz = GetTempPath(0, NULL);
- if (bufsz == 0) {
- perror("oa_get_tmpdir");
- exit(1);
- }
- else {
- int new_size;
- buf = (char*) malloc(bufsz + 1);
- new_size = GetTempPath(bufsz, buf);
- if(new_size == 0 || new_size >= bufsz) {
- perror("oa_get_tmpdir");
- free(buf);
- exit(1);
- }
- buf[new_size] = '\0';
- }
- return buf;
-#else
- return "/tmp";
-#endif
-}
-
-
-OPENAXIOM_C_EXPORT int
-oa_copy_file(const char* src, const char* dst)
-{
-#ifdef OPENAXIOM_MS_WINDOWS_HOST
- return CopyFile(src,dst, /* bFailIfExists = */ 0) ? 0 : -1;
-#else
-#define OA_BUFSZ 512
-#define OA_DEFAULT_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
- char buf[OA_BUFSZ];
- int src_fd;
- int dst_fd;
- int count;
- if((src_fd = open(src, O_RDONLY)) < 0)
- return -1;
- if ((dst_fd = creat(dst, OA_DEFAULT_MODE)) < 0) {
- close(src_fd);
- return -1;
- }
-
- while ((count = read(src_fd, buf, OA_BUFSZ)) > 0)
- if (write(dst_fd, buf, count) != count)
- break;
-
-#undef OA_DEFAULT_MODE
-#undef OA_BUFSZ
- return (close(dst_fd) < 0 || close(src_fd) < 0 || count < 0) ? -1 : 0;
-#endif
-}
-
-
-OPENAXIOM_C_EXPORT double
-plus_infinity(void )
-{
-#ifdef INFINITY
- return INFINITY;
-#else
- /* This must be a curious platform. */
- volatile double zero = 0.0;
- return 1.0 / zero; /* If it traps, well, it traps. */
-#endif
-}
-
-OPENAXIOM_C_EXPORT double
-minus_infinity(void)
-{
- return -plus_infinity();
-}
-
-OPENAXIOM_C_EXPORT double
-quiet_double_NaN(void)
-{
-#ifdef NAN
- return NAN;
-#else
- return sqrt(-1.0); /* Just pick one. */
-#endif
-}
-
-
-OPENAXIOM_C_EXPORT Byteorder
-oa_get_host_byteorder(void)
-{
-#ifdef WORDS_BIGENDIAN
- return Byteorder::big;
-#else
- return Byteorder::little;
-#endif
-}
-
-
-OPENAXIOM_C_EXPORT void
-oa_allocate_process_argv(Process* proc, int argc)
-{
- proc->argc = argc;
- proc->argv = (char**) malloc((1 + argc) * sizeof (char*));
- proc->argv[argc] = NULL;
-}
-
-OPENAXIOM_C_EXPORT int
-oa_spawn(Process* proc, SpawnFlags flags)
-{
-#ifdef OPENAXIOM_MS_WINDOWS_HOST
- const char* path = NULL;
- char* cmd_line = NULL;
- int curpos = strlen(proc->argv[0]);
- int cmd_line_length = curpos;
- int i;
- PROCESS_INFORMATION proc_info;
- STARTUPINFO startup_info = { 0 };
- DWORD status;
-
- for (i = 0; i < proc->argc; ++i)
- cmd_line_length += 1 + strlen(proc->argv[i]);
-
- cmd_line = (char*) malloc(cmd_line_length + 1);
- strcpy(cmd_line, proc->argv[0]);
- for (i = 0; i < proc->argc; ++i) {
- cmd_line[curpos++] = ' ';
- strcpy(cmd_line + curpos, proc->argv[i]);
- curpos += strlen(proc->argv[i]);
- }
- cmd_line[curpos] = '\0';
-
- if ((flags & SpawnFlags::search_path) == 0)
- path = proc->argv[0];
-
- if(CreateProcess(/* lpApplicationName */ path,
- /* lpCommandLine */ cmd_line,
- /* lpProcessAttributes */ NULL,
- /* lpThreadAttributes */ NULL,
- /* bInheritHandles */ TRUE,
- /* dwCreationFlags */ 0,
- /* lpEnvironment */ NULL,
- /* lpCurrentDirectory */ NULL,
- /* lpstartupInfo */ &startup_info,
- /* lpProcessInformation */ &proc_info) == 0) {
- fprintf(stderr, "oa_spawn: error %lu\n", GetLastError());
- return proc->id = -1;
- }
- proc->id = proc_info.dwProcessId;
- if ((flags & SpawnFlags::replace) == 0)
- return proc->id;
- WaitForSingleObject(proc_info.hProcess, INFINITE);
- GetExitCodeProcess(proc_info.hProcess, &status);
- CloseHandle(proc_info.hThread);
- CloseHandle(proc_info.hProcess);
- return status;
-
-#else
- proc->id = 0;
- if ((flags & SpawnFlags::replace) == 0)
- proc->id = fork();
- if (proc->id == 0) {
- if (flags & SpawnFlags::search_path)
- execvp(proc->argv[0], proc->argv);
- else
- execv(proc->argv[0], proc->argv);
- perror(strerror(errno));
- /* Don't keep useless clones around. */
- if ((flags & SpawnFlags::replace) == 0)
- exit(-1);
- }
- return proc->id;
-#endif
-}
-
-OPENAXIOM_C_EXPORT char*
-oa_substr(const char* str, const size_t begin, const size_t end)
-{
- char* substring;
- int len;
-
- if (str == NULL || strlen(str) == 0 ||
- strlen(str) < begin || end >= strlen(str) || begin > end)
- return NULL;
-
- len = (end - begin) + 2;
- substring = (char*) malloc(len * sizeof(char));
- memset(substring,'\0',len);
- memcpy(substring, str+begin, len-1);
-
- return substring;
-}
-
-OPENAXIOM_C_EXPORT char**
-oa_split(const char* sequence, const char* delimiter, int* size)
-{
- int sequence_length = 0, newsize = 0;
- char* token;
- char** tokens = NULL;
- char* sequence_copy;
-
- sequence_length = strlen(sequence);
- sequence_copy = (char*) malloc((sequence_length + 1) * sizeof(char*));
- strcpy(sequence_copy,sequence);
- sequence_copy[sequence_length] = '\0';
-
- token = strtok(sequence_copy, delimiter);
- while (token != NULL) {
-
- tokens = (char**) realloc(tokens,(newsize + 1) * sizeof(char*));
- tokens[newsize] = token;
- newsize++;
- token = strtok (NULL, delimiter);
- }
-
- *size = newsize;
-
- return tokens;
-}
-
-}