matchdelim.pro
5.17 KB
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
;
;+
; NAME:
; MATCHDELIM
; PURPOSE:
; Match open/close delimiters in a string.
; CATEGORY:
; text/strings
; CALLING SEQUENCE:
; position = matchdelim( strn, [openpos])
; INPUTS:
; strn -- a string containing an open in
; delimiter (e.g. '{') in which you
; want to find the matching closing
; delimiter (e.g. '}')
; KEYWORD PARAMETERS:
; OPEN_DELIM -- A single character containing the opening in
; delimiter (e.g. '('). Default is '{'
; CLOSE_DELIM -- A single character containing the closing in
; delimiter (e.g. ')'). Default is '}'
; OUTPUTS:
; position -- returns the position in strn of the out
; closing delimiter, -1 if no closing found.
; openpos -- Set to a named variable to receive the out
; position of the first opening delimiter.
; Optional.
; COMMON BLOCKS:
; SIDE EFFECTS:
; NOTES:
; - Any pair of (nonidentical) characters can be used as
; delimiters.
; EXAMPLE:
; matchdelim('{one{two}}three') returns 9, the character just
; before 'three'.
; MODIFICATION HISTORY:
; $Id: matchdelim.pro,v 1.3 1996/06/14 20:00:27 mcraig Exp $
; $Log: matchdelim.pro,v $
; Revision 1.3 1996/06/14 20:00:27 mcraig
; Updated Copyright info.
;
; Revision 1.2 1996/05/09 00:22:17 mcraig
; Removed restriction that open delim must be first char. Added argument
; to allow for return of position of open delim.
;
; Revision 1.1 1996/01/31 18:41:06 mcraig
; Initial revision
;
; RELEASE:
; $Name: Rel_2_1_2 $
;
; COPYRIGHT:
; Copyright (C) 1996 The Regents of the University of California, All
; Rights Reserved. Written by Matthew W. Craig.
; See the file COPYRIGHT for restrictions on distrubting this code.
; This code comes with absolutely NO warranty; see DISCLAIMER for details.
;-
;
FUNCTION Matchdelim, InString, OpenPos, $
OPEN_DELIM=OpenDelim, $
CLOSE_DELIM=CloseDelim, $
HELP=Help
; Return to caller if error.
On_error, 2
IF (n_params() LT 1) OR keyword_set(Help) THEN BEGIN
offset = ' '
print, offset+'Match open/close delimiters in a string.'
print, offset+'position = matchdelim( strn, [openpos])'
print, offset+'Inputs:'
print, offset+offset+'strn -- a string containing an open in'
print, offset+offset+" delimiter (e.g. '{') in which you "
print, offset+offset+' want to find the matching closing '
print, offset+offset+" delimiter (e.g. '}')"
print, offset+'Keywords:'
print, offset+offset+'OPEN_DELIM -- A single character containing the opening in'
print, offset+offset+" delimiter (e.g. '('). Default is '{'"
print, offset+offset+'CLOSE_DELIM -- A single character containing the closing in'
print, offset+offset+" delimiter (e.g. ')'). Default is '}'"
print, offset+'Outputs:'
print, offset+offset+'position -- returns the position in strn of the out'
print, offset+offset+' closing delimiter, -1 if no closing found.'
print, offset+offset+'openpos -- Set to a named variable to receive the out'
print, offset+offset+' position of the first opening delimiter.'
print, offset+offset+' Optional.'
print, offset+'Example:'
print, offset+offset+"matchdelim('a{one{two}}three') returns 10, the character just"
print, offset+offset+" before 'three'. "
print, offset+offset+$
"a=matchdelim('aaa[bbb(ccc)]ddd[eee]',f,OP='[',CL=']')"
print, offset+offset+" returns a=12 (just before ddd), f=3 "+$
"(just before bbb)."
return, -1
ENDIF
; Set default delimiters.
IF n_elements(OpenDelim) EQ 0 THEN OpenDelim = '{'
IF n_elements(CloseDelim) EQ 0 THEN CloseDelim = '}'
; Make sure InString has more than 1 character.
length = strlen(InString)
IF (length LE 1) THEN return,-1
; Return if no open delimiter
OpenPos = strpos( InString, OpenDelim )
IF (OpenPos EQ -1) THEN BEGIN
print, 'Error: No opening delimiter'
return, -1
ENDIF
; Convert strings to array of integers to speed processing.
OpenDelim = fix((byte(OpenDelim))(0))
CloseDelim = fix((byte(CloseDelim))(0))
TmpStr = fix(byte(strmid( InString, OpenPos, length)))
; Leave the -1* in here. This forces conversion from BYTE to INTEGER,
; necessary because there are no negative BYTEs.
TmpStr = (TmpStr EQ OpenDelim) $
-1*(TmpStr EQ CloseDelim)
length = n_elements(TmpStr)
; Initialize count of number of delimiters. We've found one, the
; first opener.
BraceCnt = 1
i=0
WHILE (BraceCnt GT 0) AND (i LT length-1) DO BEGIN
i = i+1
BraceCnt = BraceCnt + TmpStr(i)
ENDWHILE
i = i + OpenPos
IF (BraceCnt GT 0) THEN i = -1
return, i
END