=================================================================== RCS file: /home/cvs/OpenXM/src/hgm/mh/src/sfile.c,v retrieving revision 1.1 retrieving revision 1.20 diff -u -p -r1.1 -r1.20 --- OpenXM/src/hgm/mh/src/sfile.c 2013/02/19 08:03:14 1.1 +++ OpenXM/src/hgm/mh/src/sfile.c 2015/04/02 05:45:41 1.20 @@ -1,41 +1,98 @@ /* - $OpenXM$ - */ + $OpenXM: OpenXM/src/hgm/mh/src/sfile.c,v 1.19 2015/04/02 00:11:32 takayama Exp $ +*/ #include +#include +#include +#include #include "sfile.h" #define SSIZE 5 -void *mh_malloc(int size) { return((void *)malloc(size)); } +int MH_DEBUG = 0; +static int isIntString(char s[]); + +void mh_check_intr(int interval) { + static int intr=0; + if (intr >= interval) { + intr = 0; +#ifndef STANDALONE + R_CheckUserInterrupt(); +#endif + }else intr++; +} + +void *mh_malloc(int s) { + void *p; + static int total=0; + total += s; + if (MH_DEBUG) oxprintf("mh_malloc total allocated memory: %f M\n",(float)total/(float)(1024*1024)); +#ifdef STANDALONE + p = (void*)malloc(s); +#else + p = (void *)R_alloc(1,s); +#endif + if (p == NULL) { + oxprintfe("No memory.\n"); mh_exit(-1); + } + return(p); +} +int mh_free(void *p) { + if (MH_DEBUG) oxprintf("mh_free at %p\n",p); +#ifdef STANDALONE + free(p); /* free in mh_free */ +#endif + return(0); +} + +int mh_exit(int n) { +#ifdef STANDALONE + static int standalone=0; + if (n == MH_RESET_EXIT) { standalone=1; return(0);} + if (standalone) exit(n); + else { + oxprintfe("Fatal error mh_exit(%d) in mh-w-n.\n",n); + return(n); + } +#else + error("mh_exit(%d) is called.\n",n); +#endif +} + struct SFILE *mh_fopen(char *name,char *mode,int byFile) { struct SFILE *sfp; - sfp = mh_malloc(sizeof(struct SFILE)); + sfp = (struct SFILE *)mh_malloc(sizeof(struct SFILE)); sfp->byFile=0; sfp->s=NULL; sfp->pt=0; sfp->len=0;sfp->limit=0; sfp->fp=NULL; - sfp->forRead=1; + sfp->forRead=1; sfp->copied=0; if (byFile) { - sfp->byFile = 1; - sfp->fp = fopen(name,mode); - if (sfp->fp == NULL) return(NULL); - else return(sfp); + sfp->byFile = 1; + if (strcmp(name,"stdout")==0) { + sfp->fp = oxstdout; + }else{ + sfp->fp = fopen(name,mode); + } + if (sfp->fp == NULL) return(NULL); + else return(sfp); }else if (strcmp(mode,"r")==0) { - sfp->byFile=0; - sfp->s=name; - sfp->pt=0; - sfp->len=strlen(name); - sfp->limit=sfp->len+1; - sfp->forRead=1; - return(sfp); + sfp->byFile=0; + sfp->s=name; + sfp->pt=0; + sfp->len=strlen(name); + sfp->limit=sfp->len+1; + sfp->forRead=1; + return(sfp); }else if (strcmp(mode,"w")==0) { - sfp->byFile=0; - sfp->s=mh_malloc(SSIZE); - sfp->pt=0; - sfp->len=0; - sfp->limit= SSIZE; - sfp->forRead=0; - return(sfp); + sfp->byFile=0; + sfp->s=(char *)mh_malloc(SSIZE); + sfp->s[0]=0; + sfp->pt=0; + sfp->len=0; + sfp->limit= SSIZE; + sfp->forRead=0; + return(sfp); }else{ - fprintf(stderr,"Error: unknown mode %s in the string mode.\n",mode); - return NULL; + oxprintfe("Error: unknown mode %s in the string mode.\n",mode); + return NULL; } } @@ -48,80 +105,207 @@ char *mh_fgets(char *str,int size,struct SFILE *sfp) { if (pt >= len) return NULL; if (size != 0) str[0]=0; for (i=0; ipt = pt; - if (s[pt] == 0) return str; - if (pt >= len) return str; - if (str[i] == '\n') return str; - } + if (s[pt] != 0) { + str[i] = s[pt]; str[i+1] = 0; + pt++; sfp->pt = pt; + if (s[pt] == 0) return str; + if (pt >= len) return str; + if (str[i] == '\n') return str; + } } return str; } int mh_fputs(char *str,struct SFILE *sfp) { - int i,pt,len,limit; + int len,limit; int inputLen; char *s; if (sfp->byFile) return fputs(str,sfp->fp); - s = sfp->s; len = sfp->len; pt = sfp->pt; limit=sfp->limit; + s = sfp->s; len = sfp->len; limit=sfp->limit; inputLen=strlen(str); if (inputLen+len+1 > limit) { - limit *= 2; - s = (char *) mh_malloc(limit); - if (s == NULL) return(EOF); - strcpy(s,sfp->s); - free(sfp->s); + limit = (inputLen+len+1)*2; + s = (char *) mh_malloc(limit); + if (s == NULL) return(EOF); + strcpy(s,sfp->s); + mh_free(sfp->s); } strcpy(&(s[len]),str); len += inputLen; + /* oxprintf("mh_fputs(%d):[%s]\n",len,s); */ sfp->s=s; sfp->len=len; sfp->limit=limit; return(0); } /* Note: copy the resulting string sfp->s before mh_fclose */ int mh_fclose(struct SFILE *sfp) { + if (!sfp) return(-1); if (sfp->byFile) return fclose(sfp->fp); if (! (sfp->forRead)) { - if (sfp->s != NULL) free(sfp->s); + if (!sfp->copied) oxprintfe("Warning in mh_fclose. sfp->s has not been copied, but deallocated.\n"); + if (sfp->s != NULL) { mh_free(sfp->s); sfp->s = NULL; } } - free(sfp); + mh_free(sfp); + return(0); } +int mh_outstr(char *str,int size,struct SFILE *sfp) { + int i; + if (sfp->byFile) { + oxprintfe("Error in mh_outstr. mh_outstr is called in the file i/o mode.\n"); + return 0; + } + if (size) str[0] = 0; + for (i = 0; (ilen); i++) { + str[i] = (sfp->s)[i]; str[i+1] = 0; + } + sfp->copied=1; + return(i); +} + +void mh_error(char *s,int code) { + oxprintfe("Error: %s\n",s); + mh_exit(code); +} + +struct mh_token mh_getoken(char s[],int smax,struct SFILE *sfp) { + static int w0=0; + static int wn=0; + static char work[MH_SSIZE]; + char *r; + int t,t2; + struct mh_token token; + token.type = MH_TOKEN_EOF; + token.ival=0; token.dval=0.0; + while (1) { + if (w0 >= wn) { + r = mh_fgets(work,MH_SSIZE-1,sfp); + if (r == NULL) { + token.type = MH_TOKEN_EOF; + return token; + } + /* oxprintf("work=%s\n",work); */ + w0 = 0; wn=strlen(work); + } + t=w0; + while ((work[t] <= ' ') && (t < wn)) t++; + if (t == wn) { + w0=wn; + continue; + } + if (work[t] == ',') {w0=t+1; continue; } + t2 = t; + while((work[t2] > ' ') && (work[t2] != '=') + && (work[t2] != ',')) t2++; + /* work[t] ... work[t2-1] is a token */ + /* %abc=123#comment is not allowed. but %abc=123,# or %abc=123 # is OK. */ + if ((t == t2) && (work[t] == '=')) { + token.type=MH_TOKEN_EQ; + w0=t2+1; + return token; + } + if ((work[t] == '%') && (work[t+1] == '%')) { + /* comment */ + w0 =wn; + continue; + } + if (work[t] == '#') { + /* comment */ + w0=wn; + continue; + } + if (work[t] == '%') { + if (t2-t-2 >= smax) { + oxprintfe("s is too small in mh_getoken.\n"); + mh_exit(-1); + } + strncpy(s,&(work[t+1]),t2-(t+1)); s[t2-(t+1)] = 0; + token.type=MH_TOKEN_ID; + w0 = t2; + return token; + } + /* The case of double or int */ + strncpy(s,&(work[t]),t2-t); s[t2-t]=0; + if (isIntString(s)) { + token.type=MH_TOKEN_INT; + sscanf(s,"%d",&(token.ival)); + sscanf(s,"%lg",&(token.dval)); + }else{ + token.type=MH_TOKEN_DOUBLE; + sscanf(s,"%lg",&(token.dval)); + } + w0 = t2; + return token; + } +} + +static int isIntString(char s[]) { + int i; + for (i=0; ibyFile); - if (sfp->s) printf("sfp->s=%s\n",sfp->s); - printf("pt=%d\n",sfp->pt); - printf("len=%d\n",sfp->len); - printf("limit=%d\n",sfp->limit); - printf("fp=%p\n",sfp->fp); + oxprintf("byFile=%d\n",sfp->byFile); + if (sfp->s) oxprintf("sfp->s=%s\n",sfp->s); + oxprintf("pt=%d\n",sfp->pt); + oxprintf("len=%d\n",sfp->len); + oxprintf("limit=%d\n",sfp->limit); + oxprintf("fp=%p\n",sfp->fp); } + +#define TESTSIZE 1024 main() { struct SFILE *sfp; - char str[1024]; + char str[TESTSIZE]; int i; -/* - sfp = mh_fopen("hoge\nafo\nbho\ncat\ndot\ndolphin\n","r",0); - while (mh_fgets(str,1024,sfp)) { - printf(str); + struct mh_token tk; + sfp = mh_fopen("%%abc\n%abs=1.234\n %abs = \n 1.235\n%abs=\n1.236\n\n%abs=1.237\n%ival=-234,#comment\n","r",0); + while ((tk=mh_getoken(str,TESTSIZE,sfp)).type != MH_TOKEN_EOF) { + mh_print_token(tk,str); } - mh_fclose(sfp); + return 0; + /* + sfp = mh_fopen("hoge\nafo\nbho\ncat\ndot\ndolphin\n","r",0); + while (mh_fgets(str,1024,sfp)) { + oxprintf(str); + } + mh_fclose(sfp); - sfp = mh_fopen("sfile.h","r",1); - while (mh_fgets(str,1024,sfp)) { - printf(str); - } - mh_fclose(sfp); -*/ + sfp = mh_fopen("sfile.h","r",1); + while (mh_fgets(str,1024,sfp)) { + oxprintf(str); + } + mh_fclose(sfp); + */ sfp = mh_fopen("","w",0); for (i=0; i<3; i++) { - mh_fputs("hoge\n",sfp); - mh_fputs("hage\n",sfp); - dump(sfp); + mh_fputs("hoge\n",sfp); + mh_fputs("hage\n",sfp); + dump(sfp); } mh_fputs("end end\n",sfp); - printf("result=%s\n",sfp->s); - /* strcpy(str,sfp->s); - mh_fclose(sfp); */ + oxprintf("result=%s\n",sfp->s); + mh_outstr(str,TESTSIZE,sfp); + mh_fclose(sfp); } +#endif