⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 glplib08.c

📁 著名的大规模线性规划求解器源码GLPK.C语言版本,可以修剪.内有详细帮助文档.
💻 C
字号:
/* glplib08.c (stream input/output) *//************************************************************************  This code is part of GLPK (GNU Linear Programming Kit).**  Copyright (C) 2000,01,02,03,04,05,06,07,08,2009 Andrew Makhorin,*  Department for Applied Informatics, Moscow Aviation Institute,*  Moscow, Russia. All rights reserved. E-mail: <mao@mai2.rcnet.ru>.**  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 <http://www.gnu.org/licenses/>.***********************************************************************/#define _GLPSTD_ERRNO#define _GLPSTD_STDIO#include "glplib.h"/************************************************************************  NAME**  xfopen - open a stream**  SYNOPSIS**  #include "glplib.h"*  XFILE *xfopen(const char *fname, const char *mode);**  DESCRIPTION**  The routine xfopen opens the file whose name is a string pointed to*  by fname and associates a stream with it.**  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;*  "rb"  open binary file for reading;*  "wb"  truncate to zero length or create binary file for writing.**  RETURNS**  The routine xfopen returns a pointer to the object controlling the*  stream. If the open operation fails, xfopen returns NULL. */static void *c_fopen(const char *fname, const char *mode);static void *z_fopen(const char *fname, const char *mode);static int is_gz_file(const char *fname){     char *ext = strrchr(fname, '.');      return ext != NULL && strcmp(ext, ".gz") == 0;}XFILE *xfopen(const char *fname, const char *mode){     LIBENV *env = lib_link_env();      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;}/************************************************************************  NAME**  xfgetc - read character from the stream**  SYNOPSIS**  #include "glplib.h"*  int xfgetc(XFILE *fp);**  DESCRIPTION**  If the end-of-file indicator for the input stream pointed to by fp*  is not set and a next character is present, the routine xfgetc*  obtains that character as an unsigned char converted to an int and*  advances the associated file position indicator for the stream (if*  defined).**  RETURNS**  If the end-of-file indicator for the stream is set, or if the*  stream is at end-of-file, the end-of-file indicator for the stream*  is set and the routine xfgetc returns XEOF. Otherwise, the routine*  xfgetc returns the next character from the input stream pointed to*  by fp. If a read error occurs, the error indicator for the stream is*  set and the xfgetc routine returns XEOF.**  Note: An end-of-file and a read error can be distinguished by use of*  the routines xfeof and xferror. */static int c_fgetc(void *fh);static int z_fgetc(void *fh);int xfgetc(XFILE *fp){     int c;      switch (fp->type)      {  case FH_FILE:            c = c_fgetc(fp->fh);            break;         case FH_ZLIB:            c = z_fgetc(fp->fh);            break;         default:            xassert(fp != fp);      }      return c;}/************************************************************************  NAME**  xfputc - write character to the stream**  SYNOPSIS**  #include "glplib.h"*  int xfputc(int c, XFILE *fp);**  DESCRIPTION**  The routine xfputc writes the character specified by c (converted*  to an unsigned char) to the output stream pointed to by fp, at the*  position indicated by the associated file position indicator (if*  defined), and advances the indicator appropriately.**  RETURNS**  The routine xfputc returns the character written. If a write error*  occurs, the error indicator for the stream is set and xfputc returns*  XEOF. */static int c_fputc(int c, void *fh);static int z_fputc(int c, void *fh);int xfputc(int c, XFILE *fp){     switch (fp->type)      {  case FH_FILE:            c = c_fputc(c, fp->fh);            break;         case FH_ZLIB:            c = z_fputc(c, fp->fh);            break;         default:            xassert(fp != fp);      }      return c;}/************************************************************************  NAME**  xferror - test error indicator for the stream**  SYNOPSIS**  #include "glplib.h"*  int xferror(XFILE *fp);**  DESCRIPTION**  The routine xferror tests the error indicator for the stream*  pointed to by fp.**  RETURNS**  The routine xferror returns non-zero if and only if the error*  indicator is set for the stream. */static int c_ferror(void *fh);static int z_ferror(void *fh);int xferror(XFILE *fp){     int ret;      switch (fp->type)      {  case FH_FILE:            ret = c_ferror(fp->fh);            break;         case FH_ZLIB:            ret = z_ferror(fp->fh);            break;         default:            xassert(fp != fp);      }      return ret;}/************************************************************************  NAME**  xfeof - test end-of-file indicator for the stream**  SYNOPSIS**  #include "glplib.h"*  int xfeof(XFILE *fp);**  DESCRIPTION**  The routine xfeof tests the end-of-file indicator for the stream*  pointed to by fp.**  RETURNS**  The routine xfeof returns non-zero if and only if the end-of-file*  indicator is set for the stream. */static int c_feof(void *fh);static int z_feof(void *fh);int xfeof(XFILE *fp){     int ret;      switch (fp->type)      {  case FH_FILE:            ret = c_feof(fp->fh);            break;         case FH_ZLIB:            ret = z_feof(fp->fh);            break;         default:            xassert(fp != fp);      }      return ret;}/************************************************************************  NAME**  xfflush - flush the stream**  SYNOPSIS**  #include "glplib.h"*  int xfflush(XFILE *fp);**  DESCRIPTION**  The routine xfflush causes any unwritten data for the output stream*  pointed to by fp to be written to the associated file.**  RETURNS**  The routine xfflush returns zero if the stream was successfully*  flushed. Otherwise, xfflush sets the error indicator for the stream*  and returns XEOF. */static int c_fflush(void *fh);static int z_fflush(void *fh);int xfflush(XFILE *fp){     int ret;      switch (fp->type)      {  case FH_FILE:            ret = c_fflush(fp->fh);            break;         case FH_ZLIB:            ret = z_fflush(fp->fh);            break;         default:            xassert(fp != fp);      }      return ret;}/************************************************************************  NAME**  xfclose - close the stream**  SYNOPSIS**  #include "glplib.h"*  int xfclose(XFILE *fp);**  DESCRIPTION**  A successful call to the routine xfclose causes the stream pointed*  to by fp to be flushed and the associated file to be closed. Whether*  or not the call succeeds, the stream is disassociated from the file.**  RETURNS**  The routine xfclose returns zero if the stream was successfully*  closed, or XEOF if any errors were detected. */static int c_fclose(void *fh);static int z_fclose(void *fh);int xfclose(XFILE *fp){     LIBENV *env = lib_link_env();      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;}/************************************************************************  The following routines implement stream input/output based on the*  standard C streams. */static void *c_fopen(const char *fname, const char *mode){     FILE *fh;      fh = fopen(fname, mode);      if (fh == NULL)         lib_err_msg(strerror(errno));      return fh;}static int c_fgetc(void *_fh){     FILE *fh = _fh;      int c;      if (ferror(fh) || feof(fh))      {  c = XEOF;         goto done;      }      c = fgetc(fh);      if (ferror(fh))      {  lib_err_msg(strerror(errno));         c = XEOF;      }      else if (feof(fh))         c = XEOF;      else         xassert(0x00 <= c && c <= 0xFF);done: return c;}static int c_fputc(int c, void *_fh){     FILE *fh = _fh;      if (ferror(fh))      {  c = XEOF;         goto done;      }      c = (unsigned char)c;      fputc(c, fh);      if (ferror(fh))      {  lib_err_msg(strerror(errno));         c = XEOF;      }done: return c;}static int c_ferror(void *_fh){     FILE *fh = _fh;      return ferror(fh);}static int c_feof(void *_fh){     FILE *fh = _fh;      return feof(fh);}static int c_fflush(void *_fh){     FILE *fh = _fh;      int ret;      ret = fflush(fh);      if (ret != 0)      {  lib_err_msg(strerror(errno));         ret = XEOF;      }      return ret;}static int c_fclose(void *_fh){     FILE *fh = _fh;      int ret;      ret = fclose(fh);      if (ret != 0)      {  lib_err_msg(strerror(errno));         ret = XEOF;      }      return ret;}/************************************************************************  The following routines implement stream input/output based on the*  zlib library, which provides processing .gz files "on the fly". */#ifndef HAVE_ZLIBstatic void *z_fopen(const char *fname, const char *mode){     xassert(fname == fname);      xassert(mode == mode);      lib_err_msg("Compressed files not supported");      return NULL;}static int z_fgetc(void *fh){     xassert(fh != fh);      return 0;}static int z_fputc(int c, void *fh){     xassert(c != c);      xassert(fh != fh);      return 0;}static int z_ferror(void *fh){     xassert(fh != fh);      return 0;}static int z_feof(void *fh){     xassert(fh != fh);      return 0;}static int z_fflush(void *fh){     xassert(fh != fh);      return 0;}static int z_fclose(void *fh){     xassert(fh != fh);      return 0;}#else#include <zlib.h>struct z_file{     /* .gz file handle */      gzFile file;      /* pointer to .gz stream */      int err;      /* i/o error indicator */      int eof;      /* end-of-file indicator */};static void *z_fopen(const char *fname, const char *mode){     struct z_file *fh;      gzFile file;      if (strcmp(mode, "r") == 0 || strcmp(mode, "rb") == 0)         mode = "rb";      else if (strcmp(mode, "w") == 0 || strcmp(mode, "wb") == 0)         mode = "wb";      else      {  lib_err_msg("Invalid open mode");         fh = NULL;         goto done;      }      file = gzopen(fname, mode);      if (file == NULL)      {  lib_err_msg(strerror(errno));         fh = NULL;         goto done;      }      fh = xmalloc(sizeof(struct z_file));      fh->file = file;      fh->err = fh->eof = 0;done: return fh;}static int z_fgetc(void *_fh){     struct z_file *fh = _fh;      int c;      if (fh->err || fh->eof)      {  c = XEOF;         goto done;      }      c = gzgetc(fh->file);      if (c < 0)      {  int errnum;         const char *msg;         msg = gzerror(fh->file, &errnum);         if (errnum == Z_STREAM_END)            fh->eof = 1;         else if (errnum == Z_ERRNO)         {  fh->err = 1;            lib_err_msg(strerror(errno));         }         else         {  fh->err = 1;            lib_err_msg(msg);         }         c = XEOF;      }      else         xassert(0x00 <= c && c <= 0xFF);done: return c;}static int z_fputc(int c, void *_fh){     struct z_file *fh = _fh;      if (fh->err)      {  c = XEOF;         goto done;      }      c = (unsigned char)c;      if (gzputc(fh->file, c) < 0)      {  int errnum;         const char *msg;         fh->err = 1;         msg = gzerror(fh->file, &errnum);         if (errnum == Z_ERRNO)            lib_err_msg(strerror(errno));         else            lib_err_msg(msg);         c = XEOF;      }done: return c;}static int z_ferror(void *_fh){     struct z_file *fh = _fh;      return fh->err;}static int z_feof(void *_fh){     struct z_file *fh = _fh;      return fh->eof;}static int z_fflush(void *_fh){     struct z_file *fh = _fh;      int ret;      ret = gzflush(fh->file, Z_FINISH);      if (ret == Z_OK)         ret = 0;      else      {  int errnum;         const char *msg;         fh->err = 1;         msg = gzerror(fh->file, &errnum);         if (errnum == Z_ERRNO)            lib_err_msg(strerror(errno));         else            lib_err_msg(msg);         ret = XEOF;      }      return ret;}static int z_fclose(void *_fh){     struct z_file *fh = _fh;      gzclose(fh->file);      xfree(fh);      return 0;}#endif/* eof */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -