From feb8ebaeb76fa1c94de2dd7c4e5a0999b313f8c6 Mon Sep 17 00:00:00 2001 From: David Monniaux Date: Thu, 6 Jun 2019 20:09:32 +0200 Subject: GLPK 4.65 --- test/monniaux/glpk-4.65/src/env/alloc.c | 252 +++++++++++++++ test/monniaux/glpk-4.65/src/env/dlsup.c | 167 ++++++++++ test/monniaux/glpk-4.65/src/env/env.c | 316 +++++++++++++++++++ test/monniaux/glpk-4.65/src/env/env.h | 274 ++++++++++++++++ test/monniaux/glpk-4.65/src/env/error.c | 200 ++++++++++++ test/monniaux/glpk-4.65/src/env/stdc.c | 98 ++++++ test/monniaux/glpk-4.65/src/env/stdc.h | 73 +++++ test/monniaux/glpk-4.65/src/env/stdout.c | 262 ++++++++++++++++ test/monniaux/glpk-4.65/src/env/stream.c | 517 +++++++++++++++++++++++++++++++ test/monniaux/glpk-4.65/src/env/time.c | 150 +++++++++ test/monniaux/glpk-4.65/src/env/tls.c | 128 ++++++++ 11 files changed, 2437 insertions(+) create mode 100644 test/monniaux/glpk-4.65/src/env/alloc.c create mode 100644 test/monniaux/glpk-4.65/src/env/dlsup.c create mode 100644 test/monniaux/glpk-4.65/src/env/env.c create mode 100644 test/monniaux/glpk-4.65/src/env/env.h create mode 100644 test/monniaux/glpk-4.65/src/env/error.c create mode 100644 test/monniaux/glpk-4.65/src/env/stdc.c create mode 100644 test/monniaux/glpk-4.65/src/env/stdc.h create mode 100644 test/monniaux/glpk-4.65/src/env/stdout.c create mode 100644 test/monniaux/glpk-4.65/src/env/stream.c create mode 100644 test/monniaux/glpk-4.65/src/env/time.c create mode 100644 test/monniaux/glpk-4.65/src/env/tls.c (limited to 'test/monniaux/glpk-4.65/src/env') diff --git a/test/monniaux/glpk-4.65/src/env/alloc.c b/test/monniaux/glpk-4.65/src/env/alloc.c new file mode 100644 index 00000000..8e2d613d --- /dev/null +++ b/test/monniaux/glpk-4.65/src/env/alloc.c @@ -0,0 +1,252 @@ +/* alloc.c (dynamic memory allocation) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK 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 General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" + +#define ALIGN 16 +/* some processors need data to be properly aligned, so this macro + * defines the alignment boundary, in bytes, provided by glpk memory + * allocation routines; looks like 16-byte alignment boundary is + * sufficient for all 32- and 64-bit platforms (8-byte boundary is not + * sufficient for some 64-bit platforms because of jmp_buf) */ + +#define MBD_SIZE (((sizeof(MBD) + (ALIGN - 1)) / ALIGN) * ALIGN) +/* size of memory block descriptor, in bytes, rounded up to multiple + * of the alignment boundary */ + +/*********************************************************************** +* dma - dynamic memory allocation (basic routine) +* +* This routine performs dynamic memory allocation. It is similar to +* the standard realloc function, however, it provides every allocated +* memory block with a descriptor, which is used for sanity checks on +* reallocating/freeing previously allocated memory blocks as well as +* for book-keeping the memory usage statistics. */ + +static void *dma(const char *func, void *ptr, size_t size) +{ ENV *env = get_env_ptr(); + MBD *mbd; + if (ptr == NULL) + { /* new memory block will be allocated */ + mbd = NULL; + } + else + { /* allocated memory block will be reallocated or freed */ + /* get pointer to the block descriptor */ + mbd = (MBD *)((char *)ptr - MBD_SIZE); + /* make sure that the block descriptor is valid */ + if (mbd->self != mbd) + xerror("%s: ptr = %p; invalid pointer\n", func, ptr); + /* remove the block from the linked list */ + mbd->self = NULL; + if (mbd->prev == NULL) + env->mem_ptr = mbd->next; + else + mbd->prev->next = mbd->next; + if (mbd->next == NULL) + ; + else + mbd->next->prev = mbd->prev; + /* decrease usage counts */ + if (!(env->mem_count >= 1 && env->mem_total >= mbd->size)) + xerror("%s: memory allocation error\n", func); + env->mem_count--; + env->mem_total -= mbd->size; + if (size == 0) + { /* free the memory block */ + free(mbd); + return NULL; + } + } + /* allocate/reallocate memory block */ + if (size > SIZE_T_MAX - MBD_SIZE) + xerror("%s: block too large\n", func); + size += MBD_SIZE; + if (size > env->mem_limit - env->mem_total) + xerror("%s: memory allocation limit exceeded\n", func); + if (env->mem_count == INT_MAX) + xerror("%s: too many memory blocks allocated\n", func); + mbd = (mbd == NULL ? malloc(size) : realloc(mbd, size)); + if (mbd == NULL) + xerror("%s: no memory available\n", func); + /* setup the block descriptor */ + mbd->size = size; + mbd->self = mbd; + mbd->prev = NULL; + mbd->next = env->mem_ptr; + /* add the block to the beginning of the linked list */ + if (mbd->next != NULL) + mbd->next->prev = mbd; + env->mem_ptr = mbd; + /* increase usage counts */ + env->mem_count++; + if (env->mem_cpeak < env->mem_count) + env->mem_cpeak = env->mem_count; + env->mem_total += size; + if (env->mem_tpeak < env->mem_total) + env->mem_tpeak = env->mem_total; + return (char *)mbd + MBD_SIZE; +} + +/*********************************************************************** +* NAME +* +* glp_alloc - allocate memory block +* +* SYNOPSIS +* +* void *glp_alloc(int n, int size); +* +* DESCRIPTION +* +* The routine glp_alloc allocates a memory block of n * size bytes +* long. +* +* Note that being allocated the memory block contains arbitrary data +* (not binary zeros!). +* +* RETURNS +* +* The routine glp_alloc returns a pointer to the block allocated. +* To free this block the routine glp_free (not free!) must be used. */ + +void *glp_alloc(int n, int size) +{ if (n < 1) + xerror("glp_alloc: n = %d; invalid parameter\n", n); + if (size < 1) + xerror("glp_alloc: size = %d; invalid parameter\n", size); + if ((size_t)n > SIZE_T_MAX / (size_t)size) + xerror("glp_alloc: n = %d, size = %d; block too large\n", + n, size); + return dma("glp_alloc", NULL, (size_t)n * (size_t)size); +} + +/**********************************************************************/ + +void *glp_realloc(void *ptr, int n, int size) +{ /* reallocate memory block */ + if (ptr == NULL) + xerror("glp_realloc: ptr = %p; invalid pointer\n", ptr); + if (n < 1) + xerror("glp_realloc: n = %d; invalid parameter\n", n); + if (size < 1) + xerror("glp_realloc: size = %d; invalid parameter\n", size); + if ((size_t)n > SIZE_T_MAX / (size_t)size) + xerror("glp_realloc: n = %d, size = %d; block too large\n", + n, size); + return dma("glp_realloc", ptr, (size_t)n * (size_t)size); +} + +/*********************************************************************** +* NAME +* +* glp_free - free (deallocate) memory block +* +* SYNOPSIS +* +* void glp_free(void *ptr); +* +* DESCRIPTION +* +* The routine glp_free frees (deallocates) a memory block pointed to +* by ptr, which was previuosly allocated by the routine glp_alloc or +* reallocated by the routine glp_realloc. */ + +void glp_free(void *ptr) +{ if (ptr == NULL) + xerror("glp_free: ptr = %p; invalid pointer\n", ptr); + dma("glp_free", ptr, 0); + return; +} + +/*********************************************************************** +* NAME +* +* glp_mem_limit - set memory usage limit +* +* SYNOPSIS +* +* void glp_mem_limit(int limit); +* +* DESCRIPTION +* +* The routine glp_mem_limit limits the amount of memory available for +* dynamic allocation (in GLPK routines) to limit megabytes. */ + +void glp_mem_limit(int limit) +{ ENV *env = get_env_ptr(); + if (limit < 1) + xerror("glp_mem_limit: limit = %d; invalid parameter\n", + limit); + if ((size_t)limit <= (SIZE_T_MAX >> 20)) + env->mem_limit = (size_t)limit << 20; + else + env->mem_limit = SIZE_T_MAX; + return; +} + +/*********************************************************************** +* NAME +* +* glp_mem_usage - get memory usage information +* +* SYNOPSIS +* +* void glp_mem_usage(int *count, int *cpeak, size_t *total, +* size_t *tpeak); +* +* DESCRIPTION +* +* The routine glp_mem_usage reports some information about utilization +* of the memory by GLPK routines. Information is stored to locations +* specified by corresponding parameters (see below). Any parameter can +* be specified as NULL, in which case its value is not stored. +* +* *count is the number of the memory blocks currently allocated by the +* routines glp_malloc and glp_calloc (one call to glp_malloc or +* glp_calloc results in allocating one memory block). +* +* *cpeak is the peak value of *count reached since the initialization +* of the GLPK library environment. +* +* *total is the total amount, in bytes, of the memory blocks currently +* allocated by the routines glp_malloc and glp_calloc. +* +* *tpeak is the peak value of *total reached since the initialization +* of the GLPK library envirionment. */ + +void glp_mem_usage(int *count, int *cpeak, size_t *total, + size_t *tpeak) +{ ENV *env = get_env_ptr(); + if (count != NULL) + *count = env->mem_count; + if (cpeak != NULL) + *cpeak = env->mem_cpeak; + if (total != NULL) + *total = env->mem_total; + if (tpeak != NULL) + *tpeak = env->mem_tpeak; + return; +} + +/* eof */ diff --git a/test/monniaux/glpk-4.65/src/env/dlsup.c b/test/monniaux/glpk-4.65/src/env/dlsup.c new file mode 100644 index 00000000..54c56c6d --- /dev/null +++ b/test/monniaux/glpk-4.65/src/env/dlsup.c @@ -0,0 +1,167 @@ +/* dlsup.c (dynamic linking support) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2008-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK 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 General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "env.h" + +/* GNU version ********************************************************/ + +#if defined(HAVE_LTDL) + +#include + +void *xdlopen(const char *module) +{ /* open dynamically linked library */ + void *h = NULL; + if (lt_dlinit() != 0) + { put_err_msg(lt_dlerror()); + goto done; + } + h = lt_dlopen(module); + if (h == NULL) + { put_err_msg(lt_dlerror()); + if (lt_dlexit() != 0) + xerror("xdlopen: %s\n", lt_dlerror()); + } +done: return h; +} + +void *xdlsym(void *h, const char *symbol) +{ /* obtain address of symbol from dynamically linked library */ + void *ptr; + xassert(h != NULL); + ptr = lt_dlsym(h, symbol); + if (ptr == NULL) + xerror("xdlsym: %s: %s\n", symbol, lt_dlerror()); + return ptr; +} + +void xdlclose(void *h) +{ /* close dynamically linked library */ + xassert(h != NULL); + if (lt_dlclose(h) != 0) + xerror("xdlclose: %s\n", lt_dlerror()); + if (lt_dlexit() != 0) + xerror("xdlclose: %s\n", lt_dlerror()); + return; +} + +/* POSIX version ******************************************************/ + +#elif defined(HAVE_DLFCN) + +#include + +void *xdlopen(const char *module) +{ /* open dynamically linked library */ + void *h; + h = dlopen(module, RTLD_NOW); + if (h == NULL) + put_err_msg(dlerror()); + return h; +} + +void *xdlsym(void *h, const char *symbol) +{ /* obtain address of symbol from dynamically linked library */ + void *ptr; + xassert(h != NULL); + ptr = dlsym(h, symbol); + if (ptr == NULL) + xerror("xdlsym: %s: %s\n", symbol, dlerror()); + return ptr; +} + +void xdlclose(void *h) +{ /* close dynamically linked library */ + xassert(h != NULL); + if (dlclose(h) != 0) + xerror("xdlclose: %s\n", dlerror()); + return; +} + +/* MS Windows version *************************************************/ + +#elif defined(__WOE__) + +#include + +void *xdlopen(const char *module) +{ /* open dynamically linked library */ + void *h; + h = LoadLibrary(module); + if (h == NULL) + { char msg[20]; + sprintf(msg, "Error %d", GetLastError()); + put_err_msg(msg); + } + return h; +} + +void *xdlsym(void *h, const char *symbol) +{ /* obtain address of symbol from dynamically linked library */ + void *ptr; + xassert(h != NULL); + ptr = GetProcAddress(h, symbol); + if (ptr == NULL) + xerror("xdlsym: %s: Error %d\n", symbol, GetLastError()); + return ptr; +} + +void xdlclose(void *h) +{ /* close dynamically linked library */ + xassert(h != NULL); + if (!FreeLibrary(h)) + xerror("xdlclose: Error %d\n", GetLastError()); + return; +} + +/* NULL version *******************************************************/ + +#else + +void *xdlopen(const char *module) +{ /* open dynamically linked library */ + xassert(module == module); + put_err_msg("Shared libraries not supported"); + return NULL; +} + +void *xdlsym(void *h, const char *symbol) +{ /* obtain address of symbol from dynamically linked library */ + xassert(h != h); + xassert(symbol != symbol); + return NULL; +} + +void xdlclose(void *h) +{ /* close dynamically linked library */ + xassert(h != h); + return; +} + +#endif + +/* eof */ diff --git a/test/monniaux/glpk-4.65/src/env/env.c b/test/monniaux/glpk-4.65/src/env/env.c new file mode 100644 index 00000000..5b901f35 --- /dev/null +++ b/test/monniaux/glpk-4.65/src/env/env.c @@ -0,0 +1,316 @@ +/* env.c (GLPK environment initialization/termination) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2017 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK 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 General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "glpk.h" +#include "env.h" + +/*********************************************************************** +* NAME +* +* glp_init_env - initialize GLPK environment +* +* SYNOPSIS +* +* int glp_init_env(void); +* +* DESCRIPTION +* +* The routine glp_init_env initializes the GLPK environment. Normally +* the application program does not need to call this routine, because +* it is called automatically on the first call to any API routine. +* +* RETURNS +* +* The routine glp_init_env returns one of the following codes: +* +* 0 - initialization successful; +* 1 - environment has been already initialized; +* 2 - initialization failed (insufficient memory); +* 3 - initialization failed (unsupported programming model). */ + +int glp_init_env(void) +{ ENV *env; + int ok; + /* check if the programming model is supported */ + ok = (CHAR_BIT == 8 && sizeof(char) == 1 && + sizeof(short) == 2 && sizeof(int) == 4 && + (sizeof(void *) == 4 || sizeof(void *) == 8)); + if (!ok) + return 3; + /* check if the environment is already initialized */ + if (tls_get_ptr() != NULL) + return 1; + /* allocate and initialize the environment block */ + env = malloc(sizeof(ENV)); + if (env == NULL) + return 2; + memset(env, 0, sizeof(ENV)); +#if 0 /* 14/I-2017 */ + sprintf(env->version, "%d.%d", + GLP_MAJOR_VERSION, GLP_MINOR_VERSION); +#endif + env->self = env; + env->term_buf = malloc(TBUF_SIZE); + if (env->term_buf == NULL) + { free(env); + return 2; + } + env->term_out = GLP_ON; + env->term_hook = NULL; + env->term_info = NULL; + env->tee_file = NULL; +#if 1 /* 23/XI-2015 */ + env->err_st = 0; +#endif + env->err_file = NULL; + env->err_line = 0; + env->err_hook = NULL; + env->err_info = NULL; + env->err_buf = malloc(EBUF_SIZE); + if (env->err_buf == NULL) + { free(env->term_buf); + free(env); + return 2; + } + env->err_buf[0] = '\0'; + env->mem_limit = SIZE_T_MAX; + env->mem_ptr = NULL; + env->mem_count = env->mem_cpeak = 0; + env->mem_total = env->mem_tpeak = 0; +#if 1 /* 23/XI-2015 */ + env->gmp_pool = NULL; + env->gmp_size = 0; + env->gmp_work = NULL; +#endif + env->h_odbc = env->h_mysql = NULL; + /* save pointer to the environment block */ + tls_set_ptr(env); + /* initialization successful */ + return 0; +} + +/*********************************************************************** +* NAME +* +* get_env_ptr - retrieve pointer to environment block +* +* SYNOPSIS +* +* #include "env.h" +* ENV *get_env_ptr(void); +* +* DESCRIPTION +* +* The routine get_env_ptr retrieves and returns a pointer to the GLPK +* environment block. +* +* If the GLPK environment has not been initialized yet, the routine +* performs initialization. If initialization fails, the routine prints +* an error message to stderr and terminates the program. +* +* RETURNS +* +* The routine returns a pointer to the environment block. */ + +ENV *get_env_ptr(void) +{ ENV *env = tls_get_ptr(); + /* check if the environment has been initialized */ + if (env == NULL) + { /* not initialized yet; perform initialization */ + if (glp_init_env() != 0) + { /* initialization failed; display an error message */ + fprintf(stderr, "GLPK initialization failed\n"); + fflush(stderr); + /* and abnormally terminate the program */ + abort(); + } + /* initialization successful; retrieve the pointer */ + env = tls_get_ptr(); + } + /* check if the environment block is valid */ + if (env->self != env) + { fprintf(stderr, "Invalid GLPK environment\n"); + fflush(stderr); + abort(); + } + return env; +} + +/*********************************************************************** +* NAME +* +* glp_version - determine library version +* +* SYNOPSIS +* +* const char *glp_version(void); +* +* RETURNS +* +* The routine glp_version returns a pointer to a null-terminated +* character string, which specifies the version of the GLPK library in +* the form "X.Y", where X is the major version number, and Y is the +* minor version number, for example, "4.16". */ + +#define str(s) # s +#define xstr(s) str(s) + +const char *glp_version(void) +#if 0 /* 14/I-2017 */ +{ ENV *env = get_env_ptr(); + return env->version; +} +#else /* suggested by Heinrich */ +{ return + xstr(GLP_MAJOR_VERSION) "." xstr(GLP_MINOR_VERSION); +} +#endif + +/*********************************************************************** +* NAME +* +* glp_config - determine library configuration +* +* SYNOPSIS +* +* const char *glp_config(const char *option); +* +* DESCRIPTION +* +* The routine glp_config determines some options which were specified +* on configuring the GLPK library. +* +* RETURNS +* +* The routine glp_config returns a pointer to a null-terminating +* string depending on the option inquired. +* +* For option = "TLS" the routine returns the thread local storage +* class specifier used (e.g. "_Thread_local") if the GLPK library was +* configured to run in multi-threaded environment, or NULL otherwise. +* +* For option = "ODBC_DLNAME" the routine returns the name of ODBC +* shared library if this option was enabled, or NULL otherwise. +* +* For option = "MYSQL_DLNAME" the routine returns the name of MySQL +* shared library if this option was enabled, or NULL otherwise. */ + +const char *glp_config(const char *option) +{ const char *s; + if (strcmp(option, "TLS") == 0) +#ifndef TLS + s = NULL; +#else + s = xstr(TLS); +#endif + else if (strcmp(option, "ODBC_DLNAME") == 0) +#ifndef ODBC_DLNAME + s = NULL; +#else + s = ODBC_DLNAME; +#endif + else if (strcmp(option, "MYSQL_DLNAME") == 0) +#ifndef MYSQL_DLNAME + s = NULL; +#else + s = MYSQL_DLNAME; +#endif + else + { /* invalid option is always disabled */ + s = NULL; + } + return s; +} + +/*********************************************************************** +* NAME +* +* glp_free_env - free GLPK environment +* +* SYNOPSIS +* +* int glp_free_env(void); +* +* DESCRIPTION +* +* The routine glp_free_env frees all resources used by GLPK routines +* (memory blocks, etc.) which are currently still in use. +* +* Normally the application program does not need to call this routine, +* because GLPK routines always free all unused resources. However, if +* the application program even has deleted all problem objects, there +* will be several memory blocks still allocated for the library needs. +* For some reasons the application program may want GLPK to free this +* memory, in which case it should call glp_free_env. +* +* Note that a call to glp_free_env invalidates all problem objects as +* if no GLPK routine were called. +* +* RETURNS +* +* 0 - termination successful; +* 1 - environment is inactive (was not initialized). */ + +int glp_free_env(void) +{ ENV *env = tls_get_ptr(); + MBD *desc; + /* check if the environment is active */ + if (env == NULL) + return 1; + /* check if the environment block is valid */ + if (env->self != env) + { fprintf(stderr, "Invalid GLPK environment\n"); + fflush(stderr); + abort(); + } + /* close handles to shared libraries */ + if (env->h_odbc != NULL) + xdlclose(env->h_odbc); + if (env->h_mysql != NULL) + xdlclose(env->h_mysql); + /* free memory blocks which are still allocated */ + while (env->mem_ptr != NULL) + { desc = env->mem_ptr; + env->mem_ptr = desc->next; + free(desc); + } + /* close text file used for copying terminal output */ + if (env->tee_file != NULL) + fclose(env->tee_file); + /* invalidate the environment block */ + env->self = NULL; + /* free memory allocated to the environment block */ + free(env->term_buf); + free(env->err_buf); + free(env); + /* reset a pointer to the environment block */ + tls_set_ptr(NULL); + /* termination successful */ + return 0; +} + +/* eof */ diff --git a/test/monniaux/glpk-4.65/src/env/env.h b/test/monniaux/glpk-4.65/src/env/env.h new file mode 100644 index 00000000..67214ef6 --- /dev/null +++ b/test/monniaux/glpk-4.65/src/env/env.h @@ -0,0 +1,274 @@ +/* env.h (GLPK environment) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2017 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK 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 General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef ENV_H +#define ENV_H + +#include "stdc.h" + +typedef struct ENV ENV; +typedef struct MBD MBD; + +#define SIZE_T_MAX (~(size_t)0) +/* largest value of size_t type */ + +#define TBUF_SIZE 4096 +/* terminal output buffer size, in bytes */ + +#define EBUF_SIZE 1024 +/* error message buffer size, in bytes */ + +/* enable/disable flag: */ +#define GLP_ON 1 +#define GLP_OFF 0 + +struct ENV +{ /* GLPK environment block */ +#if 0 /* 14/I-2007 */ + char version[7+1]; + /* version string returned by the routine glp_version */ +#endif + ENV *self; + /* pointer to this block to check its validity */ + /*--------------------------------------------------------------*/ + /* terminal output */ + char *term_buf; /* char term_buf[TBUF_SIZE]; */ + /* terminal output buffer */ + int term_out; + /* flag to enable/disable terminal output */ + int (*term_hook)(void *info, const char *s); + /* user-defined routine to intercept terminal output */ + void *term_info; + /* transit pointer (cookie) passed to the routine term_hook */ + FILE *tee_file; + /* output stream used to copy terminal output */ + /*--------------------------------------------------------------*/ + /* error handling */ +#if 1 /* 07/XI-2015 */ + int err_st; + /* error state flag; set on entry to glp_error */ +#endif + const char *err_file; + /* value of the __FILE__ macro passed to glp_error */ + int err_line; + /* value of the __LINE__ macro passed to glp_error */ + void (*err_hook)(void *info); + /* user-defined routine to intercept abnormal termination */ + void *err_info; + /* transit pointer (cookie) passed to the routine err_hook */ + char *err_buf; /* char err_buf[EBUF_SIZE]; */ + /* buffer to store error messages (used by I/O routines) */ + /*--------------------------------------------------------------*/ + /* dynamic memory allocation */ + size_t mem_limit; + /* maximal amount of memory, in bytes, available for dynamic + * allocation */ + MBD *mem_ptr; + /* pointer to the linked list of allocated memory blocks */ + int mem_count; + /* total number of currently allocated memory blocks */ + int mem_cpeak; + /* peak value of mem_count */ + size_t mem_total; + /* total amount of currently allocated memory, in bytes; it is + * the sum of the size field over all memory block descriptors */ + size_t mem_tpeak; + /* peak value of mem_total */ +#if 1 /* 23/XI-2015 */ + /*--------------------------------------------------------------*/ + /* bignum module working area */ + void *gmp_pool; /* DMP *gmp_pool; */ + /* working memory pool */ + int gmp_size; + /* size of working array */ + unsigned short *gmp_work; /* ushort gmp_work[gmp_size]; */ + /* working array */ +#endif + /*--------------------------------------------------------------*/ + /* dynamic linking support (optional) */ + void *h_odbc; + /* handle to ODBC shared library */ + void *h_mysql; + /* handle to MySQL shared library */ +}; + +struct MBD +{ /* memory block descriptor */ + size_t size; + /* size of block, in bytes, including descriptor */ + MBD *self; + /* pointer to this descriptor to check its validity */ + MBD *prev; + /* pointer to previous memory block descriptor */ + MBD *next; + /* pointer to next memory block descriptor */ +}; + +#define get_env_ptr _glp_get_env_ptr +ENV *get_env_ptr(void); +/* retrieve pointer to environment block */ + +#define tls_set_ptr _glp_tls_set_ptr +void tls_set_ptr(void *ptr); +/* store global pointer in TLS */ + +#define tls_get_ptr _glp_tls_get_ptr +void *tls_get_ptr(void); +/* retrieve global pointer from TLS */ + +#define xputs glp_puts +void glp_puts(const char *s); +/* write string on terminal */ + +#define xprintf glp_printf +void glp_printf(const char *fmt, ...); +/* write formatted output on terminal */ + +#define xvprintf glp_vprintf +void glp_vprintf(const char *fmt, va_list arg); +/* write formatted output on terminal */ + +int glp_term_out(int flag); +/* enable/disable terminal output */ + +void glp_term_hook(int (*func)(void *info, const char *s), void *info); +/* install hook to intercept terminal output */ + +int glp_open_tee(const char *fname); +/* start copying terminal output to text file */ + +int glp_close_tee(void); +/* stop copying terminal output to text file */ + +#ifndef GLP_ERRFUNC_DEFINED +#define GLP_ERRFUNC_DEFINED +typedef void (*glp_errfunc)(const char *fmt, ...); +#endif + +#define xerror glp_error_(__FILE__, __LINE__) +glp_errfunc glp_error_(const char *file, int line); +/* display fatal error message and terminate execution */ + +#define xassert(expr) \ + ((void)((expr) || (glp_assert_(#expr, __FILE__, __LINE__), 1))) +void glp_assert_(const char *expr, const char *file, int line); +/* check for logical condition */ + +void glp_error_hook(void (*func)(void *info), void *info); +/* install hook to intercept abnormal termination */ + +#define put_err_msg _glp_put_err_msg +void put_err_msg(const char *msg); +/* provide error message string */ + +#define get_err_msg _glp_get_err_msg +const char *get_err_msg(void); +/* obtain error message string */ + +#define xmalloc(size) glp_alloc(1, size) +/* allocate memory block (obsolete) */ + +#define xcalloc(n, size) glp_alloc(n, size) +/* allocate memory block (obsolete) */ + +#define xalloc(n, size) glp_alloc(n, size) +#define talloc(n, type) ((type *)glp_alloc(n, sizeof(type))) +void *glp_alloc(int n, int size); +/* allocate memory block */ + +#define xrealloc(ptr, n, size) glp_realloc(ptr, n, size) +#define trealloc(ptr, n, type) ((type *)glp_realloc(ptr, n, \ + sizeof(type))) +void *glp_realloc(void *ptr, int n, int size); +/* reallocate memory block */ + +#define xfree(ptr) glp_free(ptr) +#define tfree(ptr) glp_free(ptr) +void glp_free(void *ptr); +/* free memory block */ + +void glp_mem_limit(int limit); +/* set memory usage limit */ + +void glp_mem_usage(int *count, int *cpeak, size_t *total, + size_t *tpeak); +/* get memory usage information */ + +typedef struct glp_file glp_file; +/* sequential stream descriptor */ + +#define glp_open _glp_open +glp_file *glp_open(const char *name, const char *mode); +/* open stream */ + +#define glp_eof _glp_eof +int glp_eof(glp_file *f); +/* test end-of-file indicator */ + +#define glp_ioerr _glp_ioerr +int glp_ioerr(glp_file *f); +/* test I/O error indicator */ + +#define glp_read _glp_read +int glp_read(glp_file *f, void *buf, int nnn); +/* read data from stream */ + +#define glp_getc _glp_getc +int glp_getc(glp_file *f); +/* read character from stream */ + +#define glp_write _glp_write +int glp_write(glp_file *f, const void *buf, int nnn); +/* write data to stream */ + +#define glp_format _glp_format +int glp_format(glp_file *f, const char *fmt, ...); +/* write formatted data to stream */ + +#define glp_close _glp_close +int glp_close(glp_file *f); +/* close stream */ + +#define xtime glp_time +double glp_time(void); +/* determine current universal time */ + +#define xdifftime glp_difftime +double glp_difftime(double t1, double t0); +/* compute difference between two time values */ + +#define xdlopen _glp_dlopen +void *xdlopen(const char *module); +/* open dynamically linked library */ + +#define xdlsym _glp_dlsym +void *xdlsym(void *h, const char *symbol); +/* obtain address of symbol from dynamically linked library */ + +#define xdlclose _glp_dlclose +void xdlclose(void *h); +/* close dynamically linked library */ + +#endif + +/* eof */ diff --git a/test/monniaux/glpk-4.65/src/env/error.c b/test/monniaux/glpk-4.65/src/env/error.c new file mode 100644 index 00000000..a898b768 --- /dev/null +++ b/test/monniaux/glpk-4.65/src/env/error.c @@ -0,0 +1,200 @@ +/* error.c (error handling) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2015 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK 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 General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" + +/*********************************************************************** +* NAME +* +* glp_error - display fatal error message and terminate execution +* +* SYNOPSIS +* +* void glp_error(const char *fmt, ...); +* +* DESCRIPTION +* +* The routine glp_error (implemented as a macro) formats its +* parameters using the format control string fmt, writes the formatted +* message on the terminal, and abnormally terminates the program. */ + +static void errfunc(const char *fmt, ...) +{ ENV *env = get_env_ptr(); + va_list arg; +#if 1 /* 07/XI-2015 */ + env->err_st = 1; +#endif + env->term_out = GLP_ON; + va_start(arg, fmt); + xvprintf(fmt, arg); + va_end(arg); + xprintf("Error detected in file %s at line %d\n", + env->err_file, env->err_line); + if (env->err_hook != NULL) + env->err_hook(env->err_info); + abort(); + exit(EXIT_FAILURE); + /* no return */ +} + +glp_errfunc glp_error_(const char *file, int line) +{ ENV *env = get_env_ptr(); + env->err_file = file; + env->err_line = line; + return errfunc; +} + +#if 1 /* 07/XI-2015 */ +/*********************************************************************** +* NAME +* +* glp_at_error - check for error state +* +* SYNOPSIS +* +* int glp_at_error(void); +* +* DESCRIPTION +* +* The routine glp_at_error checks if the GLPK environment is at error +* state, i.e. if the call to the routine is (indirectly) made from the +* glp_error routine via an user-defined hook routine. +* +* RETURNS +* +* If the GLPK environment is at error state, the routine glp_at_error +* returns non-zero, otherwise zero. */ + +int glp_at_error(void) +{ ENV *env = get_env_ptr(); + return env->err_st; +} +#endif + +/*********************************************************************** +* NAME +* +* glp_assert - check for logical condition +* +* SYNOPSIS +* +* void glp_assert(int expr); +* +* DESCRIPTION +* +* The routine glp_assert (implemented as a macro) checks for a logical +* condition specified by the parameter expr. If the condition is false +* (i.e. the value of expr is zero), the routine writes a message on +* the terminal and abnormally terminates the program. */ + +void glp_assert_(const char *expr, const char *file, int line) +{ glp_error_(file, line)("Assertion failed: %s\n", expr); + /* no return */ +} + +/*********************************************************************** +* NAME +* +* glp_error_hook - install hook to intercept abnormal termination +* +* SYNOPSIS +* +* void glp_error_hook(void (*func)(void *info), void *info); +* +* DESCRIPTION +* +* The routine glp_error_hook installs a user-defined hook routine to +* intercept abnormal termination. +* +* The parameter func specifies the user-defined hook routine. It is +* called from the routine glp_error before the latter calls the abort +* function to abnormally terminate the application program because of +* fatal error. The parameter info is a transit pointer, specified in +* the corresponding call to the routine glp_error_hook; it may be used +* to pass some information to the hook routine. +* +* To uninstall the hook routine the parameters func and info should be +* both specified as NULL. */ + +void glp_error_hook(void (*func)(void *info), void *info) +{ ENV *env = get_env_ptr(); + if (func == NULL) + { env->err_hook = NULL; + env->err_info = NULL; + } + else + { env->err_hook = func; + env->err_info = info; + } + return; +} + +/*********************************************************************** +* NAME +* +* put_err_msg - provide error message string +* +* SYNOPSIS +* +* #include "env.h" +* void put_err_msg(const char *msg); +* +* DESCRIPTION +* +* The routine put_err_msg stores an error message string pointed to by +* msg to the environment block. */ + +void put_err_msg(const char *msg) +{ ENV *env = get_env_ptr(); + int len; + len = strlen(msg); + if (len >= EBUF_SIZE) + len = EBUF_SIZE - 1; + memcpy(env->err_buf, msg, len); + if (len > 0 && env->err_buf[len-1] == '\n') + len--; + env->err_buf[len] = '\0'; + return; +} + +/*********************************************************************** +* NAME +* +* get_err_msg - obtain error message string +* +* SYNOPSIS +* +* #include "env.h" +* const char *get_err_msg(void); +* +* RETURNS +* +* The routine get_err_msg returns a pointer to an error message string +* previously stored by the routine put_err_msg. */ + +const char *get_err_msg(void) +{ ENV *env = get_env_ptr(); + return env->err_buf; +} + +/* eof */ diff --git a/test/monniaux/glpk-4.65/src/env/stdc.c b/test/monniaux/glpk-4.65/src/env/stdc.c new file mode 100644 index 00000000..59331e22 --- /dev/null +++ b/test/monniaux/glpk-4.65/src/env/stdc.c @@ -0,0 +1,98 @@ +/* stdc.c (replacements for standard non-thread-safe functions) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2017 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK 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 General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +/* portable ANSI C version ********************************************/ + +#if !defined(TLS) + +#define ENABLE_NON_SAFE +#include "stdc.h" + +struct tm *xgmtime(const time_t *timer) +{ return + gmtime(timer); +} + +char *xstrerr(int errnum) +{ return + strerror(errnum); +} + +char *xstrtok(char *s1, const char *s2) +{ return + strtok(s1, s2); +} + +/* MS Windows version *************************************************/ + +#elif defined(__WOE__) + +#include "stdc.h" + +struct tm *xgmtime(const time_t *timer) +{ static TLS struct tm result; + gmtime_s(&result, timer); + return &result; +} + +char *xstrerr(int errnum) +{ static TLS char s[1023+1]; + strerror_s(s, sizeof(s), errnum); + return s; +} + +char *xstrtok(char *s1, const char *s2) +{ static TLS char *ptr; + return strtok_s(s1, s2, &ptr); +} + +/* GNU/Linux version **************************************************/ + +#else + +#include "stdc.h" + +struct tm *xgmtime(const time_t *timer) +{ static TLS struct tm result; + gmtime_r(timer, &result); + return &result; +} + +char *xstrerr(int errnum) +{ static TLS char s[1023+1]; + strerror_r(errnum, s, sizeof(s)); + return s; +} + +char *xstrtok(char *s1, const char *s2) +{ static TLS char *ptr; + return strtok_r(s1, s2, &ptr); +} + +#endif + +/* eof */ diff --git a/test/monniaux/glpk-4.65/src/env/stdc.h b/test/monniaux/glpk-4.65/src/env/stdc.h new file mode 100644 index 00000000..a376f2c9 --- /dev/null +++ b/test/monniaux/glpk-4.65/src/env/stdc.h @@ -0,0 +1,73 @@ +/* stdc.h (standard ANSI C headers) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2017 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK 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 General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifndef STDC_H +#define STDC_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ENABLE_NON_SAFE /* 29/I-2017 */ +/* disable using non-thread-safe functions directly */ +#undef gmtime +#define gmtime ??? +#undef strerror +#define strerror ??? +#undef strtok +#define strtok ??? +#endif + +#if 1 /* 29/I-2017 */ +/* provide replacements for these functions on a per-thread basis */ +#define xgmtime _glp_xgmtime +struct tm *xgmtime(const time_t *); +#define xstrerr _glp_xstrerr +char *xstrerr(int); +#define xstrtok _glp_xstrtok +char *xstrtok(char *, const char *); +#endif + +#if 1 /* 06/II-2018 */ +#ifdef HAVE_CONFIG_H +#include +#endif +#ifndef __WOE__ +#define CDECL +#else +#define CDECL __cdecl +#endif +#endif + +#endif + +/* eof */ diff --git a/test/monniaux/glpk-4.65/src/env/stdout.c b/test/monniaux/glpk-4.65/src/env/stdout.c new file mode 100644 index 00000000..94eee02a --- /dev/null +++ b/test/monniaux/glpk-4.65/src/env/stdout.c @@ -0,0 +1,262 @@ +/* stdout.c (terminal output) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2013 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK 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 General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#undef NDEBUG +#include +#include "env.h" + +/*********************************************************************** +* NAME +* +* glp_puts - write string on terminal +* +* SYNOPSIS +* +* void glp_puts(const char *s); +* +* The routine glp_puts writes the string s on the terminal. */ + +void glp_puts(const char *s) +{ ENV *env = get_env_ptr(); + /* if terminal output is disabled, do nothing */ + if (!env->term_out) + goto skip; + /* pass the string to the hook routine, if defined */ + if (env->term_hook != NULL) + { if (env->term_hook(env->term_info, s) != 0) + goto skip; + } + /* write the string on the terminal */ + fputs(s, stdout); + fflush(stdout); + /* write the string on the tee file, if required */ + if (env->tee_file != NULL) + { fputs(s, env->tee_file); + fflush(env->tee_file); + } +skip: return; +} + +/*********************************************************************** +* NAME +* +* glp_printf - write formatted output on terminal +* +* SYNOPSIS +* +* void glp_printf(const char *fmt, ...); +* +* DESCRIPTION +* +* The routine glp_printf uses the format control string fmt to format +* its parameters and writes the formatted output on the terminal. */ + +void glp_printf(const char *fmt, ...) +{ ENV *env = get_env_ptr(); + va_list arg; + /* if terminal output is disabled, do nothing */ + if (!env->term_out) + goto skip; + /* format the output */ + va_start(arg, fmt); + vsprintf(env->term_buf, fmt, arg); + /* (do not use xassert) */ + assert(strlen(env->term_buf) < TBUF_SIZE); + va_end(arg); + /* write the formatted output on the terminal */ + glp_puts(env->term_buf); +skip: return; +} + +/*********************************************************************** +* NAME +* +* glp_vprintf - write formatted output on terminal +* +* SYNOPSIS +* +* void glp_vprintf(const char *fmt, va_list arg); +* +* DESCRIPTION +* +* The routine glp_vprintf uses the format control string fmt to format +* its parameters specified by the list arg and writes the formatted +* output on the terminal. */ + +void glp_vprintf(const char *fmt, va_list arg) +{ ENV *env = get_env_ptr(); + /* if terminal output is disabled, do nothing */ + if (!env->term_out) + goto skip; + /* format the output */ + vsprintf(env->term_buf, fmt, arg); + /* (do not use xassert) */ + assert(strlen(env->term_buf) < TBUF_SIZE); + /* write the formatted output on the terminal */ + glp_puts(env->term_buf); +skip: return; +} + +/*********************************************************************** +* NAME +* +* glp_term_out - enable/disable terminal output +* +* SYNOPSIS +* +* int glp_term_out(int flag); +* +* DESCRIPTION +* +* Depending on the parameter flag the routine glp_term_out enables or +* disables terminal output performed by glpk routines: +* +* GLP_ON - enable terminal output; +* GLP_OFF - disable terminal output. +* +* RETURNS +* +* The routine glp_term_out returns the previous value of the terminal +* output flag. */ + +int glp_term_out(int flag) +{ ENV *env = get_env_ptr(); + int old = env->term_out; + if (!(flag == GLP_ON || flag == GLP_OFF)) + xerror("glp_term_out: flag = %d; invalid parameter\n", flag); + env->term_out = flag; + return old; +} + +/*********************************************************************** +* NAME +* +* glp_term_hook - install hook to intercept terminal output +* +* SYNOPSIS +* +* void glp_term_hook(int (*func)(void *info, const char *s), +* void *info); +* +* DESCRIPTION +* +* The routine glp_term_hook installs a user-defined hook routine to +* intercept all terminal output performed by glpk routines. +* +* This feature can be used to redirect the terminal output to other +* destination, for example to a file or a text window. +* +* The parameter func specifies the user-defined hook routine. It is +* called from an internal printing routine, which passes to it two +* parameters: info and s. The parameter info is a transit pointer, +* specified in the corresponding call to the routine glp_term_hook; +* it may be used to pass some information to the hook routine. The +* parameter s is a pointer to the null terminated character string, +* which is intended to be written to the terminal. If the hook routine +* returns zero, the printing routine writes the string s to the +* terminal in a usual way; otherwise, if the hook routine returns +* non-zero, no terminal output is performed. +* +* To uninstall the hook routine the parameters func and info should be +* specified as NULL. */ + +void glp_term_hook(int (*func)(void *info, const char *s), void *info) +{ ENV *env = get_env_ptr(); + if (func == NULL) + { env->term_hook = NULL; + env->term_info = NULL; + } + else + { env->term_hook = func; + env->term_info = info; + } + return; +} + +/*********************************************************************** +* NAME +* +* glp_open_tee - start copying terminal output to text file +* +* SYNOPSIS +* +* int glp_open_tee(const char *name); +* +* DESCRIPTION +* +* The routine glp_open_tee starts copying all the terminal output to +* an output text file, whose name is specified by the character string +* name. +* +* RETURNS +* +* 0 - operation successful +* 1 - copying terminal output is already active +* 2 - unable to create output file */ + +int glp_open_tee(const char *name) +{ ENV *env = get_env_ptr(); + if (env->tee_file != NULL) + { /* copying terminal output is already active */ + return 1; + } + env->tee_file = fopen(name, "w"); + if (env->tee_file == NULL) + { /* unable to create output file */ + return 2; + } + return 0; +} + +/*********************************************************************** +* NAME +* +* glp_close_tee - stop copying terminal output to text file +* +* SYNOPSIS +* +* int glp_close_tee(void); +* +* DESCRIPTION +* +* The routine glp_close_tee stops copying the terminal output to the +* output text file previously open by the routine glp_open_tee closing +* that file. +* +* RETURNS +* +* 0 - operation successful +* 1 - copying terminal output was not started */ + +int glp_close_tee(void) +{ ENV *env = get_env_ptr(); + if (env->tee_file == NULL) + { /* copying terminal output was not started */ + return 1; + } + fclose(env->tee_file); + env->tee_file = NULL; + return 0; +} + +/* eof */ diff --git a/test/monniaux/glpk-4.65/src/env/stream.c b/test/monniaux/glpk-4.65/src/env/stream.c new file mode 100644 index 00000000..906e5b04 --- /dev/null +++ b/test/monniaux/glpk-4.65/src/env/stream.c @@ -0,0 +1,517 @@ +/* stream.c (stream input/output) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2008-2017 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK 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 General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#include "env.h" +#include "zlib.h" + +struct glp_file +{ /* sequential stream descriptor */ + char *base; + /* pointer to buffer */ + int size; + /* size of buffer, in bytes */ + char *ptr; + /* pointer to next byte in buffer */ + int cnt; + /* count of bytes in buffer */ + int flag; + /* stream flags: */ +#define IONULL 0x01 /* null file */ +#define IOSTD 0x02 /* standard stream */ +#define IOGZIP 0x04 /* gzipped file */ +#define IOWRT 0x08 /* output stream */ +#define IOEOF 0x10 /* end of file */ +#define IOERR 0x20 /* input/output error */ + void *file; + /* pointer to underlying control object */ +}; + +/*********************************************************************** +* NAME +* +* glp_open - open stream +* +* SYNOPSIS +* +* glp_file *glp_open(const char *name, const char *mode); +* +* DESCRIPTION +* +* The routine glp_open opens a file whose name is a string pointed to +* by name and associates a stream with it. +* +* The following special filenames are recognized by the routine (this +* feature is platform independent): +* +* "/dev/null" empty (null) file; +* "/dev/stdin" standard input stream; +* "/dev/stdout" standard output stream; +* "/dev/stderr" standard error stream. +* +* If the specified filename is ended with ".gz", it is assumed that +* the file is in gzipped format. In this case the file is compressed +* or decompressed by the I/O routines "on the fly". +* +* The parameter mode points to a string, which indicates the open mode +* and should be one of the following: +* +* "r" open text file for reading; +* "w" truncate to zero length or create text file for writing; +* "a" append, open or create text file for writing at end-of-file; +* "rb" open binary file for reading; +* "wb" truncate to zero length or create binary file for writing; +* "ab" append, open or create binary file for writing at end-of-file. +* +* RETURNS +* +* The routine glp_open returns a pointer to the object controlling the +* stream. If the operation fails, the routine returns NULL. */ + +glp_file *glp_open(const char *name, const char *mode) +{ glp_file *f; + int flag; + void *file; + if (strcmp(mode, "r") == 0 || strcmp(mode, "rb") == 0) + flag = 0; + else if (strcmp(mode, "w") == 0 || strcmp(mode, "wb") == 0) + flag = IOWRT; +#if 1 /* 08/V-2014 */ + else if (strcmp(mode, "a") == 0 || strcmp(mode, "ab") == 0) + flag = IOWRT; +#endif + else + xerror("glp_open: invalid mode string\n"); + if (strcmp(name, "/dev/null") == 0) + { flag |= IONULL; + file = NULL; + } + else if (strcmp(name, "/dev/stdin") == 0) + { flag |= IOSTD; + file = stdin; + } + else if (strcmp(name, "/dev/stdout") == 0) + { flag |= IOSTD; + file = stdout; + } + else if (strcmp(name, "/dev/stderr") == 0) + { flag |= IOSTD; + file = stderr; + } + else + { char *ext = strrchr(name, '.'); + if (ext == NULL || strcmp(ext, ".gz") != 0) + { file = fopen(name, mode); + if (file == NULL) +#if 0 /* 29/I-2017 */ + { put_err_msg(strerror(errno)); +#else + { put_err_msg(xstrerr(errno)); +#endif + return NULL; + } + } + else + { flag |= IOGZIP; + if (strcmp(mode, "r") == 0) + mode = "rb"; + else if (strcmp(mode, "w") == 0) + mode = "wb"; +#if 1 /* 08/V-2014; this mode seems not to work */ + else if (strcmp(mode, "a") == 0) + mode = "ab"; +#endif + file = gzopen(name, mode); + if (file == NULL) +#if 0 /* 29/I-2017 */ + { put_err_msg(strerror(errno)); +#else + { put_err_msg(xstrerr(errno)); +#endif + return NULL; + } + } + } + f = talloc(1, glp_file); + f->base = talloc(BUFSIZ, char); + f->size = BUFSIZ; + f->ptr = f->base; + f->cnt = 0; + f->flag = flag; + f->file = file; + return f; +} + +/*********************************************************************** +* NAME +* +* glp_eof - test end-of-file indicator +* +* SYNOPSIS +* +* int glp_eof(glp_file *f); +* +* DESCRIPTION +* +* The routine glp_eof tests the end-of-file indicator for the stream +* pointed to by f. +* +* RETURNS +* +* The routine glp_eof returns non-zero if and only if the end-of-file +* indicator is set for the specified stream. */ + +int glp_eof(glp_file *f) +{ return + f->flag & IOEOF; +} + +/*********************************************************************** +* NAME +* +* glp_ioerr - test I/O error indicator +* +* SYNOPSIS +* +* int glp_ioerr(glp_file *f); +* +* DESCRIPTION +* +* The routine glp_ioerr tests the I/O error indicator for the stream +* pointed to by f. +* +* RETURNS +* +* The routine glp_ioerr returns non-zero if and only if the I/O error +* indicator is set for the specified stream. */ + +int glp_ioerr(glp_file *f) +{ return + f->flag & IOERR; +} + +/*********************************************************************** +* NAME +* +* glp_read - read data from stream +* +* SYNOPSIS +* +* int glp_read(glp_file *f, void *buf, int nnn); +* +* DESCRIPTION +* +* The routine glp_read reads, into the buffer pointed to by buf, up to +* nnn bytes, from the stream pointed to by f. +* +* RETURNS +* +* The routine glp_read returns the number of bytes successfully read +* (which may be less than nnn). If an end-of-file is encountered, the +* end-of-file indicator for the stream is set and glp_read returns +* zero. If a read error occurs, the error indicator for the stream is +* set and glp_read returns a negative value. */ + +int glp_read(glp_file *f, void *buf, int nnn) +{ int nrd, cnt; + if (f->flag & IOWRT) + xerror("glp_read: attempt to read from output stream\n"); + if (nnn < 1) + xerror("glp_read: nnn = %d; invalid parameter\n", nnn); + for (nrd = 0; nrd < nnn; nrd += cnt) + { if (f->cnt == 0) + { /* buffer is empty; fill it */ + if (f->flag & IONULL) + cnt = 0; + else if (!(f->flag & IOGZIP)) + { cnt = fread(f->base, 1, f->size, (FILE *)(f->file)); + if (ferror((FILE *)(f->file))) + { f->flag |= IOERR; +#if 0 /* 29/I-2017 */ + put_err_msg(strerror(errno)); +#else + put_err_msg(xstrerr(errno)); +#endif + return EOF; + } + } + else + { int errnum; + const char *msg; + cnt = gzread((gzFile)(f->file), f->base, f->size); + if (cnt < 0) + { f->flag |= IOERR; + msg = gzerror((gzFile)(f->file), &errnum); + if (errnum == Z_ERRNO) +#if 0 /* 29/I-2017 */ + put_err_msg(strerror(errno)); +#else + put_err_msg(xstrerr(errno)); +#endif + else + put_err_msg(msg); + return EOF; + } + } + if (cnt == 0) + { if (nrd == 0) + f->flag |= IOEOF; + break; + } + f->ptr = f->base; + f->cnt = cnt; + } + cnt = nnn - nrd; + if (cnt > f->cnt) + cnt = f->cnt; + memcpy((char *)buf + nrd, f->ptr, cnt); + f->ptr += cnt; + f->cnt -= cnt; + } + return nrd; +} + +/*********************************************************************** +* NAME +* +* glp_getc - read character from stream +* +* SYNOPSIS +* +* int glp_getc(glp_file *f); +* +* DESCRIPTION +* +* The routine glp_getc obtains a next character as an unsigned char +* converted to an int from the input stream pointed to by f. +* +* RETURNS +* +* The routine glp_getc returns the next character obtained. However, +* if an end-of-file is encountered or a read error occurs, the routine +* returns EOF. (An end-of-file and a read error can be distinguished +* by use of the routines glp_eof and glp_ioerr.) */ + +int glp_getc(glp_file *f) +{ unsigned char buf[1]; + if (f->flag & IOWRT) + xerror("glp_getc: attempt to read from output stream\n"); + if (glp_read(f, buf, 1) != 1) + return EOF; + return buf[0]; +} + +/*********************************************************************** +* do_flush - flush output stream +* +* This routine causes buffered data for the specified output stream to +* be written to the associated file. +* +* If the operation was successful, the routine returns zero, otherwise +* non-zero. */ + +static int do_flush(glp_file *f) +{ xassert(f->flag & IOWRT); + if (f->cnt > 0) + { if (f->flag & IONULL) + ; + else if (!(f->flag & IOGZIP)) + { if ((int)fwrite(f->base, 1, f->cnt, (FILE *)(f->file)) + != f->cnt) + { f->flag |= IOERR; +#if 0 /* 29/I-2017 */ + put_err_msg(strerror(errno)); +#else + put_err_msg(xstrerr(errno)); +#endif + return EOF; + } + } + else + { int errnum; + const char *msg; + if (gzwrite((gzFile)(f->file), f->base, f->cnt) != f->cnt) + { f->flag |= IOERR; + msg = gzerror((gzFile)(f->file), &errnum); + if (errnum == Z_ERRNO) +#if 0 /* 29/I-2017 */ + put_err_msg(strerror(errno)); +#else + put_err_msg(xstrerr(errno)); +#endif + else + put_err_msg(msg); + return EOF; + } + } + } + f->ptr = f->base; + f->cnt = 0; + return 0; +} + +/*********************************************************************** +* NAME +* +* glp_write - write data to stream +* +* SYNOPSIS +* +* int glp_write(glp_file *f, const void *buf, int nnn); +* +* DESCRIPTION +* +* The routine glp_write writes, from the buffer pointed to by buf, up +* to nnn bytes, to the stream pointed to by f. +* +* RETURNS +* +* The routine glp_write returns the number of bytes successfully +* written (which is equal to nnn). If a write error occurs, the error +* indicator for the stream is set and glp_write returns a negative +* value. */ + +int glp_write(glp_file *f, const void *buf, int nnn) +{ int nwr, cnt; + if (!(f->flag & IOWRT)) + xerror("glp_write: attempt to write to input stream\n"); + if (nnn < 1) + xerror("glp_write: nnn = %d; invalid parameter\n", nnn); + for (nwr = 0; nwr < nnn; nwr += cnt) + { cnt = nnn - nwr; + if (cnt > f->size - f->cnt) + cnt = f->size - f->cnt; + memcpy(f->ptr, (const char *)buf + nwr, cnt); + f->ptr += cnt; + f->cnt += cnt; + if (f->cnt == f->size) + { /* buffer is full; flush it */ + if (do_flush(f) != 0) + return EOF; + } + } + return nwr; +} + +/*********************************************************************** +* NAME +* +* glp_format - write formatted data to stream +* +* SYNOPSIS +* +* int glp_format(glp_file *f, const char *fmt, ...); +* +* DESCRIPTION +* +* The routine glp_format writes formatted data to the stream pointed +* to by f. The format control string pointed to by fmt specifies how +* subsequent arguments are converted for output. +* +* RETURNS +* +* The routine glp_format returns the number of characters written, or +* a negative value if an output error occurs. */ + +int glp_format(glp_file *f, const char *fmt, ...) +{ ENV *env = get_env_ptr(); + va_list arg; + int nnn; + if (!(f->flag & IOWRT)) + xerror("glp_format: attempt to write to input stream\n"); + va_start(arg, fmt); + nnn = vsprintf(env->term_buf, fmt, arg); + xassert(0 <= nnn && nnn < TBUF_SIZE); + va_end(arg); + return nnn == 0 ? 0 : glp_write(f, env->term_buf, nnn); +} + +/*********************************************************************** +* NAME +* +* glp_close - close stream +* +* SYNOPSIS +* +* int glp_close(glp_file *f); +* +* DESCRIPTION +* +* The routine glp_close closes the stream pointed to by f. +* +* RETURNS +* +* If the operation was successful, the routine returns zero, otherwise +* non-zero. */ + +int glp_close(glp_file *f) +{ int ret = 0; + if (f->flag & IOWRT) + { if (do_flush(f) != 0) + ret = EOF; + } + if (f->flag & (IONULL | IOSTD)) + ; + else if (!(f->flag & IOGZIP)) + { if (fclose((FILE *)(f->file)) != 0) + { if (ret == 0) +#if 0 /* 29/I-2017 */ + { put_err_msg(strerror(errno)); +#else + { put_err_msg(xstrerr(errno)); +#endif + ret = EOF; + } + } + } + else + { int errnum; + errnum = gzclose((gzFile)(f->file)); + if (errnum == Z_OK) + ; + else if (errnum == Z_ERRNO) + { if (ret == 0) +#if 0 /* 29/I-2017 */ + { put_err_msg(strerror(errno)); +#else + { put_err_msg(xstrerr(errno)); +#endif + ret = EOF; + } + } +#if 1 /* FIXME */ + else + { if (ret == 0) + { ENV *env = get_env_ptr(); + sprintf(env->term_buf, "gzclose returned %d", errnum); + put_err_msg(env->term_buf); + ret = EOF; + } + } +#endif + } + tfree(f->base); + tfree(f); + return ret; +} + +/* eof */ diff --git a/test/monniaux/glpk-4.65/src/env/time.c b/test/monniaux/glpk-4.65/src/env/time.c new file mode 100644 index 00000000..1ffb28e9 --- /dev/null +++ b/test/monniaux/glpk-4.65/src/env/time.c @@ -0,0 +1,150 @@ +/* time.c (standard time) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2000-2017 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK 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 General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "env.h" +#include "jd.h" + +/*********************************************************************** +* NAME +* +* glp_time - determine current universal time +* +* SYNOPSIS +* +* double glp_time(void); +* +* RETURNS +* +* The routine glp_time returns the current universal time (UTC), in +* milliseconds, elapsed since 00:00:00 GMT January 1, 1970. */ + +#define EPOCH 2440588 /* = jday(1, 1, 1970) */ + +/* POSIX version ******************************************************/ + +#if defined(HAVE_SYS_TIME_H) && defined(HAVE_GETTIMEOFDAY) + +#if 0 /* 29/VI-2017 */ +#include +#include + +double glp_time(void) +{ struct timeval tv; + struct tm *tm; + int j; + double t; + gettimeofday(&tv, NULL); +#if 0 /* 29/I-2017 */ + tm = gmtime(&tv.tv_sec); +#else + tm = xgmtime(&tv.tv_sec); +#endif + j = jday(tm->tm_mday, tm->tm_mon + 1, 1900 + tm->tm_year); + xassert(j >= 0); + t = ((((double)(j - EPOCH) * 24.0 + (double)tm->tm_hour) * 60.0 + + (double)tm->tm_min) * 60.0 + (double)tm->tm_sec) * 1000.0 + + (double)(tv.tv_usec / 1000); + return t; +} +#else +#include + +double glp_time(void) +{ struct timeval tv; + double t; + gettimeofday(&tv, NULL); + t = (double)tv.tv_sec + (double)(tv.tv_usec) / 1e6; + xassert(0.0 <= t && t < 4294967296.0); + return 1000.0 * t; +} +#endif + +/* MS Windows version *************************************************/ + +#elif defined(__WOE__) + +#include + +double glp_time(void) +{ SYSTEMTIME st; + int j; + double t; + GetSystemTime(&st); + j = jday(st.wDay, st.wMonth, st.wYear); + xassert(j >= 0); + t = ((((double)(j - EPOCH) * 24.0 + (double)st.wHour) * 60.0 + + (double)st.wMinute) * 60.0 + (double)st.wSecond) * 1000.0 + + (double)st.wMilliseconds; + return t; +} + +/* portable ANSI C version ********************************************/ + +#else + +#include + +double glp_time(void) +{ time_t timer; + struct tm *tm; + int j; + double t; + timer = time(NULL); +#if 0 /* 29/I-2017 */ + tm = gmtime(&timer); +#else + tm = xgmtime(&timer); +#endif + j = jday(tm->tm_mday, tm->tm_mon + 1, 1900 + tm->tm_year); + xassert(j >= 0); + t = ((((double)(j - EPOCH) * 24.0 + (double)tm->tm_hour) * 60.0 + + (double)tm->tm_min) * 60.0 + (double)tm->tm_sec) * 1000.0; + return t; +} + +#endif + +/*********************************************************************** +* NAME +* +* glp_difftime - compute difference between two time values +* +* SYNOPSIS +* +* double glp_difftime(double t1, double t0); +* +* RETURNS +* +* The routine glp_difftime returns the difference between two time +* values t1 and t0, expressed in seconds. */ + +double glp_difftime(double t1, double t0) +{ return + (t1 - t0) / 1000.0; +} + +/* eof */ diff --git a/test/monniaux/glpk-4.65/src/env/tls.c b/test/monniaux/glpk-4.65/src/env/tls.c new file mode 100644 index 00000000..4062ee4c --- /dev/null +++ b/test/monniaux/glpk-4.65/src/env/tls.c @@ -0,0 +1,128 @@ +/* tls.c (thread local storage) */ + +/*********************************************************************** +* This code is part of GLPK (GNU Linear Programming Kit). +* +* Copyright (C) 2001-2017 Andrew Makhorin, Department for Applied +* Informatics, Moscow Aviation Institute, Moscow, Russia. All rights +* reserved. E-mail: . +* +* GLPK is free software: you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GLPK 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 General Public +* License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GLPK. If not, see . +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "env.h" + +#ifndef TLS +static void *tls = NULL; +#else +static TLS void *tls = NULL; +/* this option allows running multiple independent instances of GLPK in + * different threads of a multi-threaded application, in which case the + * variable tls should be placed in the Thread Local Storage (TLS); + * it is assumed that the macro TLS is previously defined to something + * like '__thread', '_Thread_local', etc. */ +#endif + +/*********************************************************************** +* NAME +* +* tls_set_ptr - store global pointer in TLS +* +* SYNOPSIS +* +* #include "env.h" +* void tls_set_ptr(void *ptr); +* +* DESCRIPTION +* +* The routine tls_set_ptr stores a pointer specified by the parameter +* ptr in the Thread Local Storage (TLS). */ + +void tls_set_ptr(void *ptr) +{ tls = ptr; + return; +} + +/*********************************************************************** +* NAME +* +* tls_get_ptr - retrieve global pointer from TLS +* +* SYNOPSIS +* +* #include "env.h" +* void *tls_get_ptr(void); +* +* RETURNS +* +* The routine tls_get_ptr returns a pointer previously stored by the +* routine tls_set_ptr. If the latter has not been called yet, NULL is +* returned. */ + +void *tls_get_ptr(void) +{ void *ptr; + ptr = tls; + return ptr; +} + +/**********************************************************************/ + +#ifdef __WOE__ + +/*** Author: Heinrich Schuchardt ***/ + +#pragma comment(lib, "user32.lib") + +#include + +#define VISTA 0x06 + +/* This is the main entry point of the DLL. */ + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID + lpvReserved) +{ DWORD version; + DWORD major_version; +#ifdef TLS + switch (fdwReason) + { case DLL_PROCESS_ATTACH: + /* @TODO: + * GetVersion is deprecated but the version help functions are + * not available in Visual Studio 2010. So lets use it until + * we remove the outdated Build files. */ + version = GetVersion(); + major_version = version & 0xff; + if (major_version < VISTA) + { MessageBoxA(NULL, + "The GLPK library called by this application is configur" + "ed to use thread local storage which is not fully suppo" + "rted by your version of Microsoft Windows.\n\n" + "Microsoft Windows Vista or a later version of Windows i" + "s required to run this application.", + "GLPK", MB_OK | MB_ICONERROR); + return FALSE; + } + break; + } +#endif /* TLS */ + return TRUE; +} + +#endif /* __WOE__ */ + +/* eof */ -- cgit