aboutsummaryrefslogtreecommitdiff
path: root/sys/qpoe/qpaddf.x
blob: e72c2cc1fd31f148714e294faf51c449f01634d1 (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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.

include	<syserr.h>
include	<error.h>
include	<qpset.h>
include	"qpoe.h"

# QP_ADDF -- Add a new field (header parameter) to the datafile.  It is an
# error if the parameter redefines an existing symbol.  For variable array
# parameters the initial size is zero, and a new lfile is allocated for the
# parameter value.  For static parameters storage is initialized to all zeros.

procedure qp_addf (qp, param, datatype, maxelem, comment, flags)

pointer	qp			#I QPOE descriptor
char	param[ARB]		#I parameter name
char	datatype[ARB]		#I parameter data type
int	maxelem			#I allocated length of parameter
char	comment[ARB]		#I comment describing parameter
int	flags			#I parameter flags

bool	newtype
pointer	sp, text, st, fm, sym, pval, dsym, dd
int	fd, sz_elem, type, nchars, dtype, nfields, i

long	note()
pointer	qp_gpsym(), stenter(), strefstab()
int	stpstr(), qp_dtype(), qp_parsefl(), gstrcpy
int	fm_nextlfile(), fm_getfd(), qp_elementsize(), fm_fopen()
errchk	qp_bind, qp_gpsym, stenter, stpstr, fm_nextlfile, fm_fopen
errchk	fm_getfd, note, write, syserrs
define	fixed_ 91

begin
	call smark (sp)
	call salloc (text, SZ_TEXTBUF, TY_CHAR)

	if (QP_ACTIVE(qp) == NO)
	    call qp_bind (qp)

	st = QP_ST(qp)
	fm = QP_FM(qp)

	# Resolve any macro references in the 'datatype' text.
	# (Disabled - not sure this is a good idea here).

	# nchars = qp_expandtext (qp, datatype, Memc[text], SZ_TEXTBUF)
	nchars = gstrcpy (datatype, Memc[text], SZ_TEXTBUF)

	if (QP_DEBUG(qp) > 1) {
	    call eprintf ("qp_addf: `%s' typ=`%s' nel=%d com=`%s' flg=%oB\n")
		call pargstr (param)
		call pargstr (Memc[text])
		call pargi (maxelem)
		call pargstr (comment)
		call pargi (flags)
	}

	# Check for a redefinition.
	sym = qp_gpsym (qp, param)
	if (sym != NULL)
	    call syserrs (SYS_QPREDEF, param)

	# Add the symbol.
	sym = stenter (st, param, LEN_SYMBOL)

	# Determine symbol type.
	dtype = qp_dtype (qp, Memc[text], dsym)
	newtype = (dtype == TY_USER && dsym == NULL)
	sz_elem = qp_elementsize (qp, Memc[text], INSTANCEOF)

	S_DTYPE(sym) = dtype
	S_SZELEM(sym) = 0
	if (dsym != NULL)
	    S_DSYM(sym) = dsym - strefstab(st,0)
	else
	    S_DSYM(sym) = 0

	# If defining a new user datatype (domain), SZELEM is the size of
	# a structure element in chars, and MAXELEM is the length of the
	# field list string, which becomes the value of the domain definition
	# parameter.

	if (newtype) {
	    S_MAXELEM(sym) = nchars
	    call salloc (dd, LEN_DDDES, TY_STRUCT)
	    iferr (nfields = qp_parsefl (qp, Memc[text], dd))
		call erract (EA_WARN)
	    else
		S_SZELEM(sym) = DD_STRUCTLEN(dd) * SZ_STRUCT
	} else
	    S_MAXELEM(sym) = maxelem

	# If no flags are specified, set SF_INHERIT for fixed length params.
	if (flags == 0 && S_MAXELEM(sym) > 0)
	    S_FLAGS(sym) = SF_INHERIT
	else if (flags == QPF_NONE)
	    S_FLAGS(sym) = 0
	else
	    S_FLAGS(sym) = flags

	# Comments are stored in the symbol table and cannot be modified.
	if (comment[1] != EOS)
	    S_COMMENT(sym) = stpstr (st, comment, 0)
	else
	    S_COMMENT(sym) = NULL

	# Initialize data storage for the parameter.
	if (S_MAXELEM(sym) == 0) {
	    # A variable length parameter; store in it's own lfile.  The
	    # initial length is zero, hence initialization is not needed.

	    S_NELEM(sym) = 0
	    S_OFFSET(sym) = 1

	    # If we run out of lfiles, try to make do by allocating a fixed
	    # amount of static storage.

	    iferr (S_LFILE(sym) = fm_nextlfile(fm)) {
		S_MAXELEM(sym) = (QP_FMPAGESIZE(qp) + sz_elem-1) / sz_elem
		call erract (EA_WARN)
		goto fixed_
	    }

	    if (dtype == TY_CHAR)
		type = TEXT_FILE
	    else
		type = BINARY_FILE

	    fd = fm_fopen (fm, S_LFILE(sym), NEW_FILE, type)
	    call close (fd)

	} else {
	    # A fixed length parameter; allocate and initialize storage in
	    # LF_STATICPARS.
fixed_
	    fd = fm_getfd (fm, LF_STATICPARS, APPEND, 0)

	    S_NELEM(sym) = 0
	    S_OFFSET(sym) = note (fd)
	    S_LFILE(sym) = LF_STATICPARS
	    nchars = S_MAXELEM(sym) * sz_elem

	    # The param value is the field list (datatype parameter) for a
	    # domain definition; otherwise we do not have a value yet, so we
	    # merely allocate the storage and initialize to zero.

	    if (newtype) {
		call write (fd, Memc[text], nchars)
		S_NELEM(sym) = S_MAXELEM(sym)
	    } else {
		call salloc (pval, nchars, TY_CHAR)
		call aclrc (Memc[pval], nchars)
		call write (fd, Memc[pval], nchars)
	    }

	    call fm_retfd (fm, S_LFILE(sym))
	}

	if (QP_DEBUG(qp) > 2) {
	    # Dump symbol.
	    call eprintf ("%s: FLG=%oB TYP=%d DSY=%xX NEL=%d ")
		call pargstr (param)
		do i = 1, 4
		    call pargi (Memi[sym+i-1])
	    call eprintf ("MEL=%d SZE=%d COM=%xX LFN=%d OFF=%d\n")
		do i = 5, 9
		    call pargi (Memi[sym+i-1])
	}

	QP_MODIFIED(qp) = YES
	call sfree (sp)
end