1 //
2 // ParsedString.cc
3 //
4 // ParsedString: Contains a string. The string my contain $var, ${var}, $(var)
5 // `filename`. The get method will expand those using the
6 // dictionary given in argument.
7 //
8 // Part of the ht://Dig package <http://www.htdig.org/>
9 // Copyright (c) 1999-2004 The ht://Dig Group
10 // For copyright details, see the file COPYING in your distribution
11 // or the GNU Library General Public License (LGPL) version 2 or later
12 // <http://www.gnu.org/copyleft/lgpl.html>
13 //
14 // $Id: ParsedString.cc,v 1.9 2004/05/28 13:15:21 lha Exp $
15 //
16
17 #ifdef HAVE_CONFIG_H
18 #include "htconfig.h"
19 #endif /* HAVE_CONFIG_H */
20
21 #include "ParsedString.h"
22
23 #include <ctype.h>
24 #include <stdio.h>
25
26
27 //*****************************************************************************
28 // ParsedString::ParsedString()
29 //
ParsedString()30 ParsedString::ParsedString()
31 {
32 }
33
34
35 //*****************************************************************************
36 //
ParsedString(const String & s)37 ParsedString::ParsedString(const String& s)
38 {
39 value = s;
40 }
41
42
43 //*****************************************************************************
44 // ParsedString::~ParsedString()
45 //
~ParsedString()46 ParsedString::~ParsedString()
47 {
48 }
49
50
51 //*****************************************************************************
52 //
53 void
set(const String & str)54 ParsedString::set(const String& str)
55 {
56 value = str;
57 }
58
59
60 //*****************************************************************************
61 // Return a fully parsed string.
62 //
63 // Allowed syntax:
64 // $var
65 // ${var}
66 // $(var)
67 // `filename`
68 //
69 // The filename can also contain variables
70 //
71 const String
get(const Dictionary & dict) const72 ParsedString::get(const Dictionary &dict) const
73 {
74 String variable;
75 String parsed;
76 ParsedString *temp;
77 const char *str = value.get();
78 char delim = ' ';
79 int need_delim = 0;
80
81 while (*str)
82 {
83 if (*str == '$')
84 {
85 //
86 // A dollar sign starts a variable.
87 //
88 str++;
89 need_delim = 1;
90 if (*str == '{')
91 delim = '}';
92 else if (*str == '(')
93 delim = ')';
94 else
95 need_delim = 0;
96 if (need_delim)
97 str++;
98 variable.trunc();
99 while (isalnum(*str) || *str == '_' || *str == '-')
100 {
101 variable << *str++;
102 }
103 if (*str)
104 {
105 if (need_delim && *str == delim)
106 {
107 //
108 // Found end of variable
109 //
110 temp = (ParsedString *) dict[variable];
111 if (temp)
112 parsed << temp->get(dict);
113 str++;
114 }
115 else if (need_delim)
116 {
117 //
118 // Error. Probably an illegal value in the name We'll
119 // assume the variable ended here.
120 //
121 temp = (ParsedString *) dict[variable];
122 if (temp)
123 parsed << temp->get(dict);
124 }
125 else
126 {
127 //
128 // This variable didn't have a delimiter.
129 //
130 temp = (ParsedString *) dict[variable];
131 if (temp)
132 parsed << temp->get(dict);
133 }
134 }
135 else
136 {
137 //
138 // End of string reached. We'll assume that this is also
139 // the end of the variable
140 //
141 temp = (ParsedString *) dict[variable];
142 if (temp)
143 parsed << temp->get(dict);
144 }
145 }
146 else if (*str == '`')
147 {
148 //
149 // Back-quote delimits a filename which we need to insert
150 //
151 str++;
152 variable.trunc();
153 while (*str && *str != '`')
154 {
155 variable << *str++;
156 }
157 if (*str == '`')
158 str++;
159 ParsedString filename(variable);
160 variable.trunc();
161 getFileContents(variable, filename.get(dict));
162 parsed << variable;
163 }
164 else if (*str == '\\')
165 {
166 //
167 // Backslash escapes the next character
168 //
169 str++;
170 if (*str)
171 parsed << *str++;
172 }
173 else
174 {
175 //
176 // Normal character
177 //
178 parsed << *str++;
179 }
180 }
181 return parsed;
182 }
183
184
185 void
getFileContents(String & str,const String & filename) const186 ParsedString::getFileContents(String &str, const String& filename) const
187 {
188 FILE *fl = fopen(filename, "r");
189 char buffer[1000];
190
191 if (!fl)
192 return;
193 while (fgets(buffer, sizeof(buffer), fl))
194 {
195 String s(buffer);
196 s.chop("\r\n\t ");
197 str << s << ' ';
198 }
199 str.chop(1);
200 fclose(fl);
201 }
202
203