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

📄 slstdio.c

📁 一个C格式的脚本处理函数库源代码,可让你的C程序具有执行C格式的脚本文件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* file stdio intrinsics for S-Lang *//* Copyright (c) 1992, 1999, 2001, 2002, 2003 John E. Davis * This file is part of the S-Lang library. * * You may distribute under the terms of either the GNU General Public * License or the Perl Artistic License. */#include "slinclud.h"#if defined(__unix__) || (defined (__os2__) && defined (__EMX__))# include <sys/types.h>#endif#ifdef HAVE_FCNTL_H# include <fcntl.h>#endif#ifdef HAVE_SYS_FCNTL_H# include <sys/fcntl.h>#endif#ifdef __unix__# include <sys/file.h>#endif#if defined(__BORLANDC__)# include <io.h># include <dir.h>#endif#if defined(__DECC) && defined(VMS)# include <unixio.h># include <unixlib.h>#endif#ifdef VMS# include <stat.h>#else# include <sys/stat.h>#endif#include <errno.h>#include <ctype.h>/* #define SL_APP_WANTS_FOREACH */#include "slang.h"#include "_slang.h"typedef struct{   FILE *fp;			       /* kind of obvious */   char *file;			       /* file name associated with pointer */   unsigned int flags;		       /* modes, etc... */#define SL_READ		0x0001#define SL_WRITE	0x0002#define SL_BINARY	0x0004#define SL_FDOPEN	0x2000#define SL_PIPE		0x4000#define SL_INUSE	0x8000}SL_File_Table_Type;static SL_File_Table_Type *SL_File_Table;static SL_File_Table_Type *get_free_file_table_entry (void){   SL_File_Table_Type *t = SL_File_Table, *tmax;   tmax = t + SL_MAX_FILES;   while (t < tmax)     {	if (t->flags == 0)	  {	     memset ((char *) t, 0, sizeof (SL_File_Table_Type));	     return t;	  }	t++;     }   return NULL;}static unsigned int file_process_flags (char *mode){   char ch;   unsigned int flags = 0;   while (1)     {	ch = *mode++;	switch (ch)	  {	   case 'r': flags |= SL_READ;	     break;	   case 'w':	   case 'a':	   case 'A':	     flags |= SL_WRITE;	     break;	   case '+': flags |= SL_WRITE | SL_READ;	     break;	   case 'b': flags |= SL_BINARY;	     break;	   case 0:	     return flags;	   default:	     SLang_verror (SL_INVALID_PARM, "File flag %c is not supported", ch);	     return 0;	  }     }}static int open_file_type (char *file, int fd, char *mode,			   FILE *(*open_fun)(char *, char *),			   int (*close_fun)(FILE *),			   unsigned int xflags){   FILE *fp;   SL_File_Table_Type *t;   unsigned int flags;   SLang_MMT_Type *mmt;   fp = NULL;   /* t = NULL; */   mmt = NULL;   if ((NULL == (t = get_free_file_table_entry ()))       || (0 == (flags = file_process_flags(mode))))     goto return_error;      if (fd != -1)     fp = fdopen (fd, mode);   else     fp = open_fun (file, mode);   if (fp == NULL)     {	_SLerrno_errno = errno;	goto return_error;     }   if (NULL == (mmt = SLang_create_mmt (SLANG_FILE_PTR_TYPE, (VOID_STAR) t)))     goto return_error;   t->fp = fp;   t->flags = flags | xflags;   fp = NULL;			       /* allow free_mmt to close fp */   if ((NULL != (t->file = SLang_create_slstring (file)))       && (0 == SLang_push_mmt (mmt)))     return 0;   /* drop */   return_error:   if (fp != NULL) (*close_fun) (fp);   if (mmt != NULL) SLang_free_mmt (mmt);   (void) SLang_push_null ();   return -1;}/* Since some compilers do not have popen/pclose prototyped and in scope, * and pc compilers sometimes have silly prototypes involving PASCAL, etc. * use wrappers around the function to avoid compilation errors. */static FILE *fopen_fun (char *f, char *m){   return fopen (f, m);}static int fclose_fun (FILE *fp){   return fclose (fp);}static void stdio_fopen (char *file, char *mode){   (void) open_file_type (file, -1, mode, fopen_fun, fclose_fun, 0);}int _SLstdio_fdopen (char *file, int fd, char *mode){   if (fd == -1)     {	_SLerrno_errno = EBADF;	(void) SLang_push_null ();	return -1;     }   return open_file_type (file, fd, mode, NULL, fclose_fun, SL_FDOPEN);}#ifdef HAVE_POPENstatic int pclose_fun (FILE *fp){   return pclose (fp);}static FILE *popen_fun (char *file, char *mode){   return popen (file, mode);}static void stdio_popen (char *file, char *mode){   (void) open_file_type (file, -1, mode, popen_fun, pclose_fun, SL_PIPE);}#endif/* returns pointer to file entry if it is open and consistent with   flags.  Returns NULL otherwise */static SLang_MMT_Type *pop_fp (unsigned int flags, FILE **fp_ptr){   SL_File_Table_Type *t;   SLang_MMT_Type *mmt;   *fp_ptr = NULL;   if (NULL == (mmt = SLang_pop_mmt (SLANG_FILE_PTR_TYPE)))     return NULL;   t = (SL_File_Table_Type *) SLang_object_from_mmt (mmt);   if ((t->flags & flags)       && (NULL != (*fp_ptr = t->fp)))     return mmt;   SLang_free_mmt (mmt);   return NULL;}static FILE *check_fp (SL_File_Table_Type *t, unsigned flags){   if ((t != NULL) && (t->flags & flags))     return t->fp;   return NULL;}char *SLang_get_name_from_fileptr (SLang_MMT_Type *mmt){   SL_File_Table_Type *ft;   ft = (SL_File_Table_Type *) SLang_object_from_mmt (mmt);   if (ft == NULL)     return NULL;   return ft->file;}int SLang_pop_fileptr (SLang_MMT_Type **mmt, FILE **fp){   if (NULL == (*mmt = pop_fp (0xFFFF, fp)))     {#ifdef EBADF	_SLerrno_errno = EBADF;#endif	return -1;     }   return 0;}static int close_file_type (SL_File_Table_Type *t){   int ret = 0;   FILE *fp;   if (t == NULL)     return -1;   fp = t->fp;   if (NULL == fp) ret = -1;   else     {	if (0 == (t->flags & SL_PIPE))	  {	     if (EOF == (ret = fclose (fp)))	       _SLerrno_errno = errno;	  }#ifdef HAVE_POPEN	else	  {	     if (-1 == (ret = pclose (fp)))	       _SLerrno_errno = errno;	  }#endif     }   if (t->file != NULL) SLang_free_slstring (t->file);   memset ((char *) t, 0, sizeof (SL_File_Table_Type));   return ret;}static int stdio_fclose (SL_File_Table_Type *t){   int ret;   if (NULL == check_fp (t, 0xFFFF))     return -1;   ret = close_file_type (t);   t->flags = SL_INUSE;   return ret;}static int read_one_line (FILE *fp, char **strp, unsigned int *lenp, int trim_trailing){   char buf[512];   char *str;   unsigned int len;   *strp = NULL;   len = 0;   str = NULL;   while (NULL != fgets (buf, sizeof (buf), fp))     {	unsigned int dlen;	char *new_str;	int done_flag;	dlen = strlen (buf);	/* Note: If the file contains embedded \0 characters, then this	 * fails to work properly since dlen will not be correct.	 */	done_flag = ((dlen + 1 < sizeof (buf))		     || (buf[dlen - 1] == '\n'));	if (done_flag && (str == NULL))	  {	     /* Avoid the malloc */	     str = buf;	     len = dlen;	     break;	  }	if (NULL == (new_str = SLrealloc (str, len + dlen + 1)))	  {	     SLfree (str);	     return -1;	  }	str = new_str;	strcpy (str + len, buf);	len += dlen;	if (done_flag) break;     }   if (str == NULL)     return 0;   if (trim_trailing)     {	unsigned int len1 = len;	while (len1)	  {	     len1--;	     if (0 == isspace(str[len1]))	       {		  len1++;		  break;	       }	  }	len = len1;     }	          *strp = SLang_create_nslstring (str, len);   if (str != buf) SLfree (str);   if (*strp == NULL) return -1;   *lenp = len;   return 1;}/* returns number of characters read and pushes the string to the stack.   If it fails, it returns -1 */static int stdio_fgets (SLang_Ref_Type *ref, SL_File_Table_Type *t){   char *s;   unsigned int len;   FILE *fp;   int status;   if (NULL == (fp = check_fp (t, SL_READ)))     return -1;   status = read_one_line (fp, &s, &len, 0);   if (status <= 0)     return -1;   status = SLang_assign_to_ref (ref, SLANG_STRING_TYPE, (VOID_STAR)&s);   SLang_free_slstring (s);   if (status == -1)     return -1;   return (int) len;}static void stdio_fgetslines_internal (FILE *fp, unsigned int n){   unsigned int num_lines, max_num_lines;   char **list;   SLang_Array_Type *at;   int inum_lines;   if (n > 1024)     max_num_lines = 1024;   else      {	max_num_lines = n;	if (max_num_lines == 0)	  max_num_lines++;     }   list = (char **) SLmalloc (sizeof (char *) * max_num_lines);   if (list == NULL)     return;   num_lines = 0;   while (num_lines < n)     {	int status;	char *line;	unsigned int len;	status = read_one_line (fp, &line, &len, 0);	if (status == -1)	  goto return_error;	if (status == 0)	  break;	if (max_num_lines == num_lines)	  {	     char **new_list;	     if (max_num_lines + 4096 > n)	       max_num_lines = n;	     else	       max_num_lines += 4096;	     new_list = (char **) SLrealloc ((char *)list, sizeof (char *) * max_num_lines);	     if (new_list == NULL)	       {		  SLang_free_slstring (line);		  goto return_error;	       }	     list = new_list;	  }	list[num_lines] = line;	num_lines++;     }   if (num_lines != max_num_lines)     {	char **new_list;	new_list = (char **)SLrealloc ((char *)list, sizeof (char *) * (num_lines + 1));	if (new_list == NULL)	  goto return_error;	list = new_list;     }   inum_lines = (int) num_lines;   if (NULL == (at = SLang_create_array (SLANG_STRING_TYPE, 0, (VOID_STAR) list, &inum_lines, 1)))     goto return_error;   if (-1 == SLang_push_array (at, 1))     SLang_push_null ();   return;   return_error:   while (num_lines > 0)     {	num_lines--;	SLfree (list[num_lines]);     }   SLfree ((char *)list);   SLang_push_null ();}static void stdio_fgetslines (void){   unsigned int n;   FILE *fp;   SLang_MMT_Type *mmt;   n = (unsigned int)-1;   if (SLang_Num_Function_Args == 2)     {	if (-1 == SLang_pop_uinteger (&n))	  return;     }      if (NULL == (mmt = pop_fp (SL_READ, &fp)))     {	SLang_push_null ();	return;     }   stdio_fgetslines_internal (fp, n);   SLang_free_mmt (mmt);}static int stdio_fputs (char *s, SL_File_Table_Type *t){   FILE *fp;   if (NULL == (fp = check_fp (t, SL_WRITE)))     return -1;   if (EOF == fputs(s, fp)) return -1;   return (int) strlen (s);}static int stdio_fflush (SL_File_Table_Type *t){   FILE *fp;   if (NULL == (fp = check_fp (t, SL_WRITE)))     return -1;   if (EOF == fflush (fp))     {	_SLerrno_errno = errno;

⌨️ 快捷键说明

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