aboutsummaryrefslogtreecommitdiff
path: root/sys/imio/imparse.x
blob: cc98070db2c467d5c77677a418187a54bf460687 (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
# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.

include	<syserr.h>
include	<ctype.h>

# IMPARSE -- Parse an image specification into the cluster name, cluster index,
# cluster size, kernel section, and image section fields.
#
#	Syntax:		cluster[cl_index/cl_size][ksection][section]
#
# where all fields are optional except the cluster name.  In the limiting case
# (cl_size = 1) the cluster name and image name are the same.  CL_INDEX and
# CL_SIZE must be simple nonnegative decimal integer constants, if given.  The
# [ character must be escaped to be included in the filename of the cluster.
#
# NOTE -- The image specification syntax is not frozen and further changes
# are likely.  Use of this routine outside IMIO is not recommended as the
# calling sequence may change.  Use imgname and imgsection instead.

procedure imparse (imspec, cluster, sz_cluster, ksection, sz_ksection,
	section, sz_section, cl_index, cl_size)

char	imspec[ARB]		# full image specification
char	cluster[ARB]		# receives cluster name
int	sz_cluster		# max chars in cluster name
char	ksection[ARB]		# receives kernel section
int	sz_ksection		# max chars in kernel section name
char	section[ARB]		# receives image section
int	sz_section		# max chars in image section name
int	cl_index		# receives cluster index (default -1)
int	cl_size			# receives cluster size (default -1)

pointer	sp, cp, secbuf
int	ip, op, lbrack, level, ch, n
bool	is_ksection, sect_out, ksect_out
int	stridx()
errchk	syserrs

begin
	call smark (sp)
	call salloc (secbuf, SZ_LINE, TY_CHAR)

	ip = 1
	op = 1

	# Extract cluster name.  The first (unescaped) [ marks the start of
	# either the cl_index subscript or a section field.

	for (ch=imspec[ip];  ch != EOS && ch != '[';  ch=imspec[ip]) {
	    if (ch == '\\' && imspec[ip+1] == '[') {
		cluster[op] = '\\'
		op = op + 1
		cluster[op] = '['
		ip = ip + 1
	    } else
		cluster[op] = ch

	    op = min (sz_cluster, op + 1)
	    ip = ip + 1
	}

	cluster[op] = EOS
	ksection[1] = EOS
	section[1]  = EOS
	lbrack      = ip
	cl_index    = -1
	cl_size     = -1

	if (ch == EOS) {
	    call sfree (sp)
	    return
	}

	# If we have a [...] field, determine whether it is a cl_index
	# subscript or a kernel or image section.  A cl_index subscript is
	# anything with the syntax [ddd] or [ddd/ddd]; anything else is a
	# kernel or image section.

	ip = ip + 1
	n = -1

	for (ch=imspec[ip];  ch != EOS;  ch=imspec[ip]) {
	    if (IS_DIGIT(ch)) {
		if (n < 0)
		    n = 0
		n = (n * 10) + TO_INTEG(ch)
	    } else if (ch == '/') {
		cl_index = max (n, 1)
		n = -1
	    } else if (ch == ']') {
		ip = ip + 1
		break
	    } else {
		# Not a cl_index subscript; must be a section.
		ip = lbrack
		n = -1
		break
	    }
	    ip = ip + 1
	}

	if (cl_index < 0)
	    cl_index = n
	else
	    cl_size = n

	# The rest of the input string consists of the kernel and image
	# sections, if any.

	sect_out = false
	ksect_out = false

	while (imspec[ip] == '[') {
	    is_ksection = false
	    cp = secbuf
	    level = 0

	    for (ch=imspec[ip];  ch != EOS;  ch=imspec[ip]) {
		if (ch == '[')
		    level = level + 1
		else if (ch == ']')
		    level = level - 1
		else if (!is_ksection)
		    if (stridx (imspec[ip], " 0123456789+-:*,") == 0)
			is_ksection = true

		Memc[cp] = ch
		cp = cp + 1
		ip = ip + 1

		if (level == 0)
		    break
	    }
	    Memc[cp] = EOS

	    if (level != 0)
		call syserrs (SYS_IMSYNSEC, imspec)
	    if (is_ksection) {
		if (ksect_out)
		    call syserrs (SYS_IMSYNSEC, imspec)
		call strcpy (Memc[secbuf], ksection, sz_ksection)
		ksect_out = true
	    } else {
		if (sect_out)
		    call syserrs (SYS_IMSYNSEC, imspec)
		call strcpy (Memc[secbuf], section, sz_section)
		sect_out = true
	    }

	    while (imspec[ip] != EOS && imspec[ip] != '[')
		ip = ip + 1
	}

	call sfree (sp)
end