[comp.sys.mac.programmer] Enhancements to LSC3 stdio to use SF

np@ic.ac.uk (Nigel Perry) (10/18/89)

I recently offered enhancements to LSC3 stdio libraries to:

*	%k and %lk formats for printf() (& Co.)
	These formats print ints (%k) and longs (%lk) as characters,
	useful for ResType values.  
*	New 'device' ".SF" for fopen() and friends.
	The 'device' ".SF" causes fopen() is prompt for a file using
	the Standard File get (read/append access) or put (write access)
	dialogs. This saves the user calling Standard File themselves,
	converting the volRef/name pair to a full pathname, and then calling
	fopen()...
*	Added fdopen() and fdreopen() routines.
	These mimic their Unix counterparts but take a volume reference as well as a name.
*	Added in asm{...} statements.
	Doesn't add functionality, just decreases size to offset increase caused by new code...

I've had a number of requests, so below are diff's to the
files stdopen.c, printf-3.c & stdio.h. I'm also send an
archive to sumex containing: new library, new stdio.h,
example program and diffs.

			Enjoy, Nigel.

********************************	
Filename:  printf-3.c, new file.
--------------------------------
Filename:  printf-3.c, original file.

7	*/
8	/*
9		Modified by Nigel Perry, May 1989
10		
11		Added %k and %lk format to print word/longs as characters
12		Code controlled by #ifdef CHARINT
13		
14		) 1989, Nigel Perry
15	 */
16	 
17	/* add in %k format */
18	#define CHARINT
19	
--------------------------------
7	*/
8	

22	
23	#ifndef _stdioh_
--------------------------------
11	
12	#include "config.h"
13	
14	#ifndef _stdioh_

