Chameleon Applications

Chameleon Applications Svn Source Tree

Root/branches/iFabio/i386/libsaio/stringTable.c

Source at commit 214 created 13 years 5 months ago.
By ifabio, update to chameleon trunk 630, and now the pakage folder is the same as blackosx branch, also add Icon "building" into buildpkg script, and add mint theme info into the English localizable.strings.
1/*
2 * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 2.0 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24/*
25 * Copyright 1993 NeXT, Inc.
26 * All rights reserved.
27 */
28
29#include "bootstruct.h"
30#include "libsaio.h"
31#include "xml.h"
32
33extern char *Language;
34extern char *LoadableFamilies;
35
36bool sysConfigValid;
37
38/*
39 * Compare a string to a key with quoted characters
40 */
41static inline int
42keyncmp(const char *str, const char *key, int n)
43{
44 int c;
45 while (n--) {
46c = *key++;
47if (c == '\\') {
48 switch(c = *key++) {
49 case 'n':
50c = '\n';
51break;
52 case 'r':
53c = '\r';
54break;
55 case 't':
56c = '\t';
57break;
58 default:
59break;
60 }
61} else if (c == '\"') {
62 /* Premature end of key */
63 return 1;
64}
65if (c != *str++) {
66 return 1;
67}
68 }
69 return 0;
70}
71
72#if UNUSED
73
74static void eatThru(char val, const char **table_p)
75{
76register const char *table = *table_p;
77register bool found = false;
78
79while (*table && !found)
80{
81if (*table == '\\') table += 2;
82else
83{
84if (*table == val) found = true;
85table++;
86}
87}
88*table_p = table;
89}
90
91/* Remove key and its associated value from the table. */
92
93bool
94removeKeyFromTable(const char *key, char *table)
95{
96 register int len;
97 register char *tab;
98 char *buf;
99
100 len = strlen(key);
101 tab = (char *)table;
102 buf = (char *)malloc(len + 3);
103
104 sprintf(buf, "\"%s\"", key);
105 len = strlen(buf);
106
107 while(*tab) {
108 if(strncmp(buf, tab, len) == 0) {
109 char c;
110
111 while((c = *(tab + len)) != ';') {
112 if(c == 0) {
113 len = -1;
114 goto out;
115 }
116 len++;
117 }
118 len++;
119 if(*(tab + len) == '\n') len++;
120 goto out;
121 }
122 tab++;
123 }
124 len = -1;
125out:
126 free(buf);
127
128 if(len == -1) return false;
129
130 while((*tab = *(tab + len))) {
131 tab++;
132 }
133
134 return true;
135}
136
137char *
138newStringFromList(
139 char **list,
140 int *size
141)
142{
143 char *begin = *list, *end;
144 char *newstr;
145 int newsize = *size;
146 int bufsize;
147
148 while (*begin && newsize && isspace(*begin)) {
149begin++;
150newsize--;
151 }
152 end = begin;
153 while (*end && newsize && !isspace(*end)) {
154end++;
155newsize--;
156 }
157 if (begin == end)
158return 0;
159 bufsize = end - begin + 1;
160 newstr = malloc(bufsize);
161 strlcpy(newstr, begin, bufsize);
162 *list = end;
163 *size = newsize;
164 return newstr;
165}
166
167#endif
168
169/*
170 * compress == compress escaped characters to one character
171 */
172int stringLength(const char *table, int compress)
173{
174int ret = 0;
175
176while (*table)
177{
178if (*table == '\\')
179{
180table += 2;
181ret += 1 + (compress ? 0 : 1);
182}
183else
184{
185if (*table == '\"') return ret;
186ret++;
187table++;
188}
189}
190return ret;
191}
192
193
194bool getValueForConfigTableKey(config_file_t *config, const char *key, const char **val, int *size)
195{
196if (config->dictionary != 0 ) {
197// Look up key in XML dictionary
198TagPtr value;
199value = XMLGetProperty(config->dictionary, key);
200if (value != 0) {
201if (value->type != kTagTypeString) {
202error("Non-string tag '%s' found in config file\n",
203 key);
204return false;
205}
206*val = value->string;
207*size = strlen(value->string);
208return true;
209}
210} else {
211
212// Legacy plist-style table
213
214}
215
216return false;
217}
218
219#if UNUSED
220
221/*
222 * Returns a new malloc'ed string if one is found
223 * in the string table matching 'key'. Also translates
224 * \n escapes in the string.
225 */
226char *newStringForStringTableKey(
227char *table,
228char *key,
229config_file_t *config
230)
231{
232 const char *val;
233 char *newstr, *p;
234 int size;
235
236 if (getValueForConfigTableKey(config, key, &val, &size)) {
237newstr = (char *)malloc(size+1);
238for (p = newstr; size; size--, p++, val++) {
239 if ((*p = *val) == '\\') {
240switch (*++val) {
241case 'r':
242 *p = '\r';
243 break;
244case 'n':
245 *p = '\n';
246 break;
247case 't':
248 *p = '\t';
249 break;
250default:
251 *p = *val;
252 break;
253}
254size--;
255 }
256}
257*p = '\0';
258return newstr;
259 } else {
260return 0;
261 }
262}
263
264#endif
265
266char *
267newStringForKey(char *key, config_file_t *config)
268{
269 const char *val;
270 char *newstr;
271 int size;
272
273 if (getValueForKey(key, &val, &size, config) && size) {
274newstr = (char *)malloc(size + 1);
275strlcpy(newstr, val, size + 1);
276return newstr;
277 } else {
278return 0;
279 }
280}
281
282/* parse a command line
283 * in the form: [<argument> ...] [<option>=<value> ...]
284 * both <option> and <value> must be either composed of
285 * non-whitespace characters, or enclosed in quotes.
286 */
287
288static const char *getToken(const char *line, const char **begin, int *len)
289{
290 if (*line == '\"') {
291*begin = ++line;
292while (*line && *line != '\"')
293 line++;
294*len = line++ - *begin;
295 } else {
296*begin = line;
297while (*line && !isspace(*line) && *line != '=')
298 line++;
299*len = line - *begin;
300 }
301 return line;
302}
303
304bool getValueForBootKey(const char *line, const char *match, const char **matchval, int *len)
305{
306 const char *key, *value;
307 int key_len, value_len;
308 bool retval = false;
309
310 while (*line) {
311/* look for keyword or argument */
312while (isspace(*line)) line++;
313
314/* now look for '=' or whitespace */
315line = getToken(line, &key, &key_len);
316/* line now points to '=' or space */
317if (*line && !isspace(*line)) {
318 line = getToken(++line, &value, &value_len);
319} else {
320 value = line;
321 value_len = 0;
322}
323if ((strlen(match) == key_len)
324 && strncmp(match, key, key_len) == 0) {
325 *matchval = value;
326 *len = value_len;
327 retval = true;
328 /* Continue to look for this key; last one wins. */
329}
330 }
331 return retval;
332}
333
334/* Return NULL if no option has been successfully retrieved, or the string otherwise */
335const char * getStringForKey(const char * key, config_file_t *config)
336{
337 static const char* value =0;
338 int len=0;
339 if(!getValueForKey(key, &value, &len, config)) value = 0;
340 return value;
341}
342
343
344/* Returns TRUE if a value was found, FALSE otherwise.
345 * The boolean value of the key is stored in 'val'.
346 */
347
348bool getBoolForKey( const char *key, bool *result_val, config_file_t *config )
349{
350 const char *key_val;
351 int size;
352
353 if (getValueForKey(key, &key_val, &size, config)) {
354 if ( (size >= 1) && (key_val[0] == 'Y' || key_val[0] == 'y') ) {
355 *result_val = true;
356 } else {
357 *result_val = false;
358 }
359 return true;
360 }
361 return false;
362}
363
364bool getIntForKey( const char *key, int *value, config_file_t *config )
365{
366 const char *val;
367 int size, sum;
368 bool negative = false;
369
370 if (getValueForKey(key, &val, &size, config))
371{
372if ( size )
373{
374if (*val == '-')
375{
376negative = true;
377val++;
378size--;
379}
380
381for (sum = 0; size > 0; size--)
382{
383if (*val < '0' || *val > '9')
384return false;
385
386sum = (sum * 10) + (*val++ - '0');
387}
388
389if (negative)
390sum = -sum;
391
392*value = sum;
393return true;
394}
395}
396 return false;
397}
398
399/*
400 *
401 */
402
403bool getDimensionForKey( const char *key, unsigned int *value, config_file_t *config, unsigned int dimension_max, unsigned int object_size )
404{
405const char *val;
406
407 int size = 0;
408int sum = 0;
409
410bool negative = false;
411bool percentage = false;
412
413 if (getValueForKey(key, &val, &size, config))
414{
415if ( size )
416{
417if (*val == '-')
418{
419negative = true;
420val++;
421size--;
422}
423
424if (val[size-1] == '%')
425{
426percentage = true;
427size--;
428}
429
430// convert string to integer
431for (sum = 0; size > 0; size--)
432{
433if (*val < '0' || *val > '9')
434return false;
435
436sum = (sum * 10) + (*val++ - '0');
437}
438
439if (percentage)
440sum = ( dimension_max * sum ) / 100;
441
442// calculate offset from opposite origin
443if (negative)
444sum = ( ( dimension_max - object_size ) - sum );
445
446} else {
447
448// null value calculate center
449sum = ( dimension_max - object_size ) / 2;
450
451}
452
453*value = (uint16_t) sum;
454return true;
455}
456
457// key not found
458 return false;
459}
460
461/*
462 *get color value from plist format #RRGGBB
463 */
464
465bool getColorForKey( const char *key, unsigned int *value, config_file_t *config )
466{
467 const char *val;
468 int size;
469
470 if (getValueForKey(key, &val, &size, config))
471{
472if (*val == '#')
473{
474 val++;
475*value = strtol(val, NULL, 16);
476return true;
477 }
478 }
479 return false;
480}
481
482bool getValueForKey( const char *key, const char **val, int *size, config_file_t *config )
483{
484 const char *overrideVal;
485 int overrideSize;
486 bool override, ret;
487
488 if (getValueForBootKey(bootArgs->CommandLine, key, val, size))
489 return true;
490
491 ret = getValueForConfigTableKey(config, key, val, size);
492
493 // Try to find alternate keys in bootInfo->overrideConfig
494 // and prefer its values with the exceptions for
495 // "Kernel"="mach_kernel" and "Kernel Flags"="".
496
497 if (config->canOverride)
498 {
499 if (getValueForConfigTableKey(&bootInfo->overrideConfig, key, &overrideVal, &overrideSize))
500 {
501 override = true;
502
503 if (ret && (strcmp(key, "Kernel") == 0) && (strcmp(overrideVal, "mach_kernel") == 0))
504 override = false;
505
506 if (ret && (strcmp(key, "Kernel Flags") == 0) && (overrideSize == 0))
507 override = false;
508
509 if (override)
510 {
511 *val = overrideVal;
512 *size = overrideSize;
513 return true;
514 }
515 }
516 }
517
518 return ret;
519}
520
521
522#if UNUSED
523void
524printSystemConfig(char *p1)
525{
526 char *p2 = p1, tmp;
527
528 while (*p1 != '\0') {
529while (*p2 != '\0' && *p2 != '\n') p2++;
530tmp = *p2;
531*p2 = '\0';
532printf("%s\n", p1);
533*p2 = tmp;
534if (tmp == '\0') break;
535p1 = ++p2;
536 }
537}
538#endif
539
540//==========================================================================
541// ParseXMLFile
542// Modifies the input buffer.
543// Expects to see one dictionary in the XML file.
544// Puts the first dictionary it finds in the
545// tag pointer and returns 0, or returns -1 if not found
546// (and does not modify dict pointer).
547// Prints an error message if there is a parsing error.
548//
549int ParseXMLFile( char * buffer, TagPtr * dict )
550{
551 long length, pos;
552 TagPtr tag;
553 pos = 0;
554 char *configBuffer;
555
556 configBuffer = malloc(strlen(buffer)+1);
557 strcpy(configBuffer, buffer);
558
559 while (1)
560 {
561 length = XMLParseNextTag(configBuffer + pos, &tag);
562 if (length == -1) break;
563
564 pos += length;
565
566 if (tag == 0) continue;
567 if (tag->type == kTagTypeDict) break;
568
569 XMLFreeTag(tag);
570 }
571 free(configBuffer);
572 if (length < 0) {
573 error ("Error parsing plist file\n");
574 return -1;
575 }
576 *dict = tag;
577 return 0;
578}
579
580/* loadConfigFile
581 *
582 * Returns 0 - successful.
583 * -1 - unsuccesful.
584 */
585int loadConfigFile (const char *configFile, config_file_t *config)
586{
587int fd, count;
588
589if ((fd = open_bvdev("bt(0,0)", configFile, 0)) < 0) {
590return -1;
591}
592// read file
593count = read(fd, config->plist, IO_CONFIG_DATA_SIZE);
594close(fd);
595
596// build xml dictionary
597ParseXMLFile(config->plist, &config->dictionary);
598return 0;
599}
600
601
602/* loadSystemConfig
603 *
604 * Returns 0 - successful.
605 * -1 - unsuccesful.
606 */
607int loadSystemConfig(config_file_t *config)
608{
609char *dirspec[] = {
610"/Extra/com.apple.Boot.plist",
611"bt(0,0)/Extra/com.apple.Boot.plist",
612"/Library/Preferences/SystemConfiguration/com.apple.Boot.plist",
613"/com.apple.boot.P/Library/Preferences/SystemConfiguration/com.apple.Boot.plist",
614"/com.apple.boot.R/Library/Preferences/SystemConfiguration/com.apple.Boot.plist",
615"/com.apple.boot.S/Library/Preferences/SystemConfiguration/com.apple.Boot.plist"
616};
617
618int i, fd, count, ret=-1;
619
620for(i = 0; i< sizeof(dirspec)/sizeof(dirspec[0]); i++)
621{
622if ((fd = open(dirspec[i], 0)) >= 0)
623{
624// read file
625count = read(fd, config->plist, IO_CONFIG_DATA_SIZE);
626close(fd);
627
628// build xml dictionary
629ParseXMLFile(config->plist, &config->dictionary);
630sysConfigValid = true;
631ret=0;
632
633// enable canOverride flag
634config->canOverride = true;
635
636break;
637}
638}
639return ret;
640}
641
642/* loadOverrideConfig
643 *
644 * Returns 0 - successful.
645 * -1 - unsuccesful.
646 */
647int loadOverrideConfig(config_file_t *config)
648{
649char *dirspec[] = {
650"rd(0,0)/Extra/com.apple.Boot.plist",
651"/Extra/com.apple.Boot.plist",
652"/Library/Preferences/SystemConfiguration/com.apple.Boot.plist",
653"/com.apple.boot.P/Library/Preferences/SystemConfiguration/com.apple.Boot.plist",
654"/com.apple.boot.R/Library/Preferences/SystemConfiguration/com.apple.Boot.plist",
655"/com.apple.boot.S/Library/Preferences/SystemConfiguration/com.apple.Boot.plist"
656};
657
658int i, fd, count, ret=-1;
659
660for(i = 0; i< sizeof(dirspec)/sizeof(dirspec[0]); i++)
661{
662if ((fd = open(dirspec[i], 0)) >= 0)
663{
664// read file
665count = read(fd, config->plist, IO_CONFIG_DATA_SIZE);
666close(fd);
667
668// build xml dictionary
669ParseXMLFile(config->plist, &config->dictionary);
670sysConfigValid = true;
671ret=0;
672break;
673}
674}
675return ret;
676}
677
678/* loadHelperConfig
679 *
680 * Returns 0 - successful.
681 * -1 - unsuccesful.
682 */
683int loadHelperConfig(config_file_t *config)
684{
685char *dirspec[] = {
686"/com.apple.boot.P/Library/Preferences/SystemConfiguration/com.apple.Boot.plist",
687"/com.apple.boot.R/Library/Preferences/SystemConfiguration/com.apple.Boot.plist",
688"/com.apple.boot.S/Library/Preferences/SystemConfiguration/com.apple.Boot.plist"
689};
690
691int i, fd, count, ret=-1;
692
693for(i = 0; i< sizeof(dirspec)/sizeof(dirspec[0]); i++)
694{
695if ((fd = open(dirspec[i], 0)) >= 0)
696{
697// read file
698count = read(fd, config->plist, IO_CONFIG_DATA_SIZE);
699close(fd);
700
701// build xml dictionary
702ParseXMLFile(config->plist, &config->dictionary);
703sysConfigValid = true;
704ret=0;
705break;
706}
707}
708return ret;
709}
710
711char * newString(const char * oldString)
712{
713 if ( oldString )
714 return strcpy(malloc(strlen(oldString)+1), oldString);
715 else
716 return NULL;
717}
718
719/*
720 * Extracts the next argument from the command line, double quotes are allowed here.
721 */
722char * getNextArg(char ** argPtr, char * val)
723{
724 char * ptr = *argPtr;
725 const char * strStart;
726 int len = 0;
727 bool isQuoted = false;
728
729 *val = '\0';
730
731 // Scan for the next non-whitespace character.
732 while ( *ptr && (*ptr == ' ' || *ptr == '=') )
733 {
734 ptr++;
735 }
736
737 strStart = ptr;
738
739 // Skip the leading double quote character.
740 if (*ptr == '\"')
741 {
742 isQuoted = true;
743 ptr++;
744 strStart++;
745 }
746
747 // Scan for the argument terminator character.
748 // This can be either a NULL character - in case we reach the end of the string,
749 // a double quote in case of quoted argument,
750 // or a whitespace character (' ' or '=') for non-quoted argument.
751 while (*ptr && !( (isQuoted && (*ptr == '\"')) ||
752 (!isQuoted && (*ptr == ' ' || *ptr == '=')) )
753 )
754 {
755 ptr++;
756 }
757
758 len = ptr - strStart;
759
760 // Skip the closing double quote character and adjust
761 // the starting pointer for the next getNextArg call.
762 if (*ptr && isQuoted && *ptr == '\"')
763 ptr++;
764
765 // Copy the extracted argument to val.
766 strncat(val, strStart, len);
767
768 // Set command line pointer.
769 *argPtr = ptr;
770
771 return ptr;
772}
773

Archive Download this file

Revision: 214