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
|
include <tbset.h>
include "tbtables.h"
include "tbltext.h"
# tbzrdx -- read an explicit-column-definitions text file into memory
#
# The input buffer buf will likely already contain a line from the input
# file, perhaps a column definition. (If not, buf will have been set
# to EOS.) This is because the beginning of the file is read to determine
# whether it is a simple text table or one with explicit column definitions.
#
# A new column will be created for each line of the file that contains
# an explicit column definition (i.e. each line beginning with "#c ").
#
# For each data line, tbzmex is called to read values into memory. tbzmex
# reallocates buffers, if necessary, and updates the number of rows.
#
# This version is for text tables with explicit column definitions. The
# version that is appropriate for a simple text table is tbzrds.
#
# Phil Hodge, 7-Jun-1999 Subroutine created, based on tbzopn.
# Phil Hodge, 24-Sep-1999 In tbbecd, call tbztyp instead of tbbtyp.
procedure tbzrdx (tp, buf, line, line_type)
pointer tp # i: pointer to table descriptor
char buf[ARB] # io: buffer for input line
int line # io: line number in input file
int line_type # io: type of line read by tbzlin
#--
pointer cp # pointer to column descriptor
char colname[SZ_COLNAME] # column name (read from buffer)
int datatype # data type code for a column
char colfmt[SZ_COLFMT] # print format for a column
char colunits[SZ_COLUNITS] # units for a column
int fd # fd for the file
int row # row number (can be from more than one line)
bool data_read # has a line of data been read?
bool done
int nchar, tbzlin() # reads a line from the file
errchk tbzlin, tbzmex, tbbecd, tbcadd, tbzkey
begin
fd = TB_FILE(tp)
row = 0
data_read = false
done = false
# If the input buffer is empty, read the first line.
if (buf[1] == EOS) {
nchar = tbzlin (fd, buf, SZ_TEXTBUF, line, line_type)
if (nchar == EOF)
done = true
}
while (!done) {
if (line_type == COMMENT_LINE) {
call tbbcmt (tp, buf) # append to comment buffer
} else if (line_type == KEYWORD_LINE) {
call tbzkey (tp, buf, 0) # append to list of keywords
} else if (line_type == COLDEF_LINE) {
if (data_read) {
call error (1,
"tbtopn: column definitions must precede all data lines")
}
# Interpret column definition, and create a new column.
call tbbecd (buf, colname, datatype, colfmt, colunits)
call tbcadd (tp, cp, colname, colunits, colfmt, datatype, 1, 1)
} else if (line_type == DATA_LINE) {
data_read = true
row = row + 1
# Read data into memory.
call tbzmex (tp, buf, row, line)
} else {
call error (1, "tbzrdx: internal error")
}
# Read the next line.
nchar = tbzlin (fd, buf, SZ_TEXTBUF, line, line_type)
if (nchar == EOF)
done = true
}
end
# tbbecd -- read column definition from buffer
# This routine skips over "#c ", then reads the column name, data type,
# print format, and units from the input buffer. Only the column name
# is required; the default data type is double.
procedure tbbecd (buf, colname, datatype, colfmt, colunits)
char buf[ARB] # i: buffer containing column definition
char colname[SZ_COLNAME] # o: column name
int datatype # o: data type code for column
char colfmt[SZ_COLFMT] # o: print format for column
char colunits[SZ_COLUNITS] # o: units for column
#--
char chdtype[SZ_COLNAME] # scratch for data type extracted from buffer
int ip, ctowrd()
errchk tbbftp, tbztyp
begin
ip = 4 # skip over "#c "
if (ctowrd (buf, ip, colname, SZ_COLNAME) < 1)
call error (1, "could not read column name")
if (ctowrd (buf, ip, chdtype, SZ_COLNAME) < 1) {
call strcpy ("d", chdtype, SZ_COLNAME) # default is double
colfmt[1] = EOS
colunits[1] = EOS
} else if (ctowrd (buf, ip, colfmt, SZ_COLFMT) < 1) {
colfmt[1] = EOS
colunits[1] = EOS
} else if (ctowrd (buf, ip, colunits, SZ_COLUNITS) < 1) {
colunits[1] = EOS
}
# Convert the format from Fortran style to SPP style.
call tbbftp (colfmt, colfmt)
# Convert the data type to an integer code.
call tbztyp (chdtype, datatype)
end
|