1 /*
2 * scriplib.c
3 * MACT library Script file parsing and writing
4 *
5 * by Jonathon Fowler
6 *
7 * Since we weren't given the source for MACT386.LIB so I've had to do some
8 * creative interpolation here.
9 *
10 * This all should be rewritten in a much much cleaner fashion.
11 *
12 */
13 //-------------------------------------------------------------------------
14 /*
15 Duke Nukem Copyright (C) 1996, 2003 3D Realms Entertainment
16
17 This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
18
19 Duke Nukem 3D is free software; you can redistribute it and/or
20 modify it under the terms of the GNU General Public License
21 as published by the Free Software Foundation; either version 2
22 of the License, or (at your option) any later version.
23
24 This program is distributed in the hope that it will be useful,
25 but WITHOUT ANY WARRANTY; without even the implied warranty of
26 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
27
28 See the GNU General Public License for more details.
29
30 You should have received a copy of the GNU General Public License
31 along with this program; if not, write to the Free Software
32 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33 */
34 //-------------------------------------------------------------------------
35
36 #include "compat.h"
37 #include "types.h"
38 #include "scriplib.h"
39 #include "util_lib.h"
40 #include "file_lib.h"
41 #include "_scrplib.h"
42 #include <string.h>
43 #include <stdio.h>
44 #include <ctype.h>
45
46 #ifdef __WATCOMC__
47 #include <malloc.h>
48 #endif
49
50
51 static script_t *scriptfiles[MAXSCRIPTFILES];
52
53
54 #define SC(s) scriptfiles[s]
55
56
SCRIPT_New(void)57 int32 SCRIPT_New(void)
58 {
59 int32 i;
60
61 for (i=0; i<MAXSCRIPTFILES; i++) {
62 if (!SC(i)) {
63 SC(i) = (script_t *)SafeMalloc(sizeof(script_t));
64 if (!SC(i)) return -1;
65 memset(SC(i), 0, sizeof(script_t));
66 return i;
67 }
68 }
69
70 return -1;
71 }
72
SCRIPT_Delete(int32 scripthandle)73 void SCRIPT_Delete(int32 scripthandle)
74 {
75 ScriptSectionType *s;
76
77 if (scripthandle < 0 || scripthandle >= MAXSCRIPTFILES) return;
78
79 if (!SC(scripthandle)) return;
80
81 if (SCRIPT(scripthandle,script)) {
82 while (SCRIPT(scripthandle,script)->nextsection != SCRIPT(scripthandle,script)) {
83 s = SCRIPT(scripthandle,script)->nextsection;
84 SCRIPT_FreeSection(SCRIPT(scripthandle,script));
85 SafeFree(SCRIPT(scripthandle,script));
86 SCRIPT(scripthandle,script) = s;
87 }
88
89 SafeFree(SCRIPT(scripthandle,script));
90 }
91
92 SafeFree(SC(scripthandle));
93 SC(scripthandle) = 0;
94 }
95
SCRIPT_FreeSection(ScriptSectionType * section)96 void SCRIPT_FreeSection(ScriptSectionType * section)
97 {
98 ScriptEntryType *e;
99
100 if (!section) return;
101 if (!section->entries) return;
102
103 while (section->entries->nextentry != section->entries) {
104 e = section->entries->nextentry;
105 SafeFree(section->entries);
106 section->entries = e;
107 }
108
109 SafeFree(section->entries);
110 free(section->name);
111 }
112
113 #define AllocSection(s) \
114 { \
115 (s) = SafeMalloc(sizeof(ScriptSectionType)); \
116 (s)->name = NULL; \
117 (s)->entries = NULL; \
118 (s)->lastline = NULL; \
119 (s)->nextsection = (s); \
120 (s)->prevsection = (s); \
121 }
122 #define AllocEntry(e) \
123 { \
124 (e) = SafeMalloc(sizeof(ScriptEntryType)); \
125 (e)->name = NULL; \
126 (e)->value = NULL; \
127 (e)->nextentry = (e); \
128 (e)->preventry = (e); \
129 }
130
SCRIPT_SectionExists(int32 scripthandle,const char * sectionname)131 ScriptSectionType * SCRIPT_SectionExists( int32 scripthandle, const char * sectionname )
132 {
133 ScriptSectionType *s, *ls=NULL;
134
135 if (scripthandle < 0 || scripthandle >= MAXSCRIPTFILES) return NULL;
136 if (!sectionname) return NULL;
137 if (!SC(scripthandle)) return NULL;
138 if (!SCRIPT(scripthandle,script)) return NULL;
139
140 for (s = SCRIPT(scripthandle,script); ls != s; ls=s,s=s->nextsection)
141 if (!Bstrcasecmp(s->name, sectionname)) return s;
142
143 return NULL;
144 }
145
SCRIPT_AddSection(int32 scripthandle,const char * sectionname)146 ScriptSectionType * SCRIPT_AddSection( int32 scripthandle, const char * sectionname )
147 {
148 ScriptSectionType *s,*s2;
149
150 if (scripthandle < 0 || scripthandle >= MAXSCRIPTFILES) return NULL;
151 if (!sectionname) return NULL;
152 if (!SC(scripthandle)) return NULL;
153
154 s = SCRIPT_SectionExists(scripthandle, sectionname);
155 if (s) return s;
156
157 AllocSection(s);
158 s->name = strdup(sectionname);
159 if (!SCRIPT(scripthandle,script)) {
160 SCRIPT(scripthandle,script) = s;
161 } else {
162 s2 = SCRIPT(scripthandle,script);
163 while (s2->nextsection != s2) s2=s2->nextsection;
164 s2->nextsection = s;
165 s->prevsection = s2;
166 }
167
168 return s;
169 }
170
SCRIPT_EntryExists(ScriptSectionType * section,const char * entryname)171 ScriptEntryType * SCRIPT_EntryExists ( ScriptSectionType * section, const char * entryname )
172 {
173 ScriptEntryType *e,*le=NULL;
174
175 if (!section) return NULL;
176 if (!entryname) return NULL;
177 if (!section->entries) return NULL;
178
179 for (e = section->entries; le != e; le=e,e=e->nextentry)
180 if (!Bstrcasecmp(e->name, entryname)) return e;
181
182 return NULL;
183 }
184
SCRIPT_AddEntry(int32 scripthandle,const char * sectionname,const char * entryname,const char * entryvalue)185 void SCRIPT_AddEntry ( int32 scripthandle, const char * sectionname, const char * entryname, const char * entryvalue )
186 {
187 ScriptSectionType *s;
188 ScriptEntryType *e,*e2;
189
190 if (scripthandle < 0 || scripthandle >= MAXSCRIPTFILES) return;
191 if (!sectionname || !entryname || !entryvalue) return;
192 if (!SC(scripthandle)) return;
193
194 // s = SCRIPT_SectionExists(scripthandle, sectionname);
195 // if (!s) {
196 s = SCRIPT_AddSection(scripthandle, sectionname);
197 if (!s) return;
198 // }
199
200 e = SCRIPT_EntryExists(s, entryname);
201 if (!e) {
202 AllocEntry(e);
203 e->name = strdup(entryname);
204 if (!s->entries) {
205 s->entries = e;
206 } else {
207 e2 = s->entries;
208 while (e2->nextentry != e2) e2=e2->nextentry;
209 e2->nextentry = e;
210 e->preventry = e2;
211 }
212 }
213
214 if (e->value) free(e->value);
215 e->value = strdup(entryvalue);
216 }
217
218
SCRIPT_ParseBuffer(int32 scripthandle,char * data,int32 length)219 int32 SCRIPT_ParseBuffer(int32 scripthandle, char *data, int32 length)
220 {
221 char *fence = data + length;
222 char *dp, *sp, ch=0, lastch=0;
223 char *currentsection = "";
224 char *currententry = NULL;
225 char *currentvalue = NULL;
226 enum {
227 ParsingIdle,
228 ParsingSectionBegin,
229 ParsingSectionName,
230 ParsingEntry,
231 ParsingValueBegin,
232 ParsingValue
233 };
234 enum {
235 ExpectingSection = 1,
236 ExpectingEntry = 2,
237 ExpectingAssignment = 4,
238 ExpectingValue = 8,
239 ExpectingComment = 16
240 };
241 int state;
242 int expect;
243 int linenum=1;
244 int rv = 0;
245 #define SETRV(v) if (v>rv||rv==0) rv=v
246
247 if (!data) return 1;
248 if (length < 0) return 1;
249
250 dp = sp = data;
251 state = ParsingIdle;
252 expect = ExpectingSection | ExpectingEntry;
253
254 #define EATLINE(p) while (length > 0 && *p != '\n' && *p != '\r') { p++; length--; }
255 #define LETTER() { lastch = ch; ch = *(sp++); length--; }
256
257 while (length > 0) {
258 switch (state) {
259 case ParsingIdle:
260 LETTER();
261 switch (ch) {
262 // whitespace
263 case ' ':
264 case '\t': continue;
265 case '\n': if (lastch == '\r') continue; linenum++; continue;
266 case '\r': linenum++; continue;
267
268 case ';':
269 /*case '#':*/
270 EATLINE(sp);
271 continue;
272
273 case '[': if (!(expect & ExpectingSection)) {
274 // Unexpected section start
275 printf("Unexpected start of section on line %d.\n", linenum);
276 SETRV(-1);
277 EATLINE(sp);
278 continue;
279 } else {
280 state = ParsingSectionBegin;
281 continue;
282 }
283
284 default: if (isalpha(ch)) {
285 if (!(expect & ExpectingEntry)) {
286 // Unexpected name start
287 printf("Unexpected entry label on line %d.\n", linenum);
288 SETRV(-1);
289 EATLINE(sp);
290 continue;
291 } else {
292 currententry = dp = sp-1;
293 state = ParsingEntry;
294 continue;
295 }
296 } else {
297 // Unexpected character
298 printf("Illegal character (ASCII %d) on line %d.\n", ch, linenum);
299 SETRV(-1);
300 EATLINE(sp);
301 continue;
302 }
303 }
304
305 case ParsingSectionBegin:
306 currentsection = dp = sp;
307 state = ParsingSectionName;
308 case ParsingSectionName:
309 LETTER();
310 switch (ch) {
311 case '\n':
312 case '\r': // Unexpected newline
313 printf("Unexpected newline on line %d.\n", linenum);
314 SETRV(-1);
315 state = ParsingIdle;
316 linenum++;
317 continue;
318
319 case ']':
320 *(dp) = 0; // Add new section
321 expect = ExpectingSection | ExpectingEntry;
322 state = ParsingIdle;
323 EATLINE(sp);
324 continue;
325
326 default:
327 dp++;
328 continue;
329 }
330
331 case ParsingEntry:
332 LETTER();
333 switch (ch) {
334 case ';':
335 /*case '#':*/
336 // unexpected comment
337 EATLINE(sp);
338 printf("Unexpected comment on line %d.\n", linenum);
339 SETRV(-1);
340 case '\n':
341 case '\r':
342 // Unexpected newline
343 printf("Unexpected newline on line %d.\n", linenum);
344 SETRV(-1);
345 expect = ExpectingSection | ExpectingEntry;
346 state = ParsingIdle;
347 linenum++;
348 continue;
349
350 case '=':
351 // Entry name finished, now for the value
352 while (*dp == ' ' || *dp == '\t') dp--;
353 *(++dp) = 0;
354 state = ParsingValueBegin;
355 continue;
356
357 default:
358 dp++;
359 continue;
360 }
361
362 case ParsingValueBegin:
363 currentvalue = dp = sp;
364 state = ParsingValue;
365 case ParsingValue:
366 LETTER();
367 switch (ch) {
368 case '\n':
369 case '\r':
370 // value complete, add it using parsed name
371 while (*dp == ' ' && *dp == '\t') dp--;
372 *(dp) = 0;
373 while (*currentvalue == ' ' || *currentvalue == '\t') currentvalue++;
374 state = ParsingIdle;
375 linenum++;
376
377 SCRIPT_AddSection(scripthandle,currentsection);
378 SCRIPT_AddEntry(scripthandle,currentsection,currententry,currentvalue);
379 continue;
380
381 default:
382 dp++;
383 continue;
384 }
385
386 default: length=0;
387 continue;
388 }
389 }
390
391 if (sp > fence) printf("Stepped outside the fence!\n");
392
393 return rv;
394 }
395
396
397 //---
398
SCRIPT_Init(const char * name)399 int32 SCRIPT_Init( const char * name )
400 {
401 int32 h = SCRIPT_New();
402
403 if (h >= 0) strncpy(SCRIPT(h,scriptfilename), name, 127);
404
405 return h;
406 }
407
SCRIPT_Free(int32 scripthandle)408 void SCRIPT_Free( int32 scripthandle )
409 {
410 SCRIPT_Delete(scripthandle);
411 }
412
SCRIPT_Parse(char * UNUSED (data),int32 UNUSED (length),char * UNUSED (name))413 int32 SCRIPT_Parse ( char *UNUSED(data), int32 UNUSED(length), char * UNUSED(name) )
414 {
415 return 0;
416 }
417
SCRIPT_Load(const char * filename)418 int32 SCRIPT_Load ( const char * filename )
419 {
420 int32 s,h,l;
421 char *b;
422
423 h = SafeOpenRead(filename, filetype_binary);
424 l = SafeFileLength(h)+1;
425 b = (char *)SafeMalloc(l);
426 SafeRead(h,b,l-1);
427 b[l-1] = '\n'; // JBF 20040111: evil nasty hack to trick my evil nasty parser
428 SafeClose(h);
429
430 s = SCRIPT_Init(filename);
431 if (s<0) {
432 SafeFree(b);
433 return -1;
434 }
435
436 SCRIPT_ParseBuffer(s,b,l);
437
438 SafeFree(b);
439
440 return s;
441 }
442
SCRIPT_Save(int32 scripthandle,const char * filename)443 void SCRIPT_Save (int32 scripthandle, const char * filename)
444 {
445 const char *section, *entry, *value;
446 int sec, ent, numsect, nument;
447 FILE *fp;
448
449
450 if (!filename) return;
451 if (!SC(scripthandle)) return;
452
453 fp = fopen(filename, "w");
454 if (!fp) return;
455
456 numsect = SCRIPT_NumberSections(scripthandle);
457 for (sec=0; sec<numsect; sec++) {
458 section = SCRIPT_Section(scripthandle, sec);
459 if (sec>0) fprintf(fp, "\n");
460 if (section[0] != 0)
461 fprintf(fp, "[%s]\n", section);
462
463 nument = SCRIPT_NumberEntries(scripthandle,section);
464 for (ent=0; ent<nument; ent++) {
465 entry = SCRIPT_Entry(scripthandle,section,ent);
466 value = SCRIPT_GetRaw(scripthandle,section,entry);
467
468 fprintf(fp, "%s = %s\n", entry, value);
469 }
470 }
471
472 fclose(fp);
473 }
474
SCRIPT_NumberSections(int32 scripthandle)475 int32 SCRIPT_NumberSections( int32 scripthandle )
476 {
477 int32 c=0;
478 ScriptSectionType *s,*ls=NULL;
479
480 if (!SC(scripthandle)) return 0;
481 if (!SCRIPT(scripthandle,script)) return 0;
482
483 for (s = SCRIPT(scripthandle,script); ls != s; ls=s,s=s->nextsection) c++;
484
485 return c;
486 }
487
SCRIPT_Section(int32 scripthandle,int32 which)488 char * SCRIPT_Section( int32 scripthandle, int32 which )
489 {
490 ScriptSectionType *s,*ls=NULL;
491
492 if (!SC(scripthandle)) return "";
493 if (!SCRIPT(scripthandle,script)) return "";
494
495 for (s = SCRIPT(scripthandle,script); which>0 && ls != s; ls=s, s=s->nextsection, which--) ;
496
497 return s->name;
498 }
499
SCRIPT_NumberEntries(int32 scripthandle,const char * sectionname)500 int32 SCRIPT_NumberEntries( int32 scripthandle, const char * sectionname )
501 {
502 ScriptSectionType *s;
503 ScriptEntryType *e,*le=NULL;
504 int32 c=0;
505
506 if (!SC(scripthandle)) return 0;
507 if (!SCRIPT(scripthandle,script)) return 0;
508
509 s = SCRIPT_SectionExists(scripthandle, sectionname);
510 if (!s) return 0;
511
512 for (e = s->entries; le != e; le=e,e=e->nextentry) c++;
513 return c;
514 }
515
SCRIPT_Entry(int32 scripthandle,const char * sectionname,int32 which)516 const char * SCRIPT_Entry( int32 scripthandle, const char * sectionname, int32 which )
517 {
518 ScriptSectionType *s;
519 ScriptEntryType *e,*le=NULL;
520
521 if (!SC(scripthandle)) return 0;
522 if (!SCRIPT(scripthandle,script)) return 0;
523
524 s = SCRIPT_SectionExists(scripthandle, sectionname);
525 if (!s) return "";
526
527 for (e = s->entries; which>0 && le != e; le=e, e=e->nextentry, which--) ;
528 return e->name;
529 }
530
SCRIPT_GetRaw(int32 scripthandle,const char * sectionname,const char * entryname)531 const char * SCRIPT_GetRaw(int32 scripthandle, const char * sectionname, const char * entryname)
532 {
533 ScriptSectionType *s;
534 ScriptEntryType *e;
535
536 if (!SC(scripthandle)) return 0;
537 if (!SCRIPT(scripthandle,script)) return 0;
538
539 s = SCRIPT_SectionExists(scripthandle, sectionname);
540 e = SCRIPT_EntryExists(s, entryname);
541
542 if (!e) return "";
543 return e->value;
544 }
545
SCRIPT_GetString(int32 scripthandle,const char * sectionname,const char * entryname,char * dest,size_t destlen)546 boolean SCRIPT_GetString( int32 scripthandle, const char * sectionname, const char * entryname, char * dest, size_t destlen )
547 {
548 ScriptSectionType *s;
549 ScriptEntryType *e;
550 const char *p;
551 char ch, done;
552 size_t c;
553
554 if (!SC(scripthandle)) return 1;
555 if (!SCRIPT(scripthandle,script)) return 1;
556
557 s = SCRIPT_SectionExists(scripthandle, sectionname);
558 e = SCRIPT_EntryExists(s, entryname);
559
560 if (!e) return 1;
561 if (destlen < 1) return 1;
562
563 // Deduct the terminating null.
564 destlen--;
565
566 p = e->value;
567 c = 0;
568 done = 0;
569
570 if (*p == '\"') {
571 // quoted string
572 p++;
573 while (!done && (ch = *(p++))) {
574 switch (ch) {
575 case '\\':
576 ch = *(p++);
577 if (ch == 0) {
578 done = 1;
579 } else if (c < destlen) {
580 switch (ch) {
581 case 'n': dest[c++] = '\n'; break;
582 case 'r': dest[c++] = '\r'; break;
583 case 't': dest[c++] = '\t'; break;
584 default: dest[c++] = ch; break;
585 }
586 }
587 break;
588 case '\"':
589 done = 1;
590 break;
591 default:
592 if (c < destlen) {
593 dest[c++] = ch;
594 }
595 break;
596 }
597 }
598 } else {
599 while ((ch = *(p++))) {
600 if (ch == ' ' || ch == '\t') {
601 break;
602 } else if (c < destlen) {
603 dest[c++] = ch;
604 }
605 }
606 }
607
608 dest[c] = 0;
609
610 return 0;
611 }
612
SCRIPT_GetDoubleString(int32 scripthandle,const char * sectionname,const char * entryname,char * dest1,char * dest2,size_t dest1len,size_t dest2len)613 boolean SCRIPT_GetDoubleString( int32 scripthandle, const char * sectionname, const char * entryname, char * dest1, char * dest2, size_t dest1len, size_t dest2len )
614 {
615 ScriptSectionType *s;
616 ScriptEntryType *e;
617 const char *p;
618 char ch, done;
619 size_t c;
620
621 if (!SC(scripthandle)) return 1;
622 if (!SCRIPT(scripthandle,script)) return 1;
623
624 s = SCRIPT_SectionExists(scripthandle, sectionname);
625 e = SCRIPT_EntryExists(s, entryname);
626
627 if (!e) return 1;
628 if (dest1len < 1) return 1;
629 if (dest2len < 1) return 1;
630
631 // Deduct the terminating nulls.
632 dest1len--;
633 dest2len--;
634
635 p = e->value;
636 c = 0;
637 done = 0;
638
639 if (*p == '\"') {
640 // quoted string
641 p++;
642 while (!done && (ch = *(p++))) {
643 switch (ch) {
644 case '\\':
645 ch = *(p++);
646 if (ch == 0) {
647 done = 1;
648 } else if (c < dest1len) {
649 switch (ch) {
650 case 'n': dest1[c++] = '\n'; break;
651 case 'r': dest1[c++] = '\r'; break;
652 case 't': dest1[c++] = '\t'; break;
653 default: dest1[c++] = ch; break;
654 }
655 }
656 break;
657 case '\"':
658 done = 1;
659 break;
660 default:
661 if (c < dest1len) {
662 dest1[c++] = ch;
663 }
664 break;
665 }
666 }
667 } else {
668 while ((ch = *(p++))) {
669 if (ch == ' ' || ch == '\t') {
670 break;
671 } else if (c < dest1len) {
672 dest1[c++] = ch;
673 }
674 }
675 }
676
677 dest1[c] = 0;
678
679 while (*p == ' ' || *p == '\t') p++;
680 if (*p == 0) return 0;
681
682 c = 0;
683 done = 0;
684
685 if (*p == '\"') {
686 // quoted string
687 p++;
688 while (!done && (ch = *(p++))) {
689 switch (ch) {
690 case '\\':
691 ch = *(p++);
692 if (ch == 0) {
693 done = 1;
694 } else if (c < dest2len) {
695 switch (ch) {
696 case 'n': dest2[c++] = '\n'; break;
697 case 'r': dest2[c++] = '\r'; break;
698 case 't': dest2[c++] = '\t'; break;
699 default: dest2[c++] = ch; break;
700 }
701 }
702 break;
703 case '\"':
704 done = 1;
705 break;
706 default:
707 if (c < dest2len) {
708 dest2[c++] = ch;
709 }
710 break;
711 }
712 }
713 } else {
714 while ((ch = *(p++))) {
715 if (ch == ' ' || ch == '\t') {
716 break;
717 } else if (c < dest2len) {
718 dest2[c++] = ch;
719 }
720 }
721 }
722
723 dest2[c] = 0;
724
725 return 0;
726 }
727
SCRIPT_GetNumber(int32 scripthandle,const char * sectionname,const char * entryname,int32 * number)728 boolean SCRIPT_GetNumber( int32 scripthandle, const char * sectionname, const char * entryname, int32 * number )
729 {
730 ScriptSectionType *s;
731 ScriptEntryType *e;
732 char *p;
733
734 if (!SC(scripthandle)) return 1;
735 if (!SCRIPT(scripthandle,script)) return 1;
736
737 s = SCRIPT_SectionExists(scripthandle, sectionname);
738 e = SCRIPT_EntryExists(s, entryname);
739
740 if (!e) return 1;// *number = 0;
741 else {
742 if (e->value[0] == '0' && e->value[1] == 'x') {
743 // hex
744 *number = strtol(e->value+2, &p, 16);
745 if (p == e->value || *p != 0 || *p != ' ' || *p != '\t') return 1;
746 } else {
747 // decimal
748 *number = strtol(e->value, &p, 10);
749 if (p == e->value || *p != 0 || *p != ' ' || *p != '\t') return 1;
750 }
751 }
752
753 return 0;
754 }
755
SCRIPT_GetBoolean(int32 scripthandle,const char * sectionname,const char * entryname,boolean * boole)756 boolean SCRIPT_GetBoolean( int32 scripthandle, const char * sectionname, const char * entryname, boolean * boole )
757 {
758 ScriptSectionType *s;
759 ScriptEntryType *e;
760
761 if (!SC(scripthandle)) return 1;
762 if (!SCRIPT(scripthandle,script)) return 1;
763
764 s = SCRIPT_SectionExists(scripthandle, sectionname);
765 e = SCRIPT_EntryExists(s, entryname);
766
767 if (!e) return 1;// *boole = 0;
768 else {
769 if (!Bstrncasecmp(e->value, "true", 4)) *boole = 1;
770 else if (!Bstrncasecmp(e->value, "false", 5)) *boole = 0;
771 else if (e->value[0] == '1' && (e->value[1] == ' ' || e->value[1] == '\t' || e->value[1] == 0)) *boole = 1;
772 else if (e->value[0] == '0' && (e->value[1] == ' ' || e->value[1] == '\t' || e->value[1] == 0)) *boole = 0;
773 }
774
775 return 0;
776 }
777
SCRIPT_GetDouble(int32 scripthandle,const char * sectionname,const char * entryname,double * UNUSED (number))778 boolean SCRIPT_GetDouble( int32 scripthandle, const char * sectionname, const char * entryname, double * UNUSED(number) )
779 {
780 ScriptSectionType *s;
781 ScriptEntryType *e;
782
783 if (!SC(scripthandle)) return 1;
784 if (!SCRIPT(scripthandle,script)) return 1;
785
786 s = SCRIPT_SectionExists(scripthandle, sectionname);
787 e = SCRIPT_EntryExists(s, entryname);
788
789 if (!e) return 1;// *number = 0.0;
790 else {
791 //XXX
792 }
793
794 return 0;
795 }
796
SCRIPT_PutComment(int32 UNUSED (scripthandle),const char * UNUSED (sectionname),const char * UNUSED (comment))797 void SCRIPT_PutComment( int32 UNUSED(scripthandle), const char * UNUSED(sectionname), const char * UNUSED(comment) )
798 {
799 //XXX
800 }
801
SCRIPT_PutEOL(int32 UNUSED (scripthandle),const char * UNUSED (sectionname))802 void SCRIPT_PutEOL( int32 UNUSED(scripthandle), const char * UNUSED(sectionname) )
803 {
804 //XXX
805 }
806
SCRIPT_PutMultiComment(int32 UNUSED (scripthandle),const char * UNUSED (sectionname),const char * UNUSED (comment),...)807 void SCRIPT_PutMultiComment
808 (
809 int32 UNUSED(scripthandle),
810 const char * UNUSED(sectionname),
811 const char * UNUSED(comment),
812 ...
813 )
814 {
815 }
816
SCRIPT_PutSection(int32 scripthandle,const char * sectionname)817 void SCRIPT_PutSection( int32 scripthandle, const char * sectionname )
818 {
819 SCRIPT_AddSection(scripthandle, sectionname);
820 }
821
SCRIPT_PutRaw(int32 scripthandle,const char * sectionname,const char * entryname,const char * raw)822 void SCRIPT_PutRaw
823 (
824 int32 scripthandle,
825 const char * sectionname,
826 const char * entryname,
827 const char * raw
828 )
829 {
830 SCRIPT_AddEntry(scripthandle, sectionname, entryname, raw);
831 }
832
SCRIPT_PutString(int32 scripthandle,const char * sectionname,const char * entryname,const char * string)833 void SCRIPT_PutString
834 (
835 int32 scripthandle,
836 const char * sectionname,
837 const char * entryname,
838 const char * string
839 )
840 {
841 char *raw,*p;
842 const char *q;
843 int len = 3;
844 if (!string) string = "";
845
846 for (q=string; *q; q++) {
847 if (*q == '\r' || *q == '\n' || *q == '\t' || *q == '\\' || *q == '"') len+=2;
848 else if (*q >= ' ') len++;
849 }
850 p = raw = Bmalloc(len);
851 *(p++) = '"';
852 for (q=string; *q; q++) {
853 if (*q == '\r') { *(p++) = '\\'; *(p++) = 'r'; }
854 else if (*q == '\n') { *(p++) = '\\'; *(p++) = 'n'; }
855 else if (*q == '\t') { *(p++) = '\\'; *(p++) = 't'; }
856 else if (*q == '\\' || *q == '"') { *(p++) = '\\'; *(p++) = *q; }
857 else if (*q >= ' ') *(p++) = *q;
858 }
859 *(p++) = '"';
860 *p=0;
861
862 SCRIPT_AddEntry(scripthandle, sectionname, entryname, raw);
863 Bfree(raw);
864 }
865
SCRIPT_PutDoubleString(int32 scripthandle,const char * sectionname,const char * entryname,const char * string1,const char * string2)866 void SCRIPT_PutDoubleString
867 (
868 int32 scripthandle,
869 const char * sectionname,
870 const char * entryname,
871 const char * string1,
872 const char * string2
873 )
874 {
875 char *raw,*p;
876 const char *q;
877 int len = 6;
878 if (!string1) string1 = "";
879 if (!string2) string2 = "";
880
881 for (q=string1; *q; q++) {
882 if (*q == '\r' || *q == '\n' || *q == '\t' || *q == '\\' || *q == '"') len+=2;
883 else if (*q >= ' ') len++;
884 }
885 for (q=string2; *q; q++) {
886 if (*q == '\r' || *q == '\n' || *q == '\t' || *q == '\\' || *q == '"') len+=2;
887 else if (*q >= ' ') len++;
888 }
889 p = raw = Bmalloc(len);
890 *(p++) = '"';
891 for (q=string1; *q; q++) {
892 if (*q == '\r') { *(p++) = '\\'; *(p++) = 'r'; }
893 else if (*q == '\n') { *(p++) = '\\'; *(p++) = 'n'; }
894 else if (*q == '\t') { *(p++) = '\\'; *(p++) = 't'; }
895 else if (*q == '\\' || *q == '"') { *(p++) = '\\'; *(p++) = *q; }
896 else if (*q >= ' ') *(p++) = *q;
897 }
898 *(p++) = '"';
899 *(p++) = ' ';
900 *(p++) = '"';
901 for (q=string2; *q; q++) {
902 if (*q == '\r') { *(p++) = '\\'; *(p++) = 'r'; }
903 else if (*q == '\n') { *(p++) = '\\'; *(p++) = 'n'; }
904 else if (*q == '\t') { *(p++) = '\\'; *(p++) = 't'; }
905 else if (*q == '\\' || *q == '"') { *(p++) = '\\'; *(p++) = *q; }
906 else if (*q >= ' ') *(p++) = *q;
907 }
908 *(p++) = '"';
909 *p=0;
910
911 SCRIPT_AddEntry(scripthandle, sectionname, entryname, raw);
912 Bfree(raw);
913 }
914
SCRIPT_PutNumber(int32 scripthandle,const char * sectionname,const char * entryname,int32 number,boolean hexadecimal,boolean UNUSED (defaultvalue))915 void SCRIPT_PutNumber
916 (
917 int32 scripthandle,
918 const char * sectionname,
919 const char * entryname,
920 int32 number,
921 boolean hexadecimal,
922 boolean UNUSED(defaultvalue)
923 )
924 {
925 char raw[64];
926
927 if (hexadecimal) sprintf(raw, "0x%X", number);
928 else sprintf(raw, "%d", number);
929
930 SCRIPT_AddEntry(scripthandle, sectionname, entryname, raw);
931 }
932
SCRIPT_PutBoolean(int32 scripthandle,const char * sectionname,const char * entryname,boolean boole)933 void SCRIPT_PutBoolean
934 (
935 int32 scripthandle,
936 const char * sectionname,
937 const char * entryname,
938 boolean boole
939 )
940 {
941 char raw[2] = "0";
942
943 if (boole) raw[0] = '1';
944
945 SCRIPT_AddEntry(scripthandle, sectionname, entryname, raw);
946 }
947
SCRIPT_PutDouble(int32 scripthandle,const char * sectionname,const char * entryname,double number,boolean UNUSED (defaultvalue))948 void SCRIPT_PutDouble
949 (
950 int32 scripthandle,
951 const char * sectionname,
952 const char * entryname,
953 double number,
954 boolean UNUSED(defaultvalue)
955 )
956 {
957 char raw[64];
958
959 sprintf(raw, "%g", number);
960
961 SCRIPT_AddEntry(scripthandle, sectionname, entryname, raw);
962 }
963
964