287	{
288	Boolean left_justify;           /* flag to indicate left justification */
289	Boolean do_precision;           /* flag limited precision */
--------------------------------
278	{
279	Boolean left_justify;           /* flag to indicate left justiccation */
280	Boolean do_precision;           /* flag limited precision */

635						break;
636	#ifdef CHARINT
637			case 'k':
638				{	register char *arg_hold;
639	
640					length = its_a_long ? sizeof(long) : sizeof(int);
641					arg_hold = argument + length;
642					if (do_precision && length > precision) length = precision;
643					width -= length;
644					
645					if(!left_justify) padd(BLANKS, width);
646					while (--length >= 0)
647						(*outputx)(*argument++);
648					if(left_justify) padd(BLANKS, width);
649	
650					argument = arg_hold;
651				}
652				break;
653	#endif
654	
--------------------------------
626						break;
627	


4 mismatches.

********************************	
Filename:  stdopen.c, new file.
--------------------------------
Filename:  stdopen.c, original file.

5	*/
6	/*
7		Modified by Nigel Perry, May 1989
8		
9		Added new "driver" name ".SF" which uses the Standard File Package
10		to select a file.
11		
12		All .SF code #ifdef'ed by STDFILE
13		
14		Added fdopen() and fdreopen() routines to open files given
15		volume reference and name.
16		
17		All fdopen() code #ifdef'ed by FDOPEN
18		
19		Added inline traps. All asm code #ifdef'ed by USEASM
20		
21		) 1989, Nigel Perry
22	 */
23	 
24	/* if defined will include new ".SF" "driver" */
25	#define STDFILE
26	/* if defined will include fdopen() code */
27	#define FDOPEN
28	/* do trap calls inline */
29	#define USEASM
30	
31	#ifndef _stdioh_
--------------------------------
5	*/
6	 
7	#ifndef _stdioh_

42	
43	#ifdef USEASM
44	#include <asm.h>
45	#endif
46	
47	#ifdef STDFILE
48	#ifndef	_StdFilePkg_
49	#include <StdFilePkg.h>
50	#endif
51	
52	/* "Point" to place dialog */
53	#define GETWHERE 0x00470052L
54	#define PUTWHERE 0x004f0068L
55	#define NIL (void *)0
56	#define EMPTY ((char *)0xA02)		/* low memory global OneOne */
57										/* used for "" and "\p" */
58	
59	#endif
60	
61	static Boolean _exiting_closeall_flag = false;
--------------------------------
18	
19	static Boolean _exiting_closeall_flag = false;

66	#line 0 xfopen
67	#ifdef FDOPEN
68	static FILE	*xfopen(volref,nameptr,type,who)
69	int volref;
70	#else
71	static FILE	*xfopen(nameptr,type,who)
72	#endif
73	char	*nameptr;
--------------------------------
24	#line 0 xfopen
25	static FILE	*xfopen(nameptr,type,who)
26	char	*nameptr;

89		register Ptr	p;
90	#ifdef STDFILE
91		SFReply reply;
92		SFTypeList types;
93		Boolean	SFdriver = false;
94	#endif
95	#ifdef FDOPEN
96		Boolean FDopen = false;
97	#endif
98	
--------------------------------
42		register Ptr	p;
43	

157	
158	#ifndef STDFILE
159	#ifdef FDOPEN
160		if(volref != 0)
161			FDopen = true;
162		else
163	#endif
164			CtoPstr(nameptr);
165	#else
166	#ifdef FDOPEN
167		if(volref != 0)
168			FDopen = true;
169		else
170	#endif
171		/* I would use *((long *)nameptr) == '.SF\0' if it were aligned... */
172		if( nameptr[0] == '.' && nameptr[1] == 'S'
173		 && nameptr[2] == 'F' && nameptr[3] == '\0' )
174		{	SFdriver = true;
175			if(!create || add)
176				SFGetFile(GETWHERE, EMPTY, NIL, -1, types, NIL, &reply);
177			else
178				SFPutFile(PUTWHERE, EMPTY, EMPTY, NIL, &reply);
179			if(!reply.good)
180			{	errno = bdNamErr;
181				return(NULL);
182			}
183		}
184		else
185			CtoPstr(nameptr);
186	#endif
187	
188	#ifndef USEASM
189		p = NewPtr((long)BUFSIZ);
190	#else
191		asm
192		{	move.l		#BUFSIZ,d0
193			_NewPtr
194			movea.l		a0,p
195		}
196	#endif
197	
198		do	{
199	
200	#ifdef STDFILE
201			if(!SFdriver)
202			{
203	#endif
204	#ifdef FDOPEN
205				if(!FDopen)
206				{
207	#endif	
208					/* pdg 7/29/86 - look only via default path */
209					pb.ioNamePtr	= 0;
210	#ifndef USEASM
211					if (PBGetVol(&pb, false)) pb.ioVRefNum	= 0;
212	#else
213					asm
214					{	lea		pb,a0
215						_PBGetVol
216						beq.s	@2
217						clr.w	pb.ioVRefNum
218					@2
219					}
220	#endif
221	#ifdef FDOPEN
222				}
223				else
224					pb.ioVRefNum = volref;
225	#endif	
226				pb.ioNamePtr	= (StringPtr)nameptr;
227	#ifdef STDFILE
228			}
229			else
230			{	pb.ioNamePtr = (StringPtr)&reply.fName;
231				pb.ioVRefNum = reply.vRefNum;
232			}
233	#endif
234			pb.ioVersNum	= 0;
--------------------------------
102	
103		CtoPstr(nameptr);
104	
105		p = NewPtr((long)BUFSIZ);
106	
107		do	{
108		
109			/* pdg 7/29/86 - look only via default path */
110	
111			pb.ioNamePtr	= 0;
112			if (PBGetVol(&pb, false)) pb.ioVRefNum	= 0;
113	
114	
115			pb.ioNamePtr	= (StringPtr)nameptr;
116			pb.ioVersNum	= 0;

237	
238	#ifndef USEASM
239			new = PBOpen(&pb,false);
240	#else
241			asm
242			{	lea		pb,a0
243				_PBOpen
244				move.w	d0,new
245			}
246	#endif
247	
248			if ((new == fnfErr) && (create))
249				{
250	#ifndef USEASM
251				if (err = (PBCreate(&pb,false))) goto err_exit;
252	#else
253				asm
254				{	lea		pb,a0
255					_PBCreate
256					bne		@err_exit
257				}
258	#endif
259	
--------------------------------
119	
120			new = PBOpen(&pb,false);
121			
122			if ((new == fnfErr) && (create))
123				{
124				if (err = (PBCreate(&pb,false))) goto err_exit;
125	

263				pb2.ioFVersNum	= pb.ioVersNum;
264	#ifndef USEASM
265				if (err = (PBGetFInfo(&pb2,false))) goto err_exit;
266	#else
267				asm
268				{	lea		pb2,a0
269					_PBGetFInfo
270					bne		@err_exit
271				}
272	#endif
273	
274				pb2.ioFlFndrInfo.fdType		= 'TEXT';
275				pb2.ioFlFndrInfo.fdCreator	= '????';
276	#ifndef USEASM
277				if (err = (PBSetFInfo(&pb2,false))) goto err_exit;
278	#else
279				asm
280				{	lea		pb2,a0
281					_PBSetFInfo
282					bne		@err_exit
283				}
284	#endif
285	
--------------------------------
129				pb2.ioFVersNum	= pb.ioVersNum;
130				if (err = (PBGetFInfo(&pb2,false))) goto err_exit;
131	
132				pb2.ioFlFndrInfo.fdType		= 'TEXT';
133				pb2.ioFlFndrInfo.fdCreator	= '????';
134				if (err = (PBSetFInfo(&pb2,false))) goto err_exit;
135	

295					{
296	#ifndef USEASM
297						if(err = (PBGetEOF(&pb,false))) goto err_exit;
298	#else
299						asm
300						{	lea		pb,a0
301							_PBGetEOF
302							bne		@err_exit
303						}
304	#endif
305		
306						pb.ioPosOffset = (long)pb.ioMisc;
307						pb.ioPosMode = fsFromStart;
308	#ifndef USEASM
309						err = PBSetFPos(&pb,false);
310						if ((err!=noErr) && (err!=eofErr)) goto err_exit;
311	#else
312						asm
313						{	lea		pb,a0
314							_PBSetFPos
315							beq.s	@1
316							cmp.w	#eofErr,d0
317							bne		@err_exit
318						@1
319						}
320	#endif
321					}
--------------------------------
145					{
146						if(err = (PBGetEOF(&pb,false))) goto err_exit;
147		
148						pb.ioPosOffset = (long)pb.ioMisc;
149						pb.ioPosMode = fsFromStart;
150						err = PBSetFPos(&pb,false);
151						if ((err!=noErr) && (err!=eofErr)) goto err_exit;
152					}

328						pb2.ioFVersNum	= pb.ioVersNum;
329	#ifndef USEASM
330						if (err = (PBGetFInfo(&pb2,false))) goto err_exit;
--------------------------------
159						pb2.ioFVersNum	= pb.ioVersNum;
160						if (err = (PBGetFInfo(&pb2,false))) goto err_exit;

340						new = PBOpen(&pb,false);
341	#else
342						asm
343						{	lea		pb2,a0
344							_PBGetFInfo
345							bne		@err_exit
346							lea		pb,a0
347							_PBClose
348							bne		@err_exit
349							lea		pb,a0
350							_PBDelete
351							bne		@err_exit
352							lea		pb,a0
353							_PBCreate
354							bne		@err_exit
355							lea		pb2,a0
356							_PBSetFInfo
357							bne		@err_exit
358							lea		pb,a0
359							_PBOpen
360							move.l	d0,new
361						}
362	#endif
363						create = false;
--------------------------------
170						new = PBOpen(&pb,false);
171						create = false;

387					who->inbuf		= 0;
388	#ifdef STDFILE
389	#ifdef FDOPEN
390					if(!SFdriver && !FDopen)
391	#else
392					if(!SFDriver)
393	#endif
394	#else
395	#ifdef FDOPEN
396					if(!FDopen)
397	#endif
398	#endif
399						PtoCstr(nameptr);
400					if (_init_onexit == false)
--------------------------------
195					who->inbuf		= 0;
196					PtoCstr(nameptr);
197					if (_init_onexit == false)

425	err_exit:
426	#ifndef USEASM
427		errno = err;
428	#else
429		asm
430		{	move.l		d0,errno
431		}
432	#endif
433		
434	exit_noset:
435	
436	#ifndef USEASM
437		DisposPtr(p);
438	#else
439		asm
440		{	movea.l		p,a0
441			_DisposPtr
442		}
443	#endif
444	
445	#ifdef STDFILE
446	#ifdef FDOPEN
447		if(!SFdriver && !FDopen)
448	#else
449		if(!SFdriver)
450	#endif
451	#else
452	#ifdef FDOPEN
453		if(!FDopen)
454	#endif
455	#endif
456			PtoCstr(nameptr);
457		return(NULL);
--------------------------------
222	err_exit:
223		errno = err;
224		
225	exit_noset:
226	
227		DisposPtr(p);
228		PtoCstr(nameptr);
229		return(NULL);

498						goto err2_exit;
499				pb.ioRefNum = refnum;
--------------------------------
270						goto err2_exit;
271	
272				pb.ioRefNum = refnum;

507	
508	#ifndef USEASM
509					if (err = who->last_error = PBWrite(&pb,false))
510						errno = err;
511	#else
512					asm
513					{	lea			pb,a0
514						_PBWrite
515						move.w		d0,err
516						move.w		d0,OFFSET(FILE,last_error)(who)
517						beq.s		@3
518						move.w		d0,errno
519					@3
520					}
521	#endif
522				}
523	
524				who->InUse = false;
525	#ifndef USEASM
526				if (err = (PBClose(&pb,false)))		/* close file */
527					goto err2_exit;
528	#else
529				asm
530				{	lea		pb,a0
531					_PBClose
532					move.w	d0,err
533					bne		@err2_exit
534				}
535	#endif
536	
--------------------------------
280	
281					if (err = who->last_error = PBWrite(&pb,false))
282						errno = err;
283				}
284	
285				who->InUse = false;
286				if (err = (PBClose(&pb,false)))		/* close file */
287					goto err2_exit;
288	

540					pb.ioNamePtr = 0L;
541	#ifndef USEASM
542					if (err = (PBFlshVol(&pb,false)))		/* flush vol */
543						goto err2_exit;
544	#else
545					asm
546					{	lea		pb,a0
547						_PBFlshVol
548						move.w	d0,err
549						bne		@err2_exit
550					}
551	#endif
552				}
--------------------------------
292					pb.ioNamePtr = 0L;
293					if (err = (PBFlshVol(&pb,false)))		/* flush vol */
294						goto err2_exit;
295				}

569			if (!who->user_buf)
570	#ifndef USEASM
571				DisposPtr(who->filebuf);			/* dispose mem*/
572	#else
573				asm
574				{	movea.l		OFFSET(FILE,filebuf)(who),a0
575					_DisposPtr
576				}
577	#endif
578			return(0);
--------------------------------
312			if (!who->user_buf)
313				DisposPtr(who->filebuf);			/* dispose mem*/
314	
315			return(0);

597	{
598	#ifdef FDOPEN
599		return(xfopen(0,nameptr,type,NULL));
600	#else
601		return(xfopen(nameptr,type,NULL));
602	#endif
603		
--------------------------------
334	{
335		return(xfopen(nameptr,type,NULL));
336		

616		if(fclose(who)) return(NULL);
617	#ifdef FDOPEN
618		return(xfopen(0,nameptr,type,who));
619	#else
620		return(xfopen(nameptr,type,who));
621	#endif
622	}
623	
624	#ifdef FDOPEN
625	#line 0 fdopen
626	FILE	*fdopen(volref,nameptr,type)
627		int		volref;
628		char	*nameptr,*type;
629	{
630		return(xfopen(volref,nameptr,type,NULL));
631	
632	}
633	
634	#line 0 fdreopen
635	FILE	*fdreopen(volref,nameptr,type,who)
636		int		volref;
637		char	*nameptr,*type;
638		FILE	*who;
639	
640	{
641		if(fclose(who)) return(NULL);
642		return(xfopen(volref,nameptr,type,who));
643	}
644	#endif
645	
--------------------------------
349		if(fclose(who)) return(NULL);
350		return(xfopen(nameptr,type,who));
351	}
352	
353	

18 mismatches.

********************************	
Filename:  stdio.h, new file.
--------------------------------
Filename:  stdio.h, original file.

7	 * (C) Copyright 1985, 1986. THINK Technologies Inc. All rights reserved.
8	 *
9	 * Added in fdopen() & fdreopen(), Nigel Perry, 1989
10	 */
--------------------------------
7	 * (C) Copyright 1985, 1986. THINK Technologies Inc. All rights reserved.
8	 */

72	FILE	*freopen();		/* open a file using the given stream */
73	FILE	*fdopen();		/* open a file using volref/name pair */
74	FILE	*fdreopen();	/* open a file using volref/name pair on the given stream */
75	extern	FILE	_file[_NFILE];	/* file descriptor array (internal) */
76	extern	FILE	_console_;		/* device name for the console */
77	long	ftell();		/* get position within file */
78	
--------------------------------
70	FILE	*freopen();		/* open a file using the given stream */
71	extern	FILE	_file[_NFILE];	/* file descriptor array (internal) */
72	extern	FILE	_console_;		/* device name for the console */
73	long	ftell();		/* get position withen file */
74	


2 mismatches.

--
---
Nigel Perry                                  Department of Computing
                                             Imperial College
Janet: np@uk.ac.ic.doc                       London
DARPA: np%uk.ac.ic.doc@ucl-cs                SW7
Uucp:  np@icdoc.UUCP, ukc!icdoc!np           England