]>
git.saurik.com Git - wxWidgets.git/blob - contrib/src/stc/scintilla/src/PropSet.cxx
d3dbabaf3b797067b03dfff1b74fa81272b6e5e5
1 // SciTE - Scintilla based Text Editor
2 // PropSet.cxx - a java style properties file module
3 // Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
4 // The License.txt file describes the conditions under which this software may be distributed.
6 // Maintain a dictionary of properties
17 bool EqualCaseInsensitive(const char *a
, const char *b
) {
19 return 0 == strcasecmp(a
, b
);
21 return 0 == stricmp(a
, b
);
23 return 0 == wxStricmp(a
, b
);
27 // Get a line of input. If end of line escaped with '\\' then continue reading.
28 static bool GetFullLine(const char *&fpc
, int &lenData
, char *s
, int len
) {
29 bool continuation
= true;
31 while ((len
> 1) && lenData
> 0) {
35 if ((ch
== '\r') || (ch
== '\n')) {
37 if ((lenData
> 0) && (ch
== '\r') && ((*fpc
) == '\n')) {
38 // munch the second half of a crlf
45 } else if ((ch
== '\\') && (lenData
> 0) && ((*fpc
== '\r') || (*fpc
== '\n'))) {
61 vals
= new char * [size
];
70 void PropSet::EnsureCanAddEntry() {
71 if (used
>= size
- 2) {
72 int newsize
= size
+ 10;
73 char **newvals
= new char * [newsize
];
75 for (int i
= 0; i
< used
; i
++) {
84 void PropSet::Set(const char *key
, const char *val
) {
86 for (int i
= 0; i
< used
; i
+= 2) {
87 if (EqualCaseInsensitive(vals
[i
], key
)) {
88 // Replace current value
89 delete [](vals
[i
+ 1]);
90 vals
[i
+ 1] = StringDup(val
);
95 vals
[used
++] = StringDup(key
);
96 vals
[used
++] = StringDup(val
);
99 void PropSet::Set(char *keyval
) {
100 char *eqat
= strchr(keyval
, '=');
103 Set(keyval
, eqat
+ 1);
108 SString
PropSet::Get(const char *key
) {
109 for (int i
= 0; i
< used
; i
+= 2) {
110 if (EqualCaseInsensitive(vals
[i
], key
)) {
115 // Failed here, so try in base property set
116 return superPS
->Get(key
);
122 int PropSet::GetInt(const char *key
, int defaultValue
) {
123 SString val
= Get(key
);
130 bool isprefix(const char *target
, const char *prefix
) {
131 while (*target
&& *prefix
) {
132 if (toupper(*target
) != toupper(*prefix
))
143 bool issuffix(const char *target
, const char *suffix
) {
144 int lentarget
= strlen(target
);
145 int lensuffix
= strlen(suffix
);
146 if (lensuffix
> lentarget
)
148 for (int i
= lensuffix
- 1; i
>= 0; i
--) {
149 if (toupper(target
[i
+ lentarget
- lensuffix
]) != toupper(suffix
[i
]))
155 SString
PropSet::GetWild(const char *keybase
, const char *filename
) {
156 for (int i
= 0; i
< used
; i
+= 2) {
157 if (isprefix(vals
[i
], keybase
)) {
158 char *orgkeyfile
= vals
[i
] + strlen(keybase
);
159 char *keyfile
= NULL
;
161 if (strstr(orgkeyfile
, "$(") == orgkeyfile
) {
162 char *cpendvar
= strchr(orgkeyfile
, ')');
164 int lenvar
= cpendvar
- orgkeyfile
- 2; // Subtract the $()
165 char *var
= static_cast<char *>(malloc(lenvar
+ 1));
166 strncpy(var
, orgkeyfile
+ 2, lenvar
);
168 SString s
= Get(var
);
170 keyfile
= strdup(s
.c_str());
173 char *keyptr
= keyfile
;
176 keyfile
= orgkeyfile
;
179 char *del
= strchr(keyfile
, ';');
181 del
= keyfile
+ strlen(keyfile
);
184 if (*keyfile
== '*') {
185 if (issuffix(filename
, keyfile
+ 1)) {
190 } else if (EqualCaseInsensitive(keyfile
, filename
)) {
202 if (EqualCaseInsensitive(vals
[i
], keybase
)) {
208 // Failed here, so try in base property set
209 return superPS
->GetWild(keybase
, filename
);
215 SString
PropSet::GetNewExpand(const char *keybase
, const char *filename
) {
216 char *base
= StringDup(GetWild(keybase
, filename
).c_str());
217 char *cpvar
= strstr(base
, "$(");
219 char *cpendvar
= strchr(cpvar
, ')');
221 int lenvar
= cpendvar
- cpvar
- 2; // Subtract the $()
222 char *var
= new char[lenvar
+ 1];
223 strncpy(var
, cpvar
+ 2, lenvar
);
225 SString val
= GetWild(var
, filename
);
226 int newlenbase
= strlen(base
) + val
.length() - lenvar
;
227 char *newbase
= new char[newlenbase
];
228 strncpy(newbase
, base
, cpvar
- base
);
229 strcpy(newbase
+ (cpvar
- base
), val
.c_str());
230 strcpy(newbase
+ (cpvar
- base
) + val
.length(), cpendvar
+ 1);
235 cpvar
= strstr(base
, "$(");
242 void PropSet::Clear() {
243 for (int i
= 0; i
< used
; i
++) {
250 void PropSet::ReadFromMemory(const char *data
, int len
) {
252 const char *pd
= data
;
254 while (GetFullLine(pd
, len
, linebuf
, sizeof(linebuf
))) {
255 if (isalpha(linebuf
[0]))
258 // If there is a final line:
259 if (isalpha(linebuf
[0]))
264 void PropSet::Read(const char *filename
) {
265 //printf("Opening properties <%s>\n", filename);
267 char propsData
[60000];
268 FILE *rcfile
= fopen(filename
, "rb");
270 int lenFile
= fread(propsData
, 1, sizeof(propsData
), rcfile
);
272 ReadFromMemory(propsData
, lenFile
);
274 //printf("Could not open <%s>\n", filename);
278 static bool iswordsep(char ch
, bool onlyLineEnds
) {
283 return ch
== '\r' || ch
== '\n';
286 // Creates an array that points into each word in the string and puts \0 terminators
288 static char **ArrayFromWordList(char *wordlist
, bool onlyLineEnds
= false) {
291 for (int j
= 0; wordlist
[j
]; j
++) {
292 if (!iswordsep(wordlist
[j
], onlyLineEnds
) && iswordsep(prev
, onlyLineEnds
))
296 char **keywords
= new char * [words
+ 1];
300 int len
= strlen(wordlist
);
301 for (int k
= 0; k
< len
; k
++) {
302 if (!iswordsep(wordlist
[k
], onlyLineEnds
)) {
304 keywords
[words
] = &wordlist
[k
];
312 keywords
[words
] = &wordlist
[len
];
317 void WordList::Clear() {
327 void WordList::Set(const char *s
) {
330 words
= ArrayFromWordList(list
, onlyLineEnds
);
333 char *WordList::Allocate(int size
) {
334 list
= new char[size
+ 1];
339 void WordList::SetFromAllocated() {
341 words
= ArrayFromWordList(list
, onlyLineEnds
);
344 // Shell sort based upon public domain C implementation by Raymond Gardner 1991
345 // Used here because of problems with mingw qsort.
346 static void SortWordList(char **words
, unsigned int len
) {
347 unsigned int gap
= len
/ 2;
350 unsigned int i
= gap
;
353 char **a
= words
+ j
;
358 if (strcmp(*a
, *b
) > 0) {
372 bool WordList::InList(const char *s
) {
376 for (int i
= 0; words
[i
][0]; i
++)
378 SortWordList(words
, len
);
379 for (unsigned int k
= 0; k
< (sizeof(starts
) / sizeof(starts
[0])); k
++)
381 for (int l
= len
- 1; l
>= 0; l
--) {
382 unsigned char indexChar
= words
[l
][0];
383 starts
[indexChar
] = l
;
386 unsigned char firstChar
= s
[0];
387 int j
= starts
[firstChar
];
389 while (words
[j
][0] == firstChar
) {
390 if (s
[1] == words
[j
][1]) {
391 const char *a
= words
[j
] + 1;
392 const char *b
= s
+ 1;
393 while (*a
&& *a
== *b
) {