int xfclose(XFILE *fp) { ENV *env = get_env_ptr(); int ret; switch (fp->type) { case FH_FILE: ret = c_fclose(fp->fh); break; case FH_ZLIB: ret = z_fclose(fp->fh); break; default: xassert(fp != fp); } fp->type = 0xF00BAD; if (fp->prev == NULL) env->file_ptr = fp->next; else fp->prev->next = fp->next; if (fp->next == NULL) ; else fp->next->prev = fp->prev; xfree(fp); return ret; }
void set_env_value(const char *key, const char *value, t_shell *shell) { int size; t_env *cur; char *var; size = my_strlen(key) + my_strlen(value) + 2; cur = get_env_ptr(key, shell->env); if (cur == NULL) { var = xmalloc(size); concat_env_var(var, key, value); shell->env = add_env_var(var, shell->env); } else { if (size > my_strlen(cur->var)) { var = xmalloc(size); concat_env_var(var, key, value); if (cur->var != NULL) free(cur->var); cur->var = var; } else concat_env_var(cur->var, key, value); } }
XFILE *xfopen(const char *fname, const char *mode) { ENV *env = get_env_ptr(); XFILE *fp; int type; void *fh; if (!is_gz_file(fname)) { type = FH_FILE; fh = c_fopen(fname, mode); } else { type = FH_ZLIB; fh = z_fopen(fname, mode); } if (fh == NULL) { fp = NULL; goto done; } fp = xmalloc(sizeof(XFILE)); fp->type = type; fp->fh = fh; fp->prev = NULL; fp->next = env->file_ptr; if (fp->next != NULL) fp->next->prev = fp; env->file_ptr = fp; done: return fp; }
void glp_puts(const char *s) { #ifdef HAVE_ENV 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; #else /* write the string on the terminal */ if (_term_hook_) _term_hook_(s); #endif }
void glp_printf(const char *fmt, ...) { #ifdef HAVE_ENV 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; #else char term_buf[TBUF_SIZE]; va_list arg; // if terminal output is disabled, do nothing if (!_term_hook_) return; // format the output va_start(arg, fmt); vsprintf(term_buf, fmt, arg); // (do not use xassert) assert(strlen(term_buf) < TBUF_SIZE); va_end(arg); // write the formatted output on the terminal glp_puts(term_buf); #endif }
void *glp_malloc(int size) { ENV *env = get_env_ptr(); MEM *desc; int size_of_desc = align_datasize(sizeof(MEM)); if (size < 1 || size > INT_MAX - size_of_desc) xerror("glp_malloc: size = %d; invalid parameter\n", size); size += size_of_desc; if (xlcmp(xlset(size), xlsub(env->mem_limit, env->mem_total)) > 0) xerror("glp_malloc: memory limit exceeded\n"); if (env->mem_count == INT_MAX) xerror("glp_malloc: too many memory blocks allocated\n"); desc = malloc(size); if (desc == NULL) xerror("glp_malloc: no memory available\n"); memset(desc, '?', size); desc->flag = MEM_MAGIC; desc->size = size; desc->prev = NULL; desc->next = env->mem_ptr; if (desc->next != NULL) desc->next->prev = desc; env->mem_ptr = desc; env->mem_count++; if (env->mem_cpeak < env->mem_count) env->mem_cpeak = env->mem_count; env->mem_total = xladd(env->mem_total, xlset(size)); if (xlcmp(env->mem_tpeak, env->mem_total) < 0) env->mem_tpeak = env->mem_total; return (void *)((char *)desc + size_of_desc); }
void glp_free(void *ptr) { ENV *env = get_env_ptr(); MEM *desc; int size_of_desc = align_datasize(sizeof(MEM)); if (ptr == NULL) xerror("glp_free: ptr = %p; null pointer\n", ptr); desc = (void *)((char *)ptr - size_of_desc); if (desc->flag != MEM_MAGIC) xerror("glp_free: ptr = %p; invalid pointer\n", ptr); if (env->mem_count == 0 || xlcmp(env->mem_total, xlset(desc->size)) < 0) xerror("glp_free: memory allocation error\n"); if (desc->prev == NULL) env->mem_ptr = desc->next; else desc->prev->next = desc->next; if (desc->next == NULL) ; else desc->next->prev = desc->prev; env->mem_count--; env->mem_total = xlsub(env->mem_total, xlset(desc->size)); memset(desc, '?', size_of_desc); free(desc); return; }
void ufree(void *ptr) { ENV *env = get_env_ptr(); MEM *desc; int size_of_desc = align_datasize(sizeof(MEM)); if (ptr == NULL) fault("ufree: null pointer"); desc = (void *)((char *)ptr - size_of_desc); if (desc->flag != MEM_FLAG) fault("ufree: invalid pointer"); if (env->mem_total < desc->size || env->mem_count == 0) fault("ufree: memory allocation error"); if (desc->prev == NULL) env->mem_ptr = desc->next; else desc->prev->next = desc->next; if (desc->next == NULL) ; else desc->next->prev = desc->prev; env->mem_total -= desc->size; env->mem_count--; memset(desc, '?', size_of_desc); free(desc); return; }
void *umalloc(int size) { ENV *env = get_env_ptr(); MEM *desc; int size_of_desc = align_datasize(sizeof(MEM)); if (size < 1) fault("umalloc: invalid size"); if (size > INT_MAX - size_of_desc) fault("umalloc: size too big"); size += size_of_desc; if (size > env->mem_limit - env->mem_total) fault("umalloc: no memory available"); desc = malloc(size); if (desc == NULL) fault("umalloc: malloc failed"); #if 1 memset(desc, '?', size); #endif desc->size = size; desc->flag = MEM_FLAG; desc->prev = NULL; desc->next = env->mem_ptr; if (desc->next != NULL) desc->next->prev = desc; env->mem_ptr = desc; env->mem_total += size; if (env->mem_tpeak < env->mem_total) env->mem_tpeak = env->mem_total; env->mem_count++; if (env->mem_cpeak < env->mem_count) env->mem_cpeak = env->mem_count; return (void *)((char *)desc + size_of_desc); }
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 value\n", flag); env->term_out = flag; return old; }
void glp_mem_limit(int limit) { ENV *env = get_env_ptr(); if (limit < 0) xerror("glp_mem_limit: limit = %d; invalid parameter\n", limit); env->mem_limit = xlmul(xlset(limit), xlset(1 << 20)); return; }
void glp_mem_usage(int *count, int *cpeak, glp_long *total, glp_long *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; }
void lib_err_msg(const char *msg) { ENV *env = get_env_ptr(); int len = strlen(msg); if (len >= IOERR_MSG_SIZE) len = IOERR_MSG_SIZE - 1; memcpy(env->ioerr_msg, msg, len); if (len > 0 && env->ioerr_msg[len-1] == '\n') len--; env->ioerr_msg[len] = '\0'; return; }
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; }
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; }
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; }
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; }
int glp_open_tee(const char *fname) { ENV *env = get_env_ptr(); if (env->tee_file != NULL) { /* copying terminal output is already active */ return 1; } env->tee_file = fopen(fname, "w"); if (env->tee_file == NULL) { /* unable to create output file */ return 2; } return 0; }
int glp_term_out(int flag) { #ifdef HAVE_ENV 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; #else return GLP_OFF; #endif }
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; }
static void error(const char *fmt, ...) { ENV *env = get_env_ptr(); va_list arg; 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 */ }
int xfprintf(XFILE *file, const char *fmt, ...) { ENV *env = get_env_ptr(); int cnt, j; va_list arg; va_start(arg, fmt); cnt = vsprintf(env->term_buf, fmt, arg); va_end(arg); for (j = 0; j < cnt; j++) { if (xfputc(env->term_buf[j], file) < 0) { cnt = -1; break; } } return cnt; }
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); */ /* /\* pass the output to the user-defined routine *\/ */ /* if (env->term_hook != NULL) */ /* { if (env->term_hook(env->term_info, env->term_buf) != 0) */ /* goto skip; */ /* } */ /* /\* send the output to the terminal *\/ */ /* fputs(env->term_buf, stdout); */ /* fflush(stdout); */ /* /\* copy the output to the text file *\/ */ /* if (env->tee_file != NULL) */ /* { fputs(env->term_buf, env->tee_file); */ /* fflush(env->tee_file); */ /* } */ skip: return; }
static int preprocess_and_solve_mip(glp_prob *P, const glp_iocp *parm) { /* solve MIP using the preprocessor */ ENV *env = get_env_ptr(); int term_out = env->term_out; NPP *npp; glp_prob *mip = NULL; glp_bfcp bfcp; glp_smcp smcp; int ret; if (parm->msg_lev >= GLP_MSG_ALL) xprintf("Preprocessing...\n"); /* create preprocessor workspace */ npp = npp_create_wksp(); /* load original problem into the preprocessor workspace */ npp_load_prob(npp, P, GLP_OFF, GLP_MIP, GLP_OFF); /* process MIP prior to applying the branch-and-bound method */ if (!term_out || parm->msg_lev < GLP_MSG_ALL) env->term_out = GLP_OFF; else env->term_out = GLP_ON; ret = npp_integer(npp, parm); env->term_out = term_out; if (ret == 0) ; else if (ret == GLP_ENOPFS) { if (parm->msg_lev >= GLP_MSG_ALL) xprintf("PROBLEM HAS NO PRIMAL FEASIBLE SOLUTION\n"); } else if (ret == GLP_ENODFS) { if (parm->msg_lev >= GLP_MSG_ALL) xprintf("LP RELAXATION HAS NO DUAL FEASIBLE SOLUTION\n"); } else xassert(ret != ret); if (ret != 0) goto done; /* build transformed MIP */ mip = glp_create_prob(); npp_build_prob(npp, mip); /* if the transformed MIP is empty, it has empty solution, which is optimal */ if (mip->m == 0 && mip->n == 0) { mip->mip_stat = GLP_OPT; mip->mip_obj = mip->c0; if (parm->msg_lev >= GLP_MSG_ALL) { xprintf("Objective value = %17.9e\n", mip->mip_obj); xprintf("INTEGER OPTIMAL SOLUTION FOUND BY MIP PREPROCESSOR" "\n"); } goto post; } /* display some statistics */ if (parm->msg_lev >= GLP_MSG_ALL) { int ni = glp_get_num_int(mip); int nb = glp_get_num_bin(mip); char s[50]; xprintf("%d row%s, %d column%s, %d non-zero%s\n", mip->m, mip->m == 1 ? "" : "s", mip->n, mip->n == 1 ? "" : "s", mip->nnz, mip->nnz == 1 ? "" : "s"); if (nb == 0) strcpy(s, "none of"); else if (ni == 1 && nb == 1) strcpy(s, ""); else if (nb == 1) strcpy(s, "one of"); else if (nb == ni) strcpy(s, "all of"); else sprintf(s, "%d of", nb); xprintf("%d integer variable%s, %s which %s binary\n", ni, ni == 1 ? "" : "s", s, nb == 1 ? "is" : "are"); } /* inherit basis factorization control parameters */ glp_get_bfcp(P, &bfcp); glp_set_bfcp(mip, &bfcp); /* scale the transformed problem */ if (!term_out || parm->msg_lev < GLP_MSG_ALL) env->term_out = GLP_OFF; else env->term_out = GLP_ON; glp_scale_prob(mip, GLP_SF_GM | GLP_SF_EQ | GLP_SF_2N | GLP_SF_SKIP); env->term_out = term_out; /* build advanced initial basis */ if (!term_out || parm->msg_lev < GLP_MSG_ALL) env->term_out = GLP_OFF; else env->term_out = GLP_ON; glp_adv_basis(mip, 0); env->term_out = term_out; /* solve initial LP relaxation */ if (parm->msg_lev >= GLP_MSG_ALL) xprintf("Solving LP relaxation...\n"); glp_init_smcp(&smcp); smcp.msg_lev = parm->msg_lev; mip->it_cnt = P->it_cnt; ret = glp_simplex(mip, &smcp); P->it_cnt = mip->it_cnt; if (ret != 0) { if (parm->msg_lev >= GLP_MSG_ERR) xprintf("glp_intopt: cannot solve LP relaxation\n"); ret = GLP_EFAIL; goto done; } /* check status of the basic solution */ ret = glp_get_status(mip); if (ret == GLP_OPT) ret = 0; else if (ret == GLP_NOFEAS) ret = GLP_ENOPFS; else if (ret == GLP_UNBND) ret = GLP_ENODFS; else xassert(ret != ret); if (ret != 0) goto done; /* solve the transformed MIP */ mip->it_cnt = P->it_cnt; #if 0 /* 11/VII-2013 */ ret = solve_mip(mip, parm); #else if (parm->use_sol) { mip->mip_stat = P->mip_stat; mip->mip_obj = P->mip_obj; } ret = solve_mip(mip, parm, P, npp); #endif P->it_cnt = mip->it_cnt; /* only integer feasible solution can be postprocessed */ if (!(mip->mip_stat == GLP_OPT || mip->mip_stat == GLP_FEAS)) { P->mip_stat = mip->mip_stat; goto done; } /* postprocess solution from the transformed MIP */ post: npp_postprocess(npp, mip); /* the transformed MIP is no longer needed */ glp_delete_prob(mip), mip = NULL; /* store solution to the original problem */ npp_unload_sol(npp, P); done: /* delete the transformed MIP, if it exists */ if (mip != NULL) glp_delete_prob(mip); /* delete preprocessor workspace */ npp_delete_wksp(npp); return ret; }
_glp_error glp_error_(const char *file, int line) { ENV *env = get_env_ptr(); env->err_file = file; env->err_line = line; return error; }
const char *get_err_msg(void) { ENV *env = get_env_ptr(); return env->err_buf; }
static int preprocess_and_solve_lp(glp_prob *P, const glp_smcp *parm) { /* solve LP using the preprocessor */ NPP *npp; glp_prob *lp = NULL; glp_bfcp bfcp; int ret; if (parm->msg_lev >= GLP_MSG_ALL) xprintf("Preprocessing...\n"); /* create preprocessor workspace */ npp = npp_create_wksp(); /* load original problem into the preprocessor workspace */ npp_load_prob(npp, P, GLP_OFF, GLP_SOL, GLP_OFF); /* process LP prior to applying primal/dual simplex method */ ret = npp_simplex(npp, parm); if (ret == 0) ; else if (ret == GLP_ENOPFS) { if (parm->msg_lev >= GLP_MSG_ALL) xprintf("PROBLEM HAS NO PRIMAL FEASIBLE SOLUTION\n"); } else if (ret == GLP_ENODFS) { if (parm->msg_lev >= GLP_MSG_ALL) xprintf("PROBLEM HAS NO DUAL FEASIBLE SOLUTION\n"); } else xassert(ret != ret); if (ret != 0) goto done; /* build transformed LP */ lp = glp_create_prob(); npp_build_prob(npp, lp); /* if the transformed LP is empty, it has empty solution, which is optimal */ if (lp->m == 0 && lp->n == 0) { lp->pbs_stat = lp->dbs_stat = GLP_FEAS; lp->obj_val = lp->c0; if (parm->msg_lev >= GLP_MSG_ON && parm->out_dly == 0) { xprintf("~%6d: obj = %17.9e infeas = %10.3e\n", P->it_cnt, lp->obj_val, 0.0); } if (parm->msg_lev >= GLP_MSG_ALL) xprintf("OPTIMAL SOLUTION FOUND BY LP PREPROCESSOR\n"); goto post; } if (parm->msg_lev >= GLP_MSG_ALL) { xprintf("%d row%s, %d column%s, %d non-zero%s\n", lp->m, lp->m == 1 ? "" : "s", lp->n, lp->n == 1 ? "" : "s", lp->nnz, lp->nnz == 1 ? "" : "s"); } /* inherit basis factorization control parameters */ glp_get_bfcp(P, &bfcp); glp_set_bfcp(lp, &bfcp); /* scale the transformed problem */ { ENV *env = get_env_ptr(); int term_out = env->term_out; if (!term_out || parm->msg_lev < GLP_MSG_ALL) env->term_out = GLP_OFF; else env->term_out = GLP_ON; glp_scale_prob(lp, GLP_SF_AUTO); env->term_out = term_out; } /* build advanced initial basis */ { ENV *env = get_env_ptr(); int term_out = env->term_out; if (!term_out || parm->msg_lev < GLP_MSG_ALL) env->term_out = GLP_OFF; else env->term_out = GLP_ON; glp_adv_basis(lp, 0); env->term_out = term_out; } /* solve the transformed LP */ lp->it_cnt = P->it_cnt; ret = solve_lp(lp, parm); P->it_cnt = lp->it_cnt; /* only optimal solution can be postprocessed */ if (!(ret == 0 && lp->pbs_stat == GLP_FEAS && lp->dbs_stat == GLP_FEAS)) { if (parm->msg_lev >= GLP_MSG_ERR) xprintf("glp_simplex: unable to recover undefined or non-op" "timal solution\n"); if (ret == 0) { if (lp->pbs_stat == GLP_NOFEAS) ret = GLP_ENOPFS; else if (lp->dbs_stat == GLP_NOFEAS) ret = GLP_ENODFS; else xassert(lp != lp); } goto done; } post: /* postprocess solution from the transformed LP */ npp_postprocess(npp, lp); /* the transformed LP is no longer needed */ glp_delete_prob(lp), lp = NULL; /* store solution to the original problem */ npp_unload_sol(npp, P); /* the original LP has been successfully solved */ ret = 0; done: /* delete the transformed LP, if it exists */ if (lp != NULL) glp_delete_prob(lp); /* delete preprocessor workspace */ npp_delete_wksp(npp); return ret; }
const char *xerrmsg(void) { ENV *env = get_env_ptr(); return env->ioerr_msg; }
const char *glp_version(void) { ENV *env = get_env_ptr(); return env->version; }