SpiderScript - Fixed array behaviour, removed memory leaks
[tpg/acess2.git] / Usermode / Libraries / libspiderscript.so_src / exports.c
1 /*
2  * Acess2 - SpiderScript
3  * - Script Exports (Lang. Namespace)
4  */
5 #define _GNU_SOURCE     // HACK!
6 #include <string.h>
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <spiderscript.h>
10
11 // === PROTOTYPES ===
12 tSpiderValue    *Exports_sizeof(tSpiderScript *Script, int NArgs, tSpiderValue **Args);
13 tSpiderValue    *Exports_array(tSpiderScript *Script, int NArgs, tSpiderValue **Args);
14 tSpiderValue    *Exports_Lang_Strings_Split(tSpiderScript *Script, int NArgs, tSpiderValue **Args);
15 tSpiderValue    *Exports_Lang_Struct(tSpiderScript *Script, int NArgs, tSpiderValue **Args);
16
17 // === GLOBALS ===
18 tSpiderFunction gExports_Lang_Strings_Split = {
19         .Name = "Split",
20         .Handler = Exports_Lang_Strings_Split,
21         .ReturnType = SS_MAKEARRAY(SS_DATATYPE_STRING),
22         .ArgTypes = {SS_DATATYPE_STRING, SS_DATATYPE_STRING, -1}
23 };
24 tSpiderNamespace        gExports_NS_Lang_Strings = {
25         .Name = "Strings",
26         .Functions = &gExports_Lang_Strings_Split
27         };
28
29 tSpiderFunction gExports_Lang_Struct = {
30         .Name = "Struct",
31         .Handler = Exports_Lang_Struct,
32         .ReturnType = SS_DATATYPE_OPAQUE,
33         .ArgTypes = {SS_DATATYPE_STRING, -1}
34 };
35 // - Lang Namespace
36 tSpiderNamespace        gExports_NS_Lang = {
37         .Name = "Lang",
38         .Functions = &gExports_Lang_Struct,
39         .FirstChild = &gExports_NS_Lang_Strings
40         };
41 tSpiderNamespace        gExportNamespaceRoot = {
42         .FirstChild = &gExports_NS_Lang
43 };
44
45 // -- Global Functions
46 tSpiderFunction gExports_array = {
47         .Next = NULL,
48         .Name = "array",
49         .Handler = Exports_array,
50         .ReturnType = SS_DATATYPE_DYNAMIC,
51         .ArgTypes = {SS_DATATYPE_INTEGER, -1}
52 };
53 tSpiderFunction gExports_sizeof = {
54         .Next = &gExports_array,
55         .Name = "sizeof",
56         .Handler = Exports_sizeof,
57         .ReturnType = SS_DATATYPE_INTEGER,
58         .ArgTypes = {SS_DATATYPE_UNDEF, -1}
59 };
60 tSpiderFunction *gpExports_First = &gExports_sizeof;
61
62 // === CODE ===
63 tSpiderValue *Exports_sizeof(tSpiderScript *Script, int NArgs, tSpiderValue **Args)
64 {
65         if(NArgs != 1 || !Args[0])      return NULL;
66
67         switch( Args[0]->Type )
68         {
69         case SS_DATATYPE_STRING:
70                 return SpiderScript_CreateInteger(Args[0]->String.Length);
71         case SS_DATATYPE_ARRAY:
72                 return SpiderScript_CreateInteger(Args[0]->Array.Length);
73         default:
74                 return NULL;
75         }
76 }
77
78 tSpiderValue *Exports_array(tSpiderScript *Script, int NArgs, tSpiderValue **Args)
79 {
80         if(NArgs != 2)  return ERRPTR;
81         if(!Args[0] || !Args[1])        return ERRPTR;
82         
83         if(Args[0]->Type != SS_DATATYPE_INTEGER || Args[1]->Type != SS_DATATYPE_INTEGER)
84                 return ERRPTR;
85
86          int    type = Args[1]->Integer;
87          int    size = Args[0]->Integer;
88
89         if( type != SS_DATATYPE_ARRAY )
90         {
91                 if( !SS_GETARRAYDEPTH(type) ) {
92                         // ERROR - This should never happen
93                         return ERRPTR;
94                 }
95                 type = SS_DOWNARRAY(type);
96         }
97
98         return SpiderScript_CreateArray(type, size);
99 }
100
101 tSpiderValue *Exports_Lang_Strings_Split(tSpiderScript *Script, int NArgs, tSpiderValue **Args)
102 {
103          int    len, ofs, slen;
104         void    *haystack, *end;
105          int    nSubStrs = 0;
106         tSpiderValue    **strings = NULL;
107         tSpiderValue    *ret;
108
109         // Error checking
110         if( NArgs != 2 )
111                 return ERRPTR;
112         if( !Args[0] || !Args[1] )
113                 return ERRPTR;
114         if( Args[0]->Type != SS_DATATYPE_STRING )
115                 return ERRPTR;
116         if( Args[1]->Type != SS_DATATYPE_STRING )
117                 return ERRPTR;
118
119         // Split the string
120         len = Args[0]->String.Length;
121         haystack = Args[0]->String.Data;
122         ofs = 0;
123         do {
124                 end = memmem(haystack + ofs, len - ofs, Args[1]->String.Data, Args[1]->String.Length);
125                 if( end )
126                         slen = end - (haystack + ofs);
127                 else
128                         slen = len - ofs;
129                 
130                 strings = realloc(strings, (nSubStrs+1)*sizeof(tSpiderValue*));
131                 strings[nSubStrs] = SpiderScript_CreateString(slen, haystack + ofs);
132                 nSubStrs ++;
133
134                 ofs += slen + Args[1]->String.Length;
135         } while(end);
136
137         // Create output array
138         ret = SpiderScript_CreateArray(SS_DATATYPE_STRING, nSubStrs);
139         memcpy(ret->Array.Items, strings, nSubStrs*sizeof(tSpiderValue*));
140         free(strings);
141
142         return ret;
143 }
144
145 tSpiderValue *Exports_Lang_Struct(tSpiderScript *Script, int NArgs, tSpiderValue **Args)
146 {
147          int    i;
148         printf("Exports_Lang_Struct: (Script=%p, NArgs=%i, Args=%p)\n", Script, NArgs, Args);
149         
150         for( i = 0; i < NArgs; i ++ )
151         {
152                 printf(" Args[%i] = {Type: %i, ", i, Args[i]->Type);
153                 switch(Args[i]->Type)
154                 {
155                 case SS_DATATYPE_INTEGER:
156                         printf(" Integer: 0x%lx", Args[i]->Integer);
157                         break;
158                 case SS_DATATYPE_REAL:
159                         printf(" Real: %f", Args[i]->Real);
160                         break;
161                 case SS_DATATYPE_STRING:
162                         printf(" Length: %i, Data = '%s'", Args[i]->String.Length, Args[i]->String.Data);
163                         break;
164                 default:
165                         break;
166                 }
167                 printf("}\n");
168         }
169         
170         return NULL;
171 }

UCC git Repository :: git.ucc.asn.au