2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 Primitives for String.
26 #include "PyrPrimitive.h"
27 #include "PyrKernel.h"
34 #include "SC_DirUtils.h"
37 # include "SC_Win32Utils.h"
39 # include <sys/param.h>
42 #include <boost/regex.hpp>
43 #include <boost/intrusive/list.hpp>
44 #include <boost/intrusive/unordered_set.hpp>
47 #include "yaml-cpp/yaml.h"
54 int prStringAsSymbol(struct VMGlobals
*g
, int numArgsPushed
);
55 int prStringAsSymbol(struct VMGlobals
*g
, int numArgsPushed
)
58 char str
[1024], *strp
=0;
62 len
= slotRawObject(a
)->size
;
63 strp
= len
> 1023 ? (char*)malloc(len
+1) : str
;
65 memcpy(strp
, slotRawString(a
)->s
, len
);
68 SetSymbol(a
, getsym(strp
));
70 if (len
> 1023) free(strp
);
75 int prString_AsInteger(struct VMGlobals
*g
, int numArgsPushed
);
76 int prString_AsInteger(struct VMGlobals
*g
, int numArgsPushed
)
81 int err
= slotStrVal(a
, str
, 255);
89 int prString_AsFloat(struct VMGlobals
*g
, int numArgsPushed
);
90 int prString_AsFloat(struct VMGlobals
*g
, int numArgsPushed
)
95 int err
= slotStrVal(a
, str
, 255);
98 SetFloat(a
, atof(str
));
103 int prString_AsCompileString(struct VMGlobals
*g
, int numArgsPushed
)
106 PyrString
* scstr
= slotRawString(a
);
107 char *chars1
= scstr
->s
;
108 int newSize
= scstr
->size
+ 2;
109 for (int i
=0; i
<scstr
->size
; ++i
) {
110 if (chars1
[i
] == '"' || chars1
[i
] == '\\') newSize
++;
112 PyrString
*newString
= newPyrStringN(g
->gc
, newSize
, 0, true);
113 char *chars2
= newString
->s
;
115 chars2
[newSize
- 1] = '"';
117 for (int i
=0; i
<scstr
->size
; ++i
) {
119 if (c
== '"' || c
== '\\') chars2
[k
++] = '\\';
122 SetObject(a
, newString
);
126 int prString_Format(struct VMGlobals
*g
, int numArgsPushed
)
128 PyrSlot
*a
= g
->sp
- 1;
131 if (!isKindOfSlot(b
, class_array
)) return errWrongType
;
133 char *fmt
= slotRawString(a
)->s
;
135 int asize
= slotRawObject(a
)->size
;
136 int bsize
= slotRawObject(b
)->size
;
139 PyrSlot
*slots
= slotRawObject(b
)->slots
;
140 for (int i
=0; i
<bsize
; ++i
) {
141 PyrSlot
*slot
= slots
+ i
;
142 if (!isKindOfSlot(slot
, class_string
)) return errWrongType
;
143 csize
+= slotRawString(slot
)->size
;
145 PyrString
*newString
= newPyrStringN(g
->gc
, csize
, 0, true);
146 char* buf
= newString
->s
;
150 for (int i
=0; i
<asize
;) {
154 PyrString
* bstring
= slotRawString(&slots
[index
]);
155 memcpy(buf
+k
, bstring
->s
, bstring
->size
);
159 } else if (ch
== '\\') {
160 if (i
>= asize
) break;
172 SetObject(a
, newString
);
178 namespace bin
= boost::intrusive
;
180 class regex_lru_cache
185 bin::list_base_hook
<>,
186 bin::unordered_set_base_hook
<>
189 regex_node(const char * str
, size_t size
, int regex_flags
):
190 pattern(str
, size
, regex_flags
)
193 boost::regex
const & get (void) const
199 boost::regex pattern
;
204 bool operator()(regex_node
const & lhs
, regex_node
const & rhs
) const
206 return lhs
.get() == rhs
.get();
209 bool operator()(const char * lhs
, regex_node
const & rhs
) const
211 return strcmp(lhs
, rhs
.get().str().c_str()) == 0;
215 static inline std::size_t string_hash(const char * str
)
222 ret
= c
+ (ret
<< 6) + (ret
<< 16) - ret
;
229 size_t operator()(regex_node
const & arg
) const
231 return string_hash(arg
.get().str().c_str());
234 size_t operator()(const char * arg
) const
236 return string_hash(arg
);
240 typedef bin::unordered_set
<regex_node
, bin::equal
<regex_equal
>, bin::hash
<regex_hash
>,
241 bin::power_2_buckets
<true>, bin::constant_time_size
<false> >
243 typedef re_set_t::bucket_type bucket_type
;
244 typedef re_set_t::bucket_traits bucket_traits
;
245 bucket_type buckets
[128];
248 bin::list
<regex_node
> re_list
;
252 regex_node
& rlu
= re_list
.back();
259 regex_lru_cache(int regex_flags
= boost::regex_constants::ECMAScript
):
260 re_set(bucket_traits(buckets
, 128))
265 while (!re_list
.empty()) {
270 boost::regex
const & get_regex(const char * str
, size_t size
)
272 re_set_t::iterator re_in_cache
= re_set
.find(str
, regex_hash(), regex_equal());
273 if (re_in_cache
!= re_set
.end()) {
274 regex_node
& node
= *re_in_cache
;
275 bin::list
<regex_node
>::iterator re_in_list
= bin::list
<regex_node
>::s_iterator_to(node
);
277 re_list
.splice(re_list
.begin(), re_list
, re_in_list
); // move to the begin of the list
278 assert(&re_list
.front() == &node
);
282 if (re_list
.size() >= 64)
285 regex_node
* new_node
= new regex_node(str
, size
, regex_flags
);
286 re_set
.insert(*new_node
);
287 re_list
.push_front(*new_node
);
288 return new_node
->get();
294 int prString_Regexp(struct VMGlobals
*g
, int numArgsPushed
)
297 static detail::regex_lru_cache
regex_lru_cache(boost::regex_constants::ECMAScript
| boost::regex_constants::nosubs
);
299 using namespace boost
;
303 PyrSlot
*a
= g
->sp
- 3;
304 PyrSlot
*b
= g
->sp
- 2;
305 PyrSlot
*c
= g
->sp
- 1;
308 if (!isKindOfSlot(b
, class_string
)) return errWrongType
;
309 if (NotInt(c
) || (NotInt(d
) && NotNil(d
))) return errWrongType
;
310 start
= slotRawInt(c
);
312 len
= slotRawObject(b
)->size
; // last char index instead of size
323 if(end
- start
<= 0) {
328 int stringlen
= end
- start
;
331 regex
const & pattern
= regex_lru_cache
.get_regex(slotRawString(a
)->s
, slotRawObject(a
)->size
);
332 match_flag_type flags
= match_nosubs
| match_any
;
334 const char * stringStart
= slotRawString(b
)->s
+ start
;
335 const char * stringEnd
= stringStart
+ stringlen
;
336 bool res
= regex_search(stringStart
, stringEnd
, pattern
, flags
);
344 } catch (std::exception
const & e
) {
345 postfl("Warning: Exception in _String_Regexp - %s\n", e
.what());
350 struct sc_regexp_match
{
356 static int prString_FindRegexp(struct VMGlobals
*g
, int numArgsPushed
)
359 static detail::regex_lru_cache
regex_lru_cache(boost::regex_constants::ECMAScript
);
361 using namespace boost
;
363 PyrSlot
*a
= g
->sp
- 2; // source string
364 PyrSlot
*b
= g
->sp
- 1; // pattern
365 PyrSlot
*c
= g
->sp
; // offset
367 if (!isKindOfSlot(b
, class_string
) || (NotInt(c
))) return errWrongType
;
369 int offset
= slotRawInt(c
);
370 int stringlen
= std::max(slotRawObject(a
)->size
- offset
, 0);
372 std::vector
<sc_regexp_match
> matches
;
373 const char* const stringBegin
= slotRawString(a
)->s
+ offset
;
375 regex
const & pattern
= regex_lru_cache
.get_regex(slotRawString(b
)->s
, slotRawObject(b
)->size
);
376 match_flag_type flags
= match_default
;
378 match_results
<const char*> what
;
379 const char* start
= stringBegin
;
380 const char* end
= start
+ stringlen
;
381 while (start
<= end
&& regex_search(start
, end
, what
, pattern
, flags
))
383 for (int i
= 0; i
< what
.size(); ++i
)
385 sc_regexp_match match
;
386 if (what
[i
].matched
) {
387 match
.pos
= what
[i
].first
- stringBegin
;
388 match
.len
= what
[i
].second
- what
[i
].first
;
393 matches
.push_back(match
);
395 start
= what
[0].second
;
396 if(what
[0].first
== what
[0].second
) ++start
;
398 } catch (std::exception
const & e
) {
399 postfl("Warning: Exception in _String_FindRegexp - %s\n", e
.what());
403 int match_count
= matches
.size();
405 PyrObject
*result_array
= newPyrArray(g
->gc
, match_count
, 0, true);
406 result_array
->size
= 0;
407 SetObject(a
, result_array
);
409 if( !match_count
) return errNone
;
411 for (int i
= 0; i
< match_count
; ++i
)
413 int pos
= matches
[i
].pos
;
414 int len
= matches
[i
].len
;
416 PyrObject
*array
= newPyrArray(g
->gc
, 2, 0, true);
417 SetObject(result_array
->slots
+ i
, array
);
418 result_array
->size
++;
419 g
->gc
->GCWrite(result_array
, array
);
421 PyrString
*matched_string
= newPyrStringN(g
->gc
, len
, 0, true);
422 memcpy(matched_string
->s
, stringBegin
+ pos
, len
);
425 SetInt(array
->slots
, pos
+ offset
);
426 SetObject(array
->slots
+1, matched_string
);
427 g
->gc
->GCWrite(array
, matched_string
);
433 int memcmpi(char *a
, char *b
, int len
)
435 for (int i
=0; i
<len
; ++i
) {
436 char aa
= toupper(a
[i
]);
437 char bb
= toupper(b
[i
]);
438 if (aa
< bb
) return -1;
439 if (aa
> bb
) return 1;
444 int prStringCompare(struct VMGlobals
*g
, int numArgsPushed
);
445 int prStringCompare(struct VMGlobals
*g
, int numArgsPushed
)
454 if (NotObj(b
) || !isKindOf(slotRawObject(b
), class_string
)) {
458 length
= sc_min(slotRawObject(a
)->size
, slotRawObject(b
)->size
);
459 if (IsTrue(c
)) cmp
= memcmpi(slotRawString(a
)->s
, slotRawString(b
)->s
, length
);
460 else cmp
= memcmp(slotRawString(a
)->s
, slotRawString(b
)->s
, length
);
462 if (slotRawObject(a
)->size
< slotRawObject(b
)->size
) cmp
= -1;
463 else if (slotRawObject(a
)->size
> slotRawObject(b
)->size
) cmp
= 1;
469 int prStringHash(struct VMGlobals
*g
, int numArgsPushed
);
470 int prStringHash(struct VMGlobals
*g
, int numArgsPushed
)
473 int hash
= Hash(slotRawString(a
)->s
, slotRawString(a
)->size
);
481 int prStringPathMatch(struct VMGlobals
*g
, int numArgsPushed
);
482 int prStringPathMatch(struct VMGlobals
*g
, int numArgsPushed
)
487 int err
= slotStrVal(a
, pattern
, 1023);
492 int gflags
= GLOB_MARK
| GLOB_TILDE
;
494 gflags
|= GLOB_QUOTE
;
497 int gerr
= glob(pattern
, gflags
, NULL
, &pglob
);
501 PyrObject
* array
= newPyrArray(g
->gc
, pglob
.gl_pathc
, 0, true);
503 if (gerr
) return errNone
;
505 for (unsigned int i
=0; i
<pglob
.gl_pathc
; ++i
) {
506 PyrObject
*string
= (PyrObject
*)newPyrString(g
->gc
, pglob
.gl_pathv
[i
], 0, true);
507 SetObject(array
->slots
+i
, string
);
508 g
->gc
->GCWrite(array
, string
);
516 #else //#ifndef SC_WIN32
517 int prStringPathMatch(struct VMGlobals
*g
, int numArgsPushed
);
519 int prStringPathMatch(struct VMGlobals
*g
, int numArgsPushed
)
524 int err
= slotStrVal(a
, pattern
, 1023);
527 win32_ReplaceCharInString(pattern
,1024,'/','\\');
528 // Remove trailing slash if found, to allow folders to be matched
529 if(pattern
[strlen(pattern
)-1]=='\\'){
530 pattern
[strlen(pattern
)-1] = 0;
532 // extract the containing folder, including backslash
534 win32_ExtractContainingFolder(folder
,pattern
,1024);
538 WIN32_FIND_DATA findData
;
542 hFind
= ::FindFirstFile(pattern
, &findData
);
543 if (hFind
== INVALID_HANDLE_VALUE
) {
547 if (hFind
== INVALID_HANDLE_VALUE
) {
548 // This is what happens when no matches. So we create an empty array to return.
549 PyrObject
* array
= newPyrArray(g
->gc
, 0, 0, true);
555 if(strcmp(findData
.cFileName
, "..")!=0 && strcmp(findData
.cFileName
, "..")!=0){
558 } while( ::FindNextFile(hFind
, &findData
));
563 hFind
= ::FindFirstFile(pattern
, &findData
);
564 if (hFind
== INVALID_HANDLE_VALUE
) {
568 PyrObject
* array
= newPyrArray(g
->gc
, nbPaths
, 0, true);
570 if (hFind
== INVALID_HANDLE_VALUE
) {
576 if(strcmp(findData
.cFileName
, "..")!=0 && strcmp(findData
.cFileName
, ".")!=0){
577 std::string
strPath(folder
);
578 strPath
+= std::string(findData
.cFileName
);
579 if(findData
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
){
580 strPath
+= std::string("\\"); // Append trailing slash, to match behaviour on unix (used by sclang to detect folderness)
582 const char* fullPath
= strPath
.c_str();
583 PyrObject
*string
= (PyrObject
*)newPyrString(g
->gc
, fullPath
, 0, true);
584 SetObject(array
->slots
+i
, string
);
585 g
->gc
->GCWrite(array
, string
);
589 } while( ::FindNextFile(hFind
, &findData
));
593 #endif //#ifndef SC_WIN32
595 int prString_Getenv(struct VMGlobals
* g
, int numArgsPushed
);
596 int prString_Getenv(struct VMGlobals
* g
, int /* numArgsPushed */)
598 PyrSlot
* arg
= g
->sp
;
603 err
= slotStrVal(arg
, key
, 256);
609 PyrString
* pyrString
= newPyrString(g
->gc
, value
, 0, true);
610 if (!pyrString
) return errFailed
;
611 SetObject(arg
, pyrString
);
619 int prString_Setenv(struct VMGlobals
* g
, int numArgsPushed
);
620 int prString_Setenv(struct VMGlobals
* g
, int /* numArgsPushed */)
622 PyrSlot
* args
= g
->sp
- 1;
626 err
= slotStrVal(args
+0, key
, 256);
631 SetEnvironmentVariable(key
,NULL
);
637 err
= slotStrVal(args
+1, value
, 1024);
640 SetEnvironmentVariable(key
, value
);
642 setenv(key
, value
, 1);
649 int prStripRtf(struct VMGlobals
*g
, int numArgsPushed
);
650 int prStripRtf(struct VMGlobals
*g
, int numArgsPushed
)
653 int len
= slotRawObject(a
)->size
;
654 char * chars
= (char*)malloc(len
+ 1);
655 memcpy(chars
, slotRawString(a
)->s
, len
);
659 PyrString
* string
= newPyrString(g
->gc
, chars
, 0, false);
660 SetObject(a
, string
);
666 int prStripHtml(struct VMGlobals
*g
, int numArgsPushed
);
667 int prStripHtml(struct VMGlobals
*g
, int numArgsPushed
)
670 int len
= slotRawObject(a
)->size
;
671 char * chars
= (char*)malloc(len
+ 1);
672 memcpy(chars
, slotRawString(a
)->s
, len
);
676 PyrString
* string
= newPyrString(g
->gc
, chars
, 0, false);
677 SetObject(a
, string
);
683 int prString_Find(struct VMGlobals
*g
, int numArgsPushed
);
684 int prString_Find(struct VMGlobals
*g
, int numArgsPushed
)
686 PyrSlot
*a
= g
->sp
- 3; // source string
687 PyrSlot
*b
= g
->sp
- 2; // search string
688 PyrSlot
*c
= g
->sp
- 1; // ignoreCase
689 PyrSlot
*d
= g
->sp
; // offset
692 int err
= slotIntVal(d
, &offset
);
695 if (!isKindOfSlot(b
, class_string
)) {
700 int alength
= slotRawObject(a
)->size
- offset
;
701 int blength
= slotRawObject(b
)->size
;
705 // should also return nil if search string is longer than source
706 || (blength
> alength
))
712 int cmp
= 1; // assume contains will be false
713 char *achar
= slotRawString(a
)->s
+ offset
;
714 char *bchar
= slotRawString(b
)->s
;
715 char bchar0
= bchar
[0];
716 int scanlength
= alength
- blength
;
718 bchar0
= toupper(bchar0
);
719 for (int i
=0; i
<= scanlength
; ++i
, ++achar
) {
720 if (toupper(*achar
) == bchar0
) {
721 cmp
= memcmpi(achar
+1, bchar
+1, blength
-1);
726 for (int i
=0; i
<= scanlength
; ++i
, ++achar
) {
727 if (*achar
== bchar0
) {
728 cmp
= memcmp(achar
+1, bchar
+1, blength
-1);
734 SetInt(a
, achar
- slotRawString(a
)->s
);
741 int prString_FindBackwards(struct VMGlobals
*g
, int numArgsPushed
);
742 int prString_FindBackwards(struct VMGlobals
*g
, int numArgsPushed
)
744 PyrSlot
*a
= g
->sp
- 3; // source string
745 PyrSlot
*b
= g
->sp
- 2; // search string
746 PyrSlot
*c
= g
->sp
- 1; // ignoreCase
747 PyrSlot
*d
= g
->sp
; // offset
750 int err
= slotIntVal(d
, &offset
);
753 if (!isKindOfSlot(b
, class_string
)) {
758 int alength
= sc_min(offset
+ 1, slotRawObject(a
)->size
);
759 int blength
= slotRawObject(b
)->size
;
763 // should also return nil if search string is longer than source
764 || (blength
> alength
))
770 int cmp
= 1; // assume contains will be false
771 char *achar
= slotRawString(a
)->s
+ (alength
- blength
);
772 char *bchar
= slotRawString(b
)->s
;
773 char bchar0
= bchar
[0];
774 int scanlength
= alength
- blength
;
776 bchar0
= toupper(bchar0
);
777 for (int i
=scanlength
; i
>= 0; --i
, --achar
) {
778 if (toupper(*achar
) == bchar0
) {
779 cmp
= memcmpi(achar
+1, bchar
+1, blength
-1);
784 for (int i
=scanlength
; i
>= 0; --i
, --achar
) {
785 if (*achar
== bchar0
) {
786 cmp
= memcmp(achar
+1, bchar
+1, blength
-1);
792 SetInt(a
, achar
- slotRawString(a
)->s
);
800 # include <CoreFoundation/CoreFoundation.h>
803 int prString_StandardizePath(struct VMGlobals
* g
, int numArgsPushed
);
804 int prString_StandardizePath(struct VMGlobals
* g
, int /* numArgsPushed */)
806 PyrSlot
* arg
= g
->sp
;
807 char ipath
[PATH_MAX
];
808 char opathbuf
[PATH_MAX
];
809 char* opath
= opathbuf
;
812 err
= slotStrVal(arg
, ipath
, PATH_MAX
);
815 if (!sc_StandardizePath(ipath
, opath
)) {
820 CFStringRef cfstring
=
821 CFStringCreateWithCString(NULL
,
823 kCFStringEncodingUTF8
);
824 err
= !CFStringGetFileSystemRepresentation(cfstring
, opath
, PATH_MAX
);
826 if (err
) return errFailed
;
829 PyrString
* pyrString
= newPyrString(g
->gc
, opath
, 0, true);
830 SetObject(arg
, pyrString
);
835 int prString_EscapeChar(struct VMGlobals
* g
, int numArgsPushed
)
837 PyrSlot
* arg
= g
->sp
- 1;
838 PyrSlot
* charToEscapeSlot
= g
->sp
;
840 assert (isKindOfSlot(arg
, class_string
));
842 if (!IsChar(charToEscapeSlot
))
845 char charToEscape
= slotRawChar(charToEscapeSlot
);
847 PyrString
* argString
= slotRawString(arg
);
848 int length
= argString
->size
;
849 PyrString
* resultString
= newPyrStringN(g
->gc
, length
*2 + 1, 0, 1); // pressimize
851 char * original
= argString
->s
;
852 char * result
= resultString
->s
;
854 int resultLength
= length
;
855 for (int i
= 0; i
!= length
; ++i
) {
856 char current
= *original
++;
857 if (current
== charToEscape
) {
865 resultString
->size
= resultLength
;
867 SetRaw(arg
, (PyrObject
*)resultString
);
872 static void yaml_traverse(struct VMGlobals
* g
, const YAML::Node
& node
, PyrObject
*parent
, PyrSlot
*slot
) {
873 YAML::NodeType::value type
= node
.Type();
875 PyrObject
*result
= NULL
;
879 case YAML::NodeType::Scalar
:
881 result
= (PyrObject
*)newPyrString(g
->gc
, out
.c_str(), 0, true);
882 SetObject(slot
, result
);
883 if(parent
) g
->gc
->GCWrite(parent
, result
);
886 case YAML::NodeType::Sequence
:
887 result
= newPyrArray(g
->gc
, node
.size(), 0, true);
889 SetObject(slot
, result
);
890 if(parent
) g
->gc
->GCWrite(parent
, result
);
891 for (unsigned int i
= 0; i
< node
.size(); i
++) {
892 const YAML::Node
& subnode
= node
[i
];
894 yaml_traverse(g
, subnode
, result
, result
->slots
+i
);
898 case YAML::NodeType::Map
:
900 result
= instantiateObject( g
->gc
, s_dictionary
->u
.classobj
, 0, false, true );
901 SetObject(slot
, result
);
902 if(parent
) g
->gc
->GCWrite(parent
, result
);
904 PyrObject
*array
= newPyrArray(g
->gc
, node
.size()*2, 0, true);
906 result
->size
= 2; // ?
907 SetObject(result
->slots
, array
); // array
908 SetInt(result
->slots
+1, node
.size()); // size
909 g
->gc
->GCWrite(result
, array
);
912 for (YAML::Iterator i
= node
.begin(); i
!= node
.end(); ++i
) {
913 const YAML::Node
& key
= i
.first();
914 const YAML::Node
& value
= i
.second();
916 PyrObject
*pkey
= (PyrObject
*)newPyrString(g
->gc
, out
.c_str(), 0, true);
917 SetObject(array
->slots
+j
, pkey
);
919 g
->gc
->GCWrite(array
, pkey
);
922 yaml_traverse(g
, value
, array
, array
->slots
+j
+1);
929 case YAML::NodeType::Null
:
934 postfl("WARNING: yaml_traverse(): unknown/unsupported node type\n");
939 int prString_ParseYAML(struct VMGlobals
* g
, int numArgsPushed
)
941 PyrSlot
* arg
= g
->sp
;
943 if (!isKindOfSlot(arg
, class_string
)) return errWrongType
;
945 string
str((const char*)slotRawString(arg
)->s
,slotRawString(arg
)->size
);
947 std::istringstream
fin(str
);
948 YAML::Parser
parser(fin
);
950 // while(parser.GetNextDocument(doc)) {
951 // yaml_traverse(doc, 0);
953 parser
.GetNextDocument(doc
);
954 yaml_traverse(g
, doc
, NULL
, arg
);
959 int prString_ParseYAMLFile(struct VMGlobals
* g
, int numArgsPushed
)
961 PyrSlot
* arg
= g
->sp
;
963 if (!isKindOfSlot(arg
, class_string
)) return errWrongType
;
965 string
str((const char*)slotRawString(arg
)->s
,slotRawString(arg
)->size
);
967 std::ifstream
fin(str
.c_str());
968 YAML::Parser
parser(fin
);
970 // while(parser.GetNextDocument(doc)) {
971 // yaml_traverse(doc, 0);
973 parser
.GetNextDocument(doc
);
974 yaml_traverse(g
, doc
, NULL
, arg
);
979 void initStringPrimitives();
980 void initStringPrimitives()
984 base
= nextPrimitiveIndex();
986 definePrimitive(base
, index
++, "_StringCompare", prStringCompare
, 3, 0);
987 definePrimitive(base
, index
++, "_StringHash", prStringHash
, 1, 0);
988 definePrimitive(base
, index
++, "_StringPathMatch", prStringPathMatch
, 1, 0);
989 definePrimitive(base
, index
++, "_StringAsSymbol", prStringAsSymbol
, 1, 0);
990 definePrimitive(base
, index
++, "_String_AsInteger", prString_AsInteger
, 1, 0);
991 definePrimitive(base
, index
++, "_String_AsFloat", prString_AsFloat
, 1, 0);
992 definePrimitive(base
, index
++, "_String_AsCompileString", prString_AsCompileString
, 1, 0);
993 definePrimitive(base
, index
++, "_String_Getenv", prString_Getenv
, 1, 0);
994 definePrimitive(base
, index
++, "_String_Setenv", prString_Setenv
, 2, 0);
995 definePrimitive(base
, index
++, "_String_Find", prString_Find
, 4, 0);
996 definePrimitive(base
, index
++, "_String_FindBackwards", prString_FindBackwards
, 4, 0);
997 definePrimitive(base
, index
++, "_String_Format", prString_Format
, 2, 0);
998 definePrimitive(base
, index
++, "_String_Regexp", prString_Regexp
, 4, 0);
999 definePrimitive(base
, index
++, "_String_FindRegexp", prString_FindRegexp
, 3, 0);
1000 definePrimitive(base
, index
++, "_StripRtf", prStripRtf
, 1, 0);
1001 definePrimitive(base
, index
++, "_StripHtml", prStripHtml
, 1, 0);
1002 definePrimitive(base
, index
++, "_String_StandardizePath", prString_StandardizePath
, 1, 0);
1003 definePrimitive(base
, index
++, "_String_EscapeChar", prString_EscapeChar
, 2, 0);
1004 definePrimitive(base
, index
++, "_String_ParseYAML", prString_ParseYAML
, 1, 0);
1005 definePrimitive(base
, index
++, "_String_ParseYAMLFile", prString_ParseYAMLFile
, 1, 0);
1011 #include "SCPlugin.h"
1013 // export the function that SC will call to load the plug in.
1015 extern "C" { SCPlugIn
* loadPlugIn(void); }
1019 // define plug in object
1020 class APlugIn
: public SCPlugIn
1026 virtual void AboutToCompile();
1031 // constructor for plug in
1036 // destructor for plug in
1039 void APlugIn::AboutToCompile()
1041 // this is called each time the class library is compiled.
1042 initStringPrimitives();
1045 // This function is called when the plug in is loaded into SC.
1046 // It returns an instance of APlugIn.
1047 SCPlugIn
* loadPlugIn()
1049 return new APlugIn();