home *** CD-ROM | disk | FTP | other *** search
/ Stone Design / Stone Design.iso / Stone_Friends / NeXT-Icons / next-icon@gun.com / Apps / ImagePortfolio / threads.subproj / threadStdio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-03  |  3.9 KB  |  174 lines

  1. // -------------------------------------------------------------------------------------
  2. // Thread safe printf(), sprintf(), fprintf(), scanf(), fscanf(), sscanf(), etc.
  3. // -------------------------------------------------------------------------------------
  4. // Permission is granted to freely redistribute this source code, and to use fragments
  5. // of this code in your own applications if you find them to be useful.  This module,
  6. // along with the source code, come with no warranty of any kind, and the user assumes
  7. // all responsibility for its use.
  8. // -------------------------------------------------------------------------------------
  9. #import <mach/cthreads.h>
  10. #import <libc.h>
  11. #import <math.h>
  12. #import <stdlib.h>
  13. #import <stdio.h>
  14. #import    <stdarg.h>
  15. #import <string.h>
  16. #import <streams/streams.h>
  17.  
  18. // -------------------------------------------------------------------------------------
  19. static char            didInit = 0;
  20. static mutex_t        protecto = (mutex_t)0;
  21.  
  22. // -------------------------------------------------------------------------------------
  23. #define    INIT        if (!didInit) thread_initStdio()
  24. #define    LOCK        mutex_lock(protecto)
  25. #define UNLOCK        mutex_unlock(protecto)
  26. #define    _DO_SCAN    1
  27.  
  28. // -------------------------------------------------------------------------------------
  29. // thread protected io initialization routine
  30. void thread_initStdio()
  31. {
  32.     if (didInit) return;
  33.     protecto = mutex_alloc();
  34.     didInit = 1;
  35. }
  36.  
  37. // -------------------------------------------------------------------------------------
  38. // <x>printf
  39.  
  40. /* vprintf() */
  41. int thread_vprintf(const char *fmt, va_list arg)
  42. {
  43.     int        rtn;
  44.     INIT;    // initialize
  45.     LOCK;
  46.     rtn = vprintf(fmt, arg);
  47.     UNLOCK;
  48.     return rtn;
  49. }
  50.  
  51. /* printf() */
  52. int thread_printf(const char *fmt, ...)
  53. {
  54.     int        rtn;
  55.     va_list    arg;
  56.     va_start(arg, fmt);
  57.     rtn = thread_vprintf(fmt, arg);
  58.     va_end(arg);
  59.     return rtn;
  60. }
  61.  
  62. /* fprintf() */
  63. int thread_vfprintf(register FILE *fhnd, const char *fmt, va_list arg)
  64. {
  65.     int        rtn;
  66.     INIT;    // initialize
  67.     LOCK;
  68.     rtn = vfprintf(fhnd, fmt, arg);
  69.     UNLOCK;
  70.     return rtn;
  71. }
  72.  
  73. /* fprintf() */
  74. int thread_fprintf(register FILE *fhnd, const char *fmt, ...)
  75. {
  76.     int        rtn;
  77.     va_list    arg;
  78.     va_start(arg, fmt);
  79.     rtn = thread_vfprintf(fhnd, fmt, arg);
  80.     va_end(arg);
  81.     return rtn;
  82. }
  83.  
  84. /* vsprintf() */
  85. int thread_vsprintf(char *str, const char *fmt, va_list arg)
  86. {
  87.     int        rtn;
  88.     INIT;    // initialize
  89.     LOCK;
  90.     rtn = vsprintf(str, fmt, arg);
  91.     UNLOCK;
  92.     return rtn;
  93. }
  94.  
  95. /* sprintf() */
  96. int thread_sprintf(char *str, const char *fmt, ...)
  97. {
  98.     int        rtn;
  99.     va_list    arg;
  100.     va_start(arg, fmt);
  101.     rtn = thread_vsprintf(str, fmt, arg);
  102.     va_end(arg);
  103.     return rtn;
  104. }
  105.  
  106. // -------------------------------------------------------------------------------------
  107. // <x>scanf
  108.  
  109. /* vfscanf() */
  110. int thread_vfscanf(FILE *fhnd, const char *fmt, va_list arg)
  111. {
  112.     int            rtn;
  113. #ifdef _DO_SCAN
  114.     extern int    _doscan(FILE*, const char*, va_list);
  115. #endif
  116.     INIT;        // initialize
  117.     LOCK;
  118. #ifdef _DO_SCAN
  119. //#warning Implementing 'thread_vfscanf()' with '_doscan()'
  120.     rtn = _doscan(fhnd, fmt, arg);
  121. #else
  122. //#warning Implementing 'thread_vfscanf()' with 'NXVScanf()'
  123.     if (fhnd->_flag & _IOSTRG) {
  124.         NXStream *s = NXOpenMemory(fhnd->_ptr, fhnd->_cnt, NX_READONLY);
  125.         rtn = NXVScanf(s, fmt, arg);
  126.         NXCloseMemory(s, NX_FREEBUFFER);
  127.     } else {
  128.         NXStream *s = NXOpenFile(fileno(fhnd), NX_READONLY);
  129.         rtn = NXVScanf(s, fmt, arg);
  130.         NXClose(s);
  131.     }
  132. #endif
  133.     UNLOCK;
  134.     return rtn;
  135. }
  136.  
  137. /* fscanf() */
  138. int thread_fscanf(FILE *fhnd, const char *fmt, ...)
  139. {
  140.     va_list    arg;
  141.     int        rtn;
  142.     va_start(arg, fmt);
  143.     rtn = thread_vfscanf(fhnd, fmt, arg);
  144.     va_end(arg);
  145.     return rtn;
  146. }
  147.  
  148.  
  149. /* scanf() */
  150. int thread_scanf(const char *fmt, ...)
  151. {
  152.     va_list arg;
  153.     int        rtn;
  154.     va_start(arg, fmt);
  155.     rtn = thread_vfscanf(stdin, fmt, arg);
  156.     va_end(arg);
  157.     return rtn;
  158. }
  159.  
  160. /* sscanf() */
  161. int thread_sscanf(register const char *str, const char *fmt, ...)
  162. {
  163.     va_list        arg;
  164.     int            rtn;
  165.     FILE        f;
  166.     va_start(arg, fmt);
  167.     f._base = f._ptr = (char*)str;
  168.     f._bufsiz = f._cnt = strlen(str);
  169.     f._flag = _IOREAD | _IOSTRG;
  170.     rtn = thread_vfscanf(&f, fmt, arg);
  171.     va_end(arg);
  172.     return rtn;
  173. }
  174.