ftp.nice.ch/pub/next/graphics/viewer/ImagePortfolio.1.45.s.tar.gz#/ImagePortfolio_v1.45_src/threads.subproj/threadStdio.c

This is threadStdio.c in view mode; [Download] [Up]

// -------------------------------------------------------------------------------------
// Thread safe printf(), sprintf(), fprintf(), scanf(), fscanf(), sscanf(), etc.
// -------------------------------------------------------------------------------------
// Permission is granted to freely redistribute this source code, and to use fragments
// of this code in your own applications if you find them to be useful.  This module,
// along with the source code, come with no warranty of any kind, and the user assumes
// all responsibility for its use.
// -------------------------------------------------------------------------------------
#import <mach/cthreads.h>
#import <libc.h>
#import <math.h>
#import <stdlib.h>
#import <stdio.h>
#import	<stdarg.h>
#import <string.h>
#import <streams/streams.h>

// -------------------------------------------------------------------------------------
static char			didInit = 0;
static mutex_t		protecto = (mutex_t)0;

// -------------------------------------------------------------------------------------
#define	INIT		if (!didInit) thread_initStdio()
#define	LOCK		mutex_lock(protecto)
#define UNLOCK		mutex_unlock(protecto)
#define	_DO_SCAN	1

// -------------------------------------------------------------------------------------
// thread protected io initialization routine
void thread_initStdio()
{
	if (didInit) return;
	protecto = mutex_alloc();
	didInit = 1;
}

// -------------------------------------------------------------------------------------
// <x>printf

/* vprintf() */
int thread_vprintf(const char *fmt, va_list arg)
{
	int		rtn;
	INIT;	// initialize
	LOCK;
	rtn = vprintf(fmt, arg);
	UNLOCK;
	return rtn;
}

/* printf() */
int thread_printf(const char *fmt, ...)
{
	int		rtn;
	va_list	arg;
	va_start(arg, fmt);
	rtn = thread_vprintf(fmt, arg);
	va_end(arg);
	return rtn;
}

/* fprintf() */
int thread_vfprintf(register FILE *fhnd, const char *fmt, va_list arg)
{
	int		rtn;
	INIT;	// initialize
	LOCK;
	rtn = vfprintf(fhnd, fmt, arg);
	UNLOCK;
	return rtn;
}

/* fprintf() */
int thread_fprintf(register FILE *fhnd, const char *fmt, ...)
{
	int		rtn;
	va_list	arg;
	va_start(arg, fmt);
	rtn = thread_vfprintf(fhnd, fmt, arg);
	va_end(arg);
	return rtn;
}

/* vsprintf() */
int thread_vsprintf(char *str, const char *fmt, va_list arg)
{
	int		rtn;
	INIT;	// initialize
	LOCK;
	rtn = vsprintf(str, fmt, arg);
	UNLOCK;
	return rtn;
}

/* sprintf() */
int thread_sprintf(char *str, const char *fmt, ...)
{
	int		rtn;
	va_list	arg;
	va_start(arg, fmt);
	rtn = thread_vsprintf(str, fmt, arg);
	va_end(arg);
	return rtn;
}

// -------------------------------------------------------------------------------------
// <x>scanf

/* vfscanf() */
int thread_vfscanf(FILE *fhnd, const char *fmt, va_list arg)
{
	int			rtn;
#ifdef _DO_SCAN
	extern int	_doscan(FILE*, const char*, va_list);
#endif
	INIT;		// initialize
	LOCK;
#ifdef _DO_SCAN
//#warning Implementing 'thread_vfscanf()' with '_doscan()'
	rtn = _doscan(fhnd, fmt, arg);
#else
//#warning Implementing 'thread_vfscanf()' with 'NXVScanf()'
	if (fhnd->_flag & _IOSTRG) {
		NXStream *s = NXOpenMemory(fhnd->_ptr, fhnd->_cnt, NX_READONLY);
		rtn = NXVScanf(s, fmt, arg);
		NXCloseMemory(s, NX_FREEBUFFER);
	} else {
		NXStream *s = NXOpenFile(fileno(fhnd), NX_READONLY);
		rtn = NXVScanf(s, fmt, arg);
		NXClose(s);
	}
#endif
	UNLOCK;
	return rtn;
}

/* fscanf() */
int thread_fscanf(FILE *fhnd, const char *fmt, ...)
{
	va_list	arg;
	int		rtn;
	va_start(arg, fmt);
	rtn = thread_vfscanf(fhnd, fmt, arg);
	va_end(arg);
	return rtn;
}


/* scanf() */
int thread_scanf(const char *fmt, ...)
{
	va_list arg;
	int		rtn;
	va_start(arg, fmt);
	rtn = thread_vfscanf(stdin, fmt, arg);
	va_end(arg);
	return rtn;
}

/* sscanf() */
int thread_sscanf(register const char *str, const char *fmt, ...)
{
	va_list		arg;
	int			rtn;
	FILE		f;
	va_start(arg, fmt);
	f._base = f._ptr = (char*)str;
	f._bufsiz = f._cnt = strlen(str);
	f._flag = _IOREAD | _IOSTRG;
	rtn = thread_vfscanf(&f, fmt, arg);
	va_end(arg);
	return rtn;
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.