aboutsummaryrefslogtreecommitdiff
path: root/pkg/tbtables/selector/rdselect.x
blob: 22b25db573991f5db0483f676288445a67d80b3a (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
define	MAXSECT		3

# RDSELECT -- Break a filename into root and selectors

procedure rdselect (file, root, rowselect, colselect, maxch)
		       
char	file[ARB]	# i: filename
char	root[ARB]	# o: filename minus any selectors
char	rowselect[ARB]	# o: row selector
char	colselect[ARB]	# o: column selector
int	maxch		# i: max length of output strings
#--
char	colon
int	ic, nc, isect, nsect, idtype
pointer	sp, ident, extend, errmsg, bracket[MAXSECT]

data	colon	 / ':' /
string	idlist	 "|row|column|"
string	badtype  "Unrecognized selector (%s)"

bool	nextbrak()
int	stridx(), strdic()

errchk	nextbrak

begin
	call smark (sp)
	call salloc (ident, SZ_FNAME, TY_CHAR)
	call salloc (extend, SZ_FNAME, TY_CHAR)
	call salloc (errmsg, SZ_LINE, TY_CHAR)

	# Search for the first unescaped bracket
	# Copy all chars prior to bracket into root

	for (ic = 1; file[ic] != EOS; ic = ic + 1) {
	    if (file[ic] == '\\' && file[ic+1] != EOS) {
		ic = ic + 1
	    } else if (file[ic] == '['){
		break
	    }
	}

	nc = min (ic-1, maxch)
	call strcpy (file, root, nc)

	# Get bracketed sections from file name

	for (isect = 1; isect <= MAXSECT; isect = isect + 1) {

	    call salloc (bracket[isect], SZ_FNAME, TY_CHAR)
	    if (! nextbrak (file, ic, Memc[bracket[isect]], maxch))
		break
	}

	nsect = isect - 1

	rowselect[1] = EOS
	colselect[1] = EOS

	# Use leading identifier to determine type of selector

	do isect = 1, nsect {
	    ic = stridx (colon, Memc[bracket[isect]])
	    if (ic == 0) {
		# Append bracketed sections with no identifier to the root

		call sprintf (Memc[extend], SZ_FNAME, "[%s]")
		call pargstr (Memc[bracket[isect]])

		call strcat (Memc[extend], root, maxch)

	    } else if (ic > 0) {
		call strcpy (Memc[bracket[isect]], Memc[ident], ic-1)
		idtype = strdic (Memc[ident], Memc[ident], SZ_FNAME, idlist)

		if (idtype == 0) {
		    call sprintf (Memc[extend], SZ_FNAME, "[%s]")
		    call pargstr (Memc[bracket[isect]])

		    call strcat (Memc[extend], root, maxch)

		} else if (idtype == 1 && rowselect[1] == EOS) {
		    call strcpy (Memc[bracket[isect]+ic], rowselect, maxch)

		} else if (idtype == 2 && colselect[1] == EOS) {
		    call strcpy (Memc[bracket[isect]+ic], colselect, maxch)

		} else {
		    call sprintf (Memc[errmsg], SZ_LINE, badtype)
		    call pargstr (file)

		    call error (1, Memc[errmsg])
		}
	    }
	}

	call sfree (sp)
end

# NEXTBRAK -- Get next bracketed section from file name

bool procedure nextbrak (file, ic, section, maxch)

char	file[ARB]	# i: file name
int	ic		# u: index to char within name
char	section[ARB]	# o: section extracted from name
int	maxch		# i: maximum length of section
#--
int	jc, level
pointer	sp, errmsg

string	badsect  "No closing bracket (%s)"

begin
	if (file[ic] != '[') {
	    section[1] = EOS
	    return (false)
	} else {
	    level = 1
	    ic = ic + 1
	}

	call smark (sp)
	call salloc (errmsg, SZ_LINE, TY_CHAR)

	jc = 1
	while (level > 0 && file[ic] != EOS) {
	    if (file[ic] == '[' && file[ic-1] != '\\') {
		level = level + 1
	    } else if (file[ic] == ']' && file[ic-1] != '\\') {
		level = level - 1
	    }

	    if (level > 0 && jc <= maxch) {
		section[jc] = file[ic]
		jc = jc + 1
	    }

	    ic = ic + 1
	}

	section[jc] = EOS

	if (level > 0) {
	    call sprintf (Memc[errmsg], SZ_LINE, badsect)
	    call pargstr (file)
	    call error (1, Memc[errmsg])
	}

	call sfree (sp)
	return (true)
end