alpar@1: /* glpenv01.c (environment initialization/termination) */ alpar@1: alpar@1: /*********************************************************************** alpar@1: * This code is part of GLPK (GNU Linear Programming Kit). alpar@1: * alpar@1: * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, alpar@1: * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, alpar@1: * Moscow Aviation Institute, Moscow, Russia. All rights reserved. alpar@1: * E-mail: . alpar@1: * alpar@1: * GLPK is free software: you can redistribute it and/or modify it alpar@1: * under the terms of the GNU General Public License as published by alpar@1: * the Free Software Foundation, either version 3 of the License, or alpar@1: * (at your option) any later version. alpar@1: * alpar@1: * GLPK is distributed in the hope that it will be useful, but WITHOUT alpar@1: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY alpar@1: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public alpar@1: * License for more details. alpar@1: * alpar@1: * You should have received a copy of the GNU General Public License alpar@1: * along with GLPK. If not, see . alpar@1: ***********************************************************************/ alpar@1: alpar@1: #include "glpapi.h" alpar@1: alpar@1: /*********************************************************************** alpar@1: * NAME alpar@1: * alpar@1: * glp_init_env - initialize GLPK environment alpar@1: * alpar@1: * SYNOPSIS alpar@1: * alpar@1: * int glp_init_env(void); alpar@1: * alpar@1: * DESCRIPTION alpar@1: * alpar@1: * The routine glp_init_env initializes the GLPK environment. Normally alpar@1: * the application program does not need to call this routine, because alpar@1: * it is called automatically on the first call to any API routine. alpar@1: * alpar@1: * RETURNS alpar@1: * alpar@1: * The routine glp_init_env returns one of the following codes: alpar@1: * alpar@1: * 0 - initialization successful; alpar@1: * 1 - environment has been already initialized; alpar@1: * 2 - initialization failed (insufficient memory); alpar@1: * 3 - initialization failed (unsupported programming model). */ alpar@1: alpar@1: int glp_init_env(void) alpar@1: { ENV *env; alpar@1: int ok; alpar@1: /* check if the programming model is supported */ alpar@1: ok = (CHAR_BIT == 8 && sizeof(char) == 1 && alpar@1: sizeof(short) == 2 && sizeof(int) == 4 && alpar@1: (sizeof(void *) == 4 || sizeof(void *) == 8)); alpar@1: if (!ok) return 3; alpar@1: /* check if the environment is already initialized */ alpar@1: if (tls_get_ptr() != NULL) return 1; alpar@1: /* allocate and initialize the environment block */ alpar@1: env = malloc(sizeof(ENV)); alpar@1: if (env == NULL) return 2; alpar@1: env->magic = ENV_MAGIC; alpar@1: sprintf(env->version, "%d.%d", alpar@1: GLP_MAJOR_VERSION, GLP_MINOR_VERSION); alpar@1: env->term_buf = malloc(TERM_BUF_SIZE); alpar@1: if (env->term_buf == NULL) alpar@1: { free(env); alpar@1: return 2; alpar@1: } alpar@1: env->term_out = GLP_ON; alpar@1: env->term_hook = NULL; alpar@1: env->term_info = NULL; alpar@1: env->tee_file = NULL; alpar@1: env->err_file = ""; alpar@1: env->err_line = 0; alpar@1: env->err_hook = NULL; alpar@1: env->err_info = NULL; alpar@1: env->mem_limit.hi = 0x7FFFFFFF, env->mem_limit.lo = 0xFFFFFFFF; alpar@1: env->mem_ptr = NULL; alpar@1: env->mem_count = env->mem_cpeak = 0; alpar@1: env->mem_total = env->mem_tpeak = xlset(0); alpar@1: env->file_ptr = NULL; alpar@1: env->ioerr_msg = malloc(IOERR_MSG_SIZE); alpar@1: if (env->ioerr_msg == NULL) alpar@1: { free(env->term_buf); alpar@1: free(env); alpar@1: return 2; alpar@1: } alpar@1: strcpy(env->ioerr_msg, "No error"); alpar@1: env->h_odbc = env->h_mysql = NULL; alpar@1: /* save pointer to the environment block */ alpar@1: tls_set_ptr(env); alpar@1: /* initialization successful */ alpar@1: return 0; alpar@1: } alpar@1: alpar@1: /*********************************************************************** alpar@1: * NAME alpar@1: * alpar@1: * get_env_ptr - retrieve pointer to environment block alpar@1: * alpar@1: * SYNOPSIS alpar@1: * alpar@1: * #include "glpenv.h" alpar@1: * ENV *get_env_ptr(void); alpar@1: * alpar@1: * DESCRIPTION alpar@1: * alpar@1: * The routine get_env_ptr retrieves and returns a pointer to the GLPK alpar@1: * environment block. alpar@1: * alpar@1: * If the GLPK environment has not been initialized yet, the routine alpar@1: * performs initialization. If initialization fails, the routine prints alpar@1: * an error message to stderr and terminates the program. alpar@1: * alpar@1: * RETURNS alpar@1: * alpar@1: * The routine returns a pointer to the environment block. */ alpar@1: alpar@1: ENV *get_env_ptr(void) alpar@1: { ENV *env = tls_get_ptr(); alpar@1: /* check if the environment has been initialized */ alpar@1: if (env == NULL) alpar@1: { /* not initialized yet; perform initialization */ alpar@1: if (glp_init_env() != 0) alpar@1: { /* initialization failed; display an error message */ alpar@1: fprintf(stderr, "GLPK initialization failed\n"); alpar@1: fflush(stderr); alpar@1: /* and abnormally terminate the program */ alpar@1: abort(); alpar@1: } alpar@1: /* initialization successful; retrieve the pointer */ alpar@1: env = tls_get_ptr(); alpar@1: } alpar@1: /* check if the environment block is valid */ alpar@1: if (env->magic != ENV_MAGIC) alpar@1: { fprintf(stderr, "Invalid GLPK environment\n"); alpar@1: fflush(stderr); alpar@1: abort(); alpar@1: } alpar@1: return env; alpar@1: } alpar@1: alpar@1: /*********************************************************************** alpar@1: * NAME alpar@1: * alpar@1: * glp_version - determine library version alpar@1: * alpar@1: * SYNOPSIS alpar@1: * alpar@1: * const char *glp_version(void); alpar@1: * alpar@1: * RETURNS alpar@1: * alpar@1: * The routine glp_version returns a pointer to a null-terminated alpar@1: * character string, which specifies the version of the GLPK library in alpar@1: * the form "X.Y", where X is the major version number, and Y is the alpar@1: * minor version number, for example, "4.16". */ alpar@1: alpar@1: const char *glp_version(void) alpar@1: { ENV *env = get_env_ptr(); alpar@1: return env->version; alpar@1: } alpar@1: alpar@1: /*********************************************************************** alpar@1: * NAME alpar@1: * alpar@1: * glp_free_env - free GLPK environment alpar@1: * alpar@1: * SYNOPSIS alpar@1: * alpar@1: * int glp_free_env(void); alpar@1: * alpar@1: * DESCRIPTION alpar@1: * alpar@1: * The routine glp_free_env frees all resources used by GLPK routines alpar@1: * (memory blocks, etc.) which are currently still in use. alpar@1: * alpar@1: * Normally the application program does not need to call this routine, alpar@1: * because GLPK routines always free all unused resources. However, if alpar@1: * the application program even has deleted all problem objects, there alpar@1: * will be several memory blocks still allocated for the library needs. alpar@1: * For some reasons the application program may want GLPK to free this alpar@1: * memory, in which case it should call glp_free_env. alpar@1: * alpar@1: * Note that a call to glp_free_env invalidates all problem objects as alpar@1: * if no GLPK routine were called. alpar@1: * alpar@1: * RETURNS alpar@1: * alpar@1: * 0 - termination successful; alpar@1: * 1 - environment is inactive (was not initialized). */ alpar@1: alpar@1: int glp_free_env(void) alpar@1: { ENV *env = tls_get_ptr(); alpar@1: MEM *desc; alpar@1: /* check if the environment is active */ alpar@1: if (env == NULL) return 1; alpar@1: /* check if the environment block is valid */ alpar@1: if (env->magic != ENV_MAGIC) alpar@1: { fprintf(stderr, "Invalid GLPK environment\n"); alpar@1: fflush(stderr); alpar@1: abort(); alpar@1: } alpar@1: /* close handles to shared libraries */ alpar@1: if (env->h_odbc != NULL) alpar@1: xdlclose(env->h_odbc); alpar@1: if (env->h_mysql != NULL) alpar@1: xdlclose(env->h_mysql); alpar@1: /* close streams which are still open */ alpar@1: while (env->file_ptr != NULL) alpar@1: xfclose(env->file_ptr); alpar@1: /* free memory blocks which are still allocated */ alpar@1: while (env->mem_ptr != NULL) alpar@1: { desc = env->mem_ptr; alpar@1: env->mem_ptr = desc->next; alpar@1: free(desc); alpar@1: } alpar@1: /* invalidate the environment block */ alpar@1: env->magic = -1; alpar@1: /* free memory allocated to the environment block */ alpar@1: free(env->term_buf); alpar@1: free(env->ioerr_msg); alpar@1: free(env); alpar@1: /* reset a pointer to the environment block */ alpar@1: tls_set_ptr(NULL); alpar@1: /* termination successful */ alpar@1: return 0; alpar@1: } alpar@1: alpar@1: /* eof */