aboutsummaryrefslogtreecommitdiff
path: root/noao/digiphot/lib/pttables/ptgnfn.x
blob: f3d4ddcb0e410362b459b98e419f0498ccfd0897 (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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
include <syserr.h>
include	<ctype.h>
include "../ptkeysdef.h"

define	MAX_FIELDS	128
define	SZ_SBUF		1024
define	LEN_FNSTRUCT	(10 + MAX_FIELDS)

define	FN_NENTRIES	Memi[$1]		# number of field names in list
define	FN_NEXT		Memi[$1+1]		# next string to be returned
define	FN_SBUF		Memi[$1+2]		# pointer to string buffer
define	FN_STRP		Memi[$1+10+$2-1]	# array of str ptrs

define	FN_FIELDNAME	Memc[FN_STRP($1,$2)]	# reference a string


# PT_OFNL -- Procedure to decode the template.

pointer procedure pt_ofnl (ap, template)

pointer	ap			# image descriptor
char	template[ARB]		# field name template

int	tp, nstr, ch, junk
pointer	sp, ip, op, rop, fn, pattern, patcode, ranges, nextch
int	patmake(), patmatch()
errchk	syserr

begin
	call smark (sp)
	call salloc (pattern, SZ_FNAME, TY_CHAR)
	call salloc (patcode, SZ_LINE,  TY_CHAR)
	call salloc (ranges, SZ_FNAME, TY_CHAR)

	# Allocate field list descriptor and initialize.
	call calloc (fn, LEN_FNSTRUCT, TY_STRUCT)
	call malloc (FN_SBUF(fn), SZ_SBUF, TY_CHAR)
	nextch = FN_SBUF(fn)
	nstr = 0
	tp = 1

	# Extract each comma delimited template, expand upon the aphot
	# database and add strings to list.

	while (template[tp] != EOS && template[tp] != '\n') {

	    # Advance to next field.
	    while (IS_WHITE(template[tp]) || template[tp] == ',')
		tp = tp + 1

	    # Extract pattern.  Enclose pattern in {} so that the match will
	    # be case insensitive.

	    op = pattern
	    Memc[op] = '^'
	    op = op + 1
	    Memc[op] = '{'
	    op = op + 1

	    # Fetch the pattern.
	    ch = template[tp]
	    while (! (IS_WHITE(ch) || ch == '\n' || ch == ',' || ch == '[' ||
	        ch == EOS)) {

		# Map "*" into "?*".
		if (ch == '*') {
		    Memc[op] = '?'
		    op = op + 1
		}

		# Update.
		Memc[op] = ch
		op = op + 1
		tp = tp + 1
		ch = template[tp]
	    }

	    # Decode ranges.
	    if (ch == '[') {
		rop = ranges
		while (! (ch == '\n' || ch == EOS || ch == ']')) {
		    Memc[rop] = ch
		    rop = rop + 1
		    tp = tp + 1
		    ch = template[tp]
		}
		Memc[rop] = ']'
		rop = rop + 1
		tp = tp + 1
		ch = template[tp]
		while (ch != EOS && ch != '\n' && ch != ',' && IS_DIGIT(ch)) {
		    Memc[rop] = ch
		    tp = tp + 1
		    ch = template[tp]
		    rop = rop + 1
		}
		Memc[rop] = EOS
	    } else
		Memc[ranges] = EOS

	    # Close off the pattern.
	    Memc[op] = '}'
	    op = op + 1
	    Memc[op] = EOS

	    # Encode the pattern.
	    junk = patmake (Memc[pattern], Memc[patcode], SZ_LINE)

	    # Scan database and extract all field names matching the
	    # pattern.

	    for (ip = KY_WORDS(ap) + 1;  Memc[ip] != EOS;  ip = ip + 1) {

		# Put key in list if it matches.
		if (patmatch (Memc[ip], Memc[patcode]) > 0) {
		    call pt_fnputkey (Memc[ip], Memc[ranges], FN_STRP(fn,1),
		        nstr, nextch, FN_SBUF(fn))
		}

		# Advance to the next record.
		while (Memc[ip] != ',' && Memc[ip] != EOS)
		    ip = ip + 1

		# Quit if you hit EOS
		if (Memc[ip] == EOS)
		    break
	    }
	}

	FN_NENTRIES(fn) = nstr
	FN_NEXT(fn)     = 1
	call sfree (sp)
	return (fn)
end


# PT_GNFN -- Get the next field name matching the given template from the
# apphot data base.

int procedure pt_gnfn (fn, outstr, ranges, maxch)

pointer	fn			# field name list descriptor
char	outstr[ARB]		# output string
char	ranges[ARB]		# ranges string
int	maxch			# maximum number of characters

char	left_bkt
int	strnum, findex, nchars
int	gstrcpy(), stridx()
data	left_bkt /'['/

begin
	# Initialize.
	ranges[1] = EOS
	outstr[1] = EOS

	# Check that there is an entry
	strnum = FN_NEXT(fn)
	if (strnum > FN_NENTRIES(fn))
	    return (EOF)

	# Get the next field name.
	nchars = gstrcpy (FN_FIELDNAME(fn,strnum), outstr, maxch)

	# Get the ranges string.
	findex = stridx (left_bkt, outstr)
	if (findex > 0) {
	    call strcpy (outstr[findex], ranges, maxch)
	    outstr[findex] = EOS
	}

	# Increment counter.
	FN_NEXT(fn) = strnum + 1

	return (nchars)
end


# PT_CFNL -- Procedure to close the list.

procedure pt_cfnl (fn)

pointer	fn			# field name list descriptor

begin
	call mfree (FN_SBUF(fn), TY_CHAR)
	call mfree (fn, TY_STRUCT)
end



# PT_FNPUTKEY -- Put a keyword into the keyword list.

procedure pt_fnputkey (key, ranges, strp, nstr, nextch, sbuf)

char	key[ARB]		# keyword name (etc.)
char	ranges[ARB]		# list of ranges
pointer	strp[ARB]		# array of string pointers
int	nstr			# current number of strings
pointer	nextch			# next available char in string buffer
pointer	sbuf			# string buffer

int	ch, ip, rip
errchk	syserr

begin
	# Check size of string buffer.
	nstr = nstr + 1
	if (nstr > MAX_FIELDS)
	    call error (0, "There too many fields in the input template")

	# Initialize.
	strp[nstr] = nextch
	ip = 1
	ch = key[ip]

	# Append keyword to the string buffer.
	while (ch != ',' && ch != ' ' && ch != EOS) {
	    Memc[nextch] = ch
	    nextch = nextch + 1
	    if (nextch >= sbuf + SZ_SBUF)
	        call error (0, "There too many fields in the input template")
	    ip = ip + 1
	    ch = key[ip]
	}

	# Get the ranges information.
	rip = 1
	while (ranges[rip] != EOS) {
	    Memc[nextch] = ranges[rip]
	    nextch = nextch + 1
	    if (nextch >= sbuf + SZ_SBUF)
	        call error (0, "There too many fields in the input template")
	    rip = rip + 1
	}

	Memc[nextch] = EOS
	nextch = nextch + 1
end