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
00348 c = fgetc(stream);
00349
00350 if (c != 'n')
00351 {
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
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