NewtIO.c

説明を見る。
00001 /*------------------------------------------------------------------------*/
00013 /* ヘッダファイル */
00014 #include <string.h>
00015 #include <stdio.h>
00016 #include <errno.h>
00017 
00018 #include "NewtCore.h"
00019 #include "NewtIO.h"
00020 
00021 #if defined(HAVE_TERMIOS_H)
00022     #include <termios.h>
00023     #include <unistd.h>
00024     #include <sys/select.h>
00025 #elif defined(__WIN32__)
00026     #include <conio.h>
00027 #endif
00028 
00029 
00030 /* マクロ */
00031 #if defined(HAVE_TERMIOS_H)
00032     #define newt_getch()    tcgetch(0)
00033 #elif defined(__WIN32__)
00034     #define newt_getch()    getch()
00035 #else
00036     #define newt_getch()    (0)
00037 #endif
00038 
00039 
00040 /* 関数プロトタイプ */
00041 static int  cbreak_and_noecho(int fd, int vmin, struct termios *tiosp);
00042 static int  tcgetch(int fd);
00043 
00044 
00045 /*------------------------------------------------------------------------*/
00054 void NIOSetFile(newtStream_t * stream, FILE * f)
00055 {
00056     stream->file = f;
00057 
00058     if (f == stdout)
00059         stream->obj = NcGetGlobalVar(NSSYM0(_STDOUT_));
00060     else if (f == stderr)
00061         stream->obj = NcGetGlobalVar(NSSYM0(_STDERR_));
00062     else
00063         stream->obj = kNewtRefUnbind;
00064 }
00065 
00066 
00067 /*------------------------------------------------------------------------*/
00079 int NIOFprintf(newtStream_t * stream, const char * format, ...)
00080 {
00081     va_list args;
00082     int     result;
00083 
00084     va_start(args, format);
00085     result = NIOVfprintf(stream, format, args);
00086     va_end(args);
00087 
00088     return result;
00089 }
00090 
00091 
00092 /*------------------------------------------------------------------------*/
00105 int NIOVfprintf(newtStream_t * stream, const char * format, va_list ap)
00106 {
00107     int     result = 0;
00108 
00109     if (NewtRefIsString(stream->obj))
00110     {
00111         char    wk[NEWT_SNPRINTF_BUFFSIZE];
00112 
00113         result = vsnprintf(wk, sizeof(wk), format, ap);
00114 
00115         if (0 < result)
00116         {
00117             if (sizeof(wk) < result)
00118                 wk[sizeof(wk) - 1] = '0';
00119 
00120             NewtStrCat(stream->obj, wk);
00121         }
00122     }
00123     else
00124     {
00125         result = vfprintf(stream->file, format, ap);
00126     }
00127 
00128     return result;
00129 }
00130 
00131 
00132 /*------------------------------------------------------------------------*/
00143 int NIOFputc(int c, newtStream_t * stream)
00144 {
00145     int     result = 0;
00146 
00147     if (NewtRefIsString(stream->obj))
00148     {
00149         char    wk[4];
00150 
00151         sprintf(wk, "%c", c);
00152         NewtStrCat(stream->obj, wk);
00153     }
00154     else
00155     {
00156         result = fputc(c, stream->file);
00157     }
00158 
00159     return result;
00160 }
00161 
00162 
00163 /*------------------------------------------------------------------------*/
00174 int NIOFputs(const char *str, newtStream_t * stream)
00175 {
00176     int     result = 0;
00177 
00178     if (NewtRefIsString(stream->obj))
00179     {
00180         NewtStrCat(stream->obj, (char *)str);
00181     }
00182     else
00183     {
00184         result = fputs(str, stream->file);
00185     }
00186 
00187     return result;
00188 }
00189 
00190 
00191 #pragma mark -
00192 /*------------------------------------------------------------------------*/
00202 int NewtFprintf(FILE * f, const char * format, ...)
00203 {
00204     newtStream_t    stream;
00205     va_list args;
00206     int     result;
00207 
00208     NIOSetFile(&stream, f);
00209 
00210     va_start(args, format);
00211     result = NIOVfprintf(&stream, format, args);
00212     va_end(args);
00213 
00214     return result;
00215 }
00216 
00217 
00218 /*------------------------------------------------------------------------*/
00227 int NewtFputc(int c, FILE * f)
00228 {
00229     newtStream_t    stream;
00230 
00231     NIOSetFile(&stream, f);
00232     return NIOFputc(c, &stream);
00233 }
00234 
00235 
00236 /*------------------------------------------------------------------------*/
00245 int NewtFputs(const char *str, FILE * f)
00246 {
00247     newtStream_t    stream;
00248 
00249     NIOSetFile(&stream, f);
00250     return NIOFputs(str, &stream);
00251 }
00252 
00253 
00254 #pragma mark -
00255 /*------------------------------------------------------------------------*/
00265 int NewtDebugMsg(const char * title, const char * format, ...)
00266 {
00267     newtStream_t    stream;
00268     va_list args;
00269     int     result;
00270 
00271     NIOSetFile(&stream, stderr);
00272 
00273     if (title != NULL)
00274     {
00275         NIOFputs("[", &stream);
00276         NIOFputs(title, &stream);
00277         NIOFputs("] ", &stream);
00278     }
00279 
00280     va_start(args, format);
00281     result = NIOVfprintf(&stream, format, args);
00282     va_end(args);
00283 
00284     return result;
00285 }
00286 
00287 
00288 #pragma mark -
00289 /*------------------------------------------------------------------------*/
00300 newtRef NewtFgets(FILE * stream)
00301 {
00302     newtRefVar  result = kNewtRefNIL;
00303     char    buff[NEWT_FGETS_BUFFSIZE];
00304     char *  str;
00305     char    c;
00306     int     maxsize;
00307     int     oldlen;
00308     int     len;
00309 
00310     maxsize = sizeof(buff) - 1;
00311 
00312     while (str = fgets(buff, sizeof(buff), stream))
00313     {
00314         len = strlen(str);
00315 
00316         if (result == kNewtRefNIL)
00317         {   // 文字列オブジェクト作成
00318             result = NewtMakeString2(str, len, false);
00319 
00320             if (NewtRefIsNIL(result))
00321             {   // メモリを確保できなかった
00322                 return NewtThrow0(kNErrOutOfObjectMemory);
00323             }
00324         }
00325         else
00326         {   // 追加
00327             oldlen = NewtStringLength(result);
00328             result = NewtStrCat2(result, str, len);
00329 
00330             if (NewtStringLength(result) < oldlen + len)
00331             {   // メモリを確保できなかった
00332                 return NewtThrow0(kNErrOutOfObjectMemory);
00333             }
00334         }
00335 
00336         if (len < maxsize)
00337             break;
00338 
00339         // 最後の文字をチェック
00340         c = buff[maxsize - 1];
00341 
00342         if (c == 'n')
00343             break;
00344 
00345         if (c == 'r')
00346         {
00347             // 1文字先読み
00348             c = fgetc(stream);
00349 
00350             if (c != 'n')
00351             {   // CRLF でない(CR のみ)場合
00352                 // 先読みした文字をストリームに戻す
00353                 ungetc(c, stream);
00354                 break;
00355             }
00356         }
00357     }
00358 
00359     return result;
00360 }
00361 
00362 
00363 /*------------------------------------------------------------------------*/
00372 newtRef NsGets(newtRefArg rcvr)
00373 {
00374     return NewtFgets(stdin);
00375 }
00376 
00377 
00378 /*------------------------------------------------------------------------*/
00387 newtRef NewtFgetc(FILE * stream)
00388 {
00389     int     c;
00390 
00391     c = fgetc(stream);
00392 
00393     if (c == EOF)
00394         return kNewtRefNIL;
00395     else
00396         return NewtMakeCharacter(c);
00397 }
00398 
00399 
00400 /*------------------------------------------------------------------------*/
00409 newtRef NsGetc(newtRefArg rcvr)
00410 {
00411     return NewtFgetc(stdin);
00412 }
00413 
00414 
00415 #ifdef HAVE_TERMIOS_H
00416 
00417 /*------------------------------------------------------------------------*/
00428 int cbreak_and_noecho(int fd, int vmin, struct termios *tiosp)
00429 {
00430     struct termios  tios;
00431     int     err;
00432 
00433     err = tcgetattr(fd, &tios);
00434     if (err) return err;
00435 
00436     if (tiosp) *tiosp = tios;
00437 
00438     tios.c_lflag &=  (ICANON | ECHO);
00439     tios.c_cc[VTIME] = 0;
00440     tios.c_cc[VMIN] = vmin;
00441     err = tcsetattr(fd, TCSANOW, &tios);
00442 
00443     return err;
00444 }
00445 
00446 
00447 /*------------------------------------------------------------------------*/
00456 int tcgetch(int fd)
00457 {
00458     struct termios  tios;
00459     char    buf[1];
00460     int     c = 0;
00461     int     err;
00462 
00463     err = cbreak_and_noecho(fd, 1, &tios);
00464     if (err) return -1;
00465 
00466     if (0 < read(fd, buf, sizeof(buf)))
00467         c = buf[0];
00468 
00469     tcsetattr(fd, TCSANOW, &tios);
00470 
00471     return c;
00472 }
00473 
00474 
00475 #endif /* HAVE_TERMIOS_H */
00476 
00477 
00478 /*------------------------------------------------------------------------*/
00487 newtRef NsGetch(newtRefArg rcvr)
00488 {
00489     int     c;
00490 
00491     c = newt_getch();
00492 
00493     if (c)
00494         return NewtMakeCharacter(c);
00495     else
00496         return kNewtRefNIL;
00497 }
00498 

NEWT/0に対してThu Nov 23 16:50:43 2006に生成されました。  doxygen 1.5.0