aboutsummaryrefslogtreecommitdiff
path: root/sys/fio/stropen.x
blob: ac3c806890beaf48f08dfe50b9f5abf7dfa288ce (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.

include	<config.h>
include	<syserr.h>
include	<fio.h>

# STROPEN, STRCLOSE -- Open/close a character string for file i/o.  Called by
# sprintf (for example) to make the output string look like a file.
# 
# The string is made to appear to be the file buffer.  It is a fatal error
# if the string is not char aligned with Mem.  If the output string should
# overflow, FIO will call FLSBUF, resulting in a system error action.  STROPEN,
# for efficiency reasons, does not really open a file, it merely validates the
# buffer pointers and reserves a file descriptor.  Note that the buffer
# pointers may be negative.  Seeks are illegal on a string file, and will
# cause an error action to be taken.
# 
# If alignment is not automatically guaranteed for char data on your machine,
# define "stropen" as "memopen($1,$2,$3,TEXT_FILE)", and "strclose" as "close",
# in <iraf.h> (or install a dummy procedure in the library).

int procedure stropen (str, maxch, mode)

char	str[ARB]			#I string buffer for i/o
int	maxch				#I capacity of buffer
int	mode				#I FIO access mode

pointer	bp
int	fd, ip, loc_str, loc_Mem
errchk	syserr
include	<fio.com>

begin
	# Find an unused file descriptor.
	for (fd=FIRST_FD;  fd <= LAST_FD && fiodes[fd] != NULL;  fd=fd+1)
	    ;
	if (fd > LAST_FD)
	    call syserr (SYS_FTOOMANYFILES)

	# Compute pointer (Memc index) to the string.
	call zlocva (str,  loc_str)
	call zlocva (Memc, loc_Mem)
	bp = loc_str - loc_Mem + 1

	# Get file descriptor and init the buffer pointers.
	call fstrfp (fiodes[fd])
	call strsetmode (fd, mode)
	bufptr[fd] = bp
	buftop[fd] = bp + maxch
	fflags[fd] = 0

	# If string is being opened in any of the following modes, it
	# must be an initialized (written into) string with an EOS.
	# Find EOS and set itop accordingly.

	if (mode == READ_ONLY || mode == READ_WRITE || mode == APPEND)
	    for (ip=1;  str[ip] != EOS && ip <= maxch;  ip=ip+1)
		;

	# Seeks are illegal on strings.  Modes RO and RW are equivalent, as
	# are WO, NF, and TF.  Append is like WO/NF/TF, but the i/o pointer is
	# positioned at the EOS.  An EOS will automatically be written when
	# a file opened with mode WO, NF, TF, or AP is closed.

	iop[fd]  = bp
	itop[fd] = bp
	otop[fd] = bp + maxch

	switch (mode) {
	case READ_ONLY, READ_WRITE:
	    itop[fd] = bp + ip - 1
	    otop[fd] = bp
	case APPEND:
	    iop[fd] = bp + ip - 1
	}

	return (fd)
end


# STRCLOSE -- Close a string file previously opened by STROPEN.  If writing
# to a new string, append an EOS to the end of the string.  This routine is
# automatically called by CLOSE if the string was opened as a file with
# STROPEN.  Applications should call CLOSE, instead of calling STRCLOSE
# directly, to ensure that the file descriptor allocated by STROPEN and FIO
# is fully closed.

procedure strclose (fd)

int	fd				#I file descriptor
int	strgetmode()
errchk	syserr
include	<fio.com>

begin
	if (fd < 0 || fiodes[fd] == NULL)
	    call syserr (SYS_FILENOTOPEN)

	# Free any file pushback.
	call mfree (FPBBUF(fiodes[fd]), TY_CHAR)

	# If string was opened for writing, append EOS.  NOTE that if the
	# string was opened with length N, the EOS will go into location N+1
	# if the string is completely full.

	switch (strgetmode(fd)) {
	case WRITE_ONLY, APPEND, NEW_FILE, TEMP_FILE:
	    Memc[iop[fd]] = EOS
	default:
	    ;
	}

	# Free the file descriptor.
	bufptr[fd] = NULL
	fiodes[fd] = NULL
end


# STRSETMODE -- Set the access mode for a string file.  This is an internal
# routine normally called only by STROPEN above.  It may also called during
# task termination and cleanup to change the string file access mode to avoid
# an attempt to EOS terminate the string buffer, before closing off any still
# open string files

procedure strsetmode (fd, mode)

int	fd				#I file descriptor
int	mode				#I file access mode
include	<fio.com>

begin
	# For a string file the access mode is arbitrarily saved in BOFFSET
	# for CLOSE (strclose), which needs to know the access mode in order
	# to append an EOS.  BOFFSET is not otherwise used for string files
	# since the string buffer has no associated file offset.

	boffset[fd] = mode
end


# STRGETMODE -- Get the access mode for a string file.  This is an internal
# routine normally called only by STRCLOSE.

int procedure strgetmode (fd)

int	fd				#I file descriptor
include	<fio.com>

begin
	return (boffset[fd])
end