]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/PropSet.cxx
7e2a906a478902d1cd2f399c9851df8ede19bd99
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;
30 while ((len
> 1) && lenData
> 0) {
34 if ((ch
== '\r') || (ch
== '\n')) {
36 if ((lenData
> 0) && (ch
== '\r') && ((*fpc
) == '\n')) {
37 // munch the second half of a crlf
44 } else if ((ch
== '\\') && (lenData
> 0) && ((*fpc
== '\r') || (*fpc
== '\n'))) {
59 vals
= new char * [size
];
68 void PropSet::EnsureCanAddEntry() {
69 if (used
>= size
- 2) {
70 int newsize
= size
+ 10;
71 char **newvals
= new char * [newsize
];
73 for (int i
= 0; i
< used
; i
++) {
82 void PropSet::Set(const char *key
, const char *val
) {
84 for (int i
= 0; i
< used
; i
+= 2) {
85 if (EqualCaseInsensitive(vals
[i
], key
)) {
86 // Replace current value
87 delete [](vals
[i
+ 1]);
88 vals
[i
+ 1] = StringDup(val
);
93 vals
[used
++] = StringDup(key
);
94 vals
[used
++] = StringDup(val
);
97 void PropSet::Set(char *keyval
) {
98 char *eqat
= strchr(keyval
, '=');
101 Set(keyval
, eqat
+ 1);
106 SString
PropSet::Get(const char *key
) {
107 for (int i
= 0; i
< used
; i
+= 2) {
108 if (EqualCaseInsensitive(vals
[i
], key
)) {
113 // Failed here, so try in base property set
114 return superPS
->Get(key
);
120 int PropSet::GetInt(const char *key
, int defaultValue
) {
121 SString val
= Get(key
);
123 return Get(key
).value();
128 bool isprefix(const char *target
, const char *prefix
) {
129 while (*target
&& *prefix
) {
130 if (toupper(*target
) != toupper(*prefix
))
141 bool issuffix(const char *target
, const char *suffix
) {
142 int lentarget
= strlen(target
);
143 int lensuffix
= strlen(suffix
);
144 if (lensuffix
> lentarget
)
146 for (int i
= lensuffix
- 1; i
>= 0; i
--) {
147 if (toupper(target
[i
+ lentarget
- lensuffix
]) != toupper(suffix
[i
]))
153 SString
PropSet::GetWild(const char *keybase
, const char *filename
) {
154 for (int i
= 0; i
< used
; i
+= 2) {
155 if (isprefix(vals
[i
], keybase
)) {
156 char *orgkeyfile
= vals
[i
] + strlen(keybase
);
157 char *keyfile
= NULL
;
159 if (strstr(orgkeyfile
, "$(") == orgkeyfile
) {
160 char *cpendvar
= strchr(orgkeyfile
, ')');
162 int lenvar
= cpendvar
- orgkeyfile
- 2; // Subtract the $()
163 char *var
= static_cast<char *>(malloc(lenvar
+ 1));
164 strncpy(var
, orgkeyfile
+ 2, lenvar
);
166 SString s
= Get(var
);
168 keyfile
= strdup(s
.c_str());
171 char *keyptr
= keyfile
;
174 keyfile
= orgkeyfile
;
177 char *del
= strchr(keyfile
, ';');
179 del
= keyfile
+ strlen(keyfile
);
182 if (*keyfile
== '*') {
183 if (issuffix(filename
, keyfile
+ 1)) {
188 } else if (EqualCaseInsensitive(keyfile
, filename
)) {
200 if (EqualCaseInsensitive(vals
[i
], keybase
)) {
206 // Failed here, so try in base property set
207 return superPS
->GetWild(keybase
, filename
);
213 SString
PropSet::GetNewExpand(const char *keybase
, const char *filename
) {
214 char *base
= StringDup(GetWild(keybase
, filename
).c_str());
215 char *cpvar
= strstr(base
, "$(");
217 char *cpendvar
= strchr(cpvar
, ')');
219 int lenvar
= cpendvar
- cpvar
- 2; // Subtract the $()
220 char *var
= new char[lenvar
+ 1];
221 strncpy(var
, cpvar
+ 2, lenvar
);
223 SString val
= GetWild(var
, filename
);
224 int newlenbase
= strlen(base
) + val
.length() - lenvar
;
225 char *newbase
= new char[newlenbase
];
226 strncpy(newbase
, base
, cpvar
- base
);
227 strcpy(newbase
+ (cpvar
- base
), val
.c_str());
228 strcpy(newbase
+ (cpvar
- base
) + val
.length(), cpendvar
+ 1);
233 cpvar
= strstr(base
, "$(");
240 void PropSet::Clear() {
241 for (int i
= 0; i
< used
; i
++) {
248 void PropSet::ReadFromMemory(const char *data
, int len
) {
250 const char *pd
= data
;
252 while (GetFullLine(pd
, len
, linebuf
, sizeof(linebuf
))) {
253 if (isalpha(linebuf
[0]))
259 void PropSet::Read(const char *filename
) {
260 //printf("Opening properties <%s>\n", filename);
262 char propsData
[60000];
263 FILE *rcfile
= fopen(filename
, "rb");
265 int lenFile
= fread(propsData
, 1, sizeof(propsData
), rcfile
);
267 ReadFromMemory(propsData
, lenFile
);
269 //printf("Could not open <%s>\n", filename);
273 static bool iswordsep(char ch
, bool onlyLineEnds
) {
278 return ch
== '\r' || ch
== '\n';
281 // Creates an array that points into each word in the string and puts \0 terminators
283 static char **ArrayFromWordList(char *wordlist
, bool onlyLineEnds
= false) {
286 for (int j
= 0; wordlist
[j
]; j
++) {
287 if (!iswordsep(wordlist
[j
], onlyLineEnds
) && iswordsep(prev
, onlyLineEnds
))
291 char **keywords
= new char * [words
+ 1];
295 int len
= strlen(wordlist
);
296 for (int k
= 0; k
< len
; k
++) {
297 if (!iswordsep(wordlist
[k
], onlyLineEnds
)) {
299 keywords
[words
] = &wordlist
[k
];
307 keywords
[words
] = &wordlist
[len
];
312 void WordList::Clear() {
322 void WordList::Set(const char *s
) {
325 words
= ArrayFromWordList(list
, onlyLineEnds
);
328 char *WordList::Allocate(int size
) {
329 list
= new char[size
+ 1];
334 void WordList::SetFromAllocated() {
336 words
= ArrayFromWordList(list
, onlyLineEnds
);
339 // Shell sort based upon public domain C implementation by Raymond Gardner 1991
340 // Used here because of problems with mingw qsort.
341 static void SortWordList(char **words
, unsigned int len
) {
342 unsigned int gap
= len
/ 2;
345 unsigned int i
= gap
;
348 char **a
= words
+ j
;
353 if (strcmp(*a
, *b
) > 0) {
367 bool WordList::InList(const char *s
) {
371 for (int i
= 0; words
[i
][0]; i
++)
373 SortWordList(words
, len
);
374 for (int k
= 0; k
< (sizeof(starts
) / sizeof(starts
[0])); k
++)
376 for (int l
= len
- 1; l
>= 0; l
--) {
377 unsigned char indexChar
= words
[l
][0];
378 starts
[indexChar
] = l
;
381 unsigned char firstChar
= s
[0];
382 int j
= starts
[firstChar
];
384 while (words
[j
][0] == firstChar
) {
385 if (s
[1] == words
[j
][1]) {
386 const char *a
= words
[j
] + 1;
387 const char *b
= s
+ 1;
388 while (*a
&& *a
== *b
) {