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
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
|
include <fset.h> # used to check whether I/O is redirected
include <error.h>
include <tbset.h>
include "tupar.h" # defines TUPAR_EXIT, TUPAR_QUIT
# tupar -- edit header parameters
# This task may be used to list, add to, replace, or delete header
# parameters in a table or list of tables.
#
# Phil Hodge, 22-Jul-1987 Task created
# Phil Hodge, 11-Aug-1987 Call tbhad[] instead of tbhpt[].
# Phil Hodge, 18-Mar-1988 Rewrite, allowing a list of tables.
# Phil Hodge, 7-Sep-1988 Change parameter name for table.
# Phil Hodge, 23-Aug-1991 Allow quit or exit.
# Phil Hodge, 9-Jul-1993 Allow quit without verification if nothing changed.
# Phil Hodge, 29-Jun-1995 Modify for FITS tables; modify tu_open and tu_close.
# Phil Hodge, 3-Oct-1995 Use tbn instead of fnt.
# Phil Hodge, 22-May-1996 Use iferr when calling tu_instr.
define LEN_ISBUF 1000 # length or increment for instruction buffer
procedure tupar()
pointer tlist # for list of input table names
bool same_for_all # same set of instructions for all tables?
bool verbose # print name of each table?
bool readonly # open tables readonly?
#--
pointer tp # pointer to table descriptor
pointer sp
pointer tname # scratch for table name
pointer tabname # scratch for full name of table (incl [...])
pointer lbuf # scratch for input buffer
pointer isbuf # buffer for saving instructions
int bufsize # allocated size of Memc[isbuf]
int ibp # index in Memc[isbuf]
int eq_flag # exit or quit
int istat # set by tu_ex_instr; > 0 implies error
bool inplace # open tables inplace?
bool modified # true if the header was modified
bool from_stdin # get input from STDIN?
bool save_instr # save instruction in buffer?
bool iredir # is input redirected?
bool oredir # is output redirected?
bool prompt # prompt user for input?
bool alldone # done with all tables?
bool done # done with current table?
bool quit # true if we should delete temp table
bool clgetb()
int fstati()
pointer tbnopenp()
int tbnget(), tbnlen()
begin
call smark (sp)
call salloc (tname, SZ_LINE, TY_CHAR)
call salloc (tabname, SZ_LINE, TY_CHAR)
call salloc (lbuf, SZ_LINE, TY_CHAR)
tlist = tbnopenp ("table")
same_for_all = clgetb ("same")
verbose = clgetb ("verbose")
readonly = clgetb ("readonly")
if (readonly)
inplace = true
else
inplace = clgetb ("inplace")
from_stdin = true
# Is input or output redirected?
iredir = (fstati (STDIN, F_REDIR) == YES)
oredir = (fstati (STDOUT, F_REDIR) == YES)
prompt = !iredir # prompt if input is not redirected
save_instr = (same_for_all && (tbnlen (tlist) > 1))
if (save_instr) {
bufsize = LEN_ISBUF
call malloc (isbuf, bufsize, TY_CHAR)
Memc[isbuf] = EOS
} else {
bufsize = 0
isbuf = NULL
}
# Loop over all table names in the file name template.
alldone = (tbnget (tlist, Memc[tname], SZ_LINE) == EOF)
while (!alldone) {
iferr {
# Open the table (or a copy of it).
call tu_open (Memc[tname], "tupar", readonly, inplace,
tp, Memc[tabname], SZ_LINE)
} then {
call eprintf ("can't open %s\n")
call pargstr (Memc[tname])
alldone = (tbnget (tlist, Memc[tname], SZ_LINE) == EOF)
call erract (EA_WARN)
next # ignore this table
}
if (verbose) {
if (oredir) {
call eprintf ("%s\n")
call pargstr (Memc[tabname])
}
call printf ("%s\n")
call pargstr (Memc[tabname])
}
# Edit header parameters in current table.
ibp = 1 # may be incremented in loop
modified = false # may be reset within tu_instr
done = false
while ( ! done ) {
# Get an instruction, execute it, and possibly save it
# for use again.
iferr {
call tu_instr (tp, Memc[lbuf], readonly, prompt, from_stdin,
iredir, save_instr, isbuf, bufsize, ibp,
modified, eq_flag, done, istat)
} then {
call erract (EA_WARN)
}
if (istat > 0)
call eprintf ("table was opened readonly\n")
if (inplace && !readonly &&
(eq_flag == TUPAR_QUIT || eq_flag == TUPAR_QUIT_NC)) {
call eprintf (
"can't quit without saving changes because you edited the table inplace\n")
done = false
} else if (eq_flag == TUPAR_QUIT && modified && !readonly) {
# Ask for verification before quitting.
call clputb ("go_ahead", clgetb ("quit_default"))
call eprintf ("quit without saving changes")
call flush (STDERR)
if (! clgetb ("go_ahead"))
done = false # no, don't quit
}
}
# Reset flags after processing first table.
if (same_for_all) {
prompt = false
from_stdin = false
}
save_instr = false
# Close the table, renaming the temp table back to the
# original if we are saving our changes.
quit = (eq_flag == TUPAR_QUIT || eq_flag == TUPAR_QUIT_NC)
iferr {
call tu_close (tp, inplace, quit, Memc[tabname])
} then {
alldone = (tbnget (tlist, Memc[tname], SZ_LINE) == EOF)
call erract (EA_WARN)
next # ignore this table
}
# Get the name of the next file in the list.
alldone = (tbnget (tlist, Memc[tname], SZ_LINE) == EOF)
# If the user modified the table but then decided to quit,
# then abort without opening the rest of the tables.
if (eq_flag != TUPAR_EXIT && modified && same_for_all)
alldone = true
}
if (isbuf != NULL)
call mfree (isbuf, TY_CHAR)
call tbnclose (tlist)
call sfree (sp)
end
# tu_save_instr -- save edit instruction
# Save the current instruction in the instruction buffer. The entries
# are separated by '\n', and the entire set of entries is terminated
# by EOS.
# If the buffer would overflow, it will be reallocated.
procedure tu_save_instr (lbuf, isbuf, bufsize, ibp)
char lbuf[ARB] # i: line buffer containing instruction
pointer isbuf # io: buffer for saving instructions
int bufsize # io: current allocated size of Memc[isbuf]
int ibp # io: current index in Memc[isbuf]
#--
int k # loop index
bool done # loop-termination flag
int leni # length of lbuf
int strlen()
begin
leni = strlen (lbuf)
if (ibp + leni >= bufsize) {
bufsize = bufsize + LEN_ISBUF
call realloc (isbuf, bufsize, TY_CHAR)
}
done = false
k = 1
while ( ! done ) {
if ((lbuf[k] == EOS) || (lbuf[k] == '\n')) {
done = true
} else {
Memc[isbuf+ibp-1] = lbuf[k]
ibp = ibp + 1
}
k = k + 1
}
Memc[isbuf+ibp-1] = '\n'
Memc[isbuf+ibp] = EOS
ibp = ibp + 1 # so ibp points to EOS
end
# tu_rd_instr -- read edit instruction
# Read an instruction from the instruction buffer. When EOS is reached
# in the buffer, an EOF will be returned; otherwise, the number of char
# in the current instruction will be returned.
int procedure tu_rd_instr (isbuf, ibp, lbuf)
char isbuf[ARB] # i: buffer containing instructions
int ibp # io: current index in isbuf
char lbuf[ARB] # o: buffer to receive instruction
#--
int k # loop index
bool done # loop-termination flag
begin
done = false
k = 0
while ( ! done ) {
if (isbuf[ibp] == '\n') {
if (k > 0) # skip past adjacent '\n'
done = true
ibp = ibp + 1
} else if (isbuf[ibp] == EOS) {
done = true # leave ibp pointing to EOS
} else {
k = k + 1
lbuf[k] = isbuf[ibp]
ibp = ibp + 1
}
}
lbuf[k+1] = EOS
if (k <= 0)
k = EOF
return (k)
end
|