99
1010
1111static KlException kllib_string_join_raw (KlState * state , size_t nval , KlValue * vals , KlValue * result );
12- static KlException kllib_string_sub (KlState * state );
12+ static KlException kllib_string_slice (KlState * state );
1313static KlException kllib_string_find (KlState * state );
1414static KlException kllib_string_join (KlState * state );
15+ static KlException kllib_string_split (KlState * state );
1516
1617static KlException kllib_string_utf8idx (KlState * state );
1718static KlException kllib_string_utf8len (KlState * state );
1819
1920static inline size_t kllib_string_utf8charlen (const unsigned char * str ) {
20- unsigned ch = * str ;
21+ unsigned char ch = * str ;
2122 if (ch < 0xC0 ) return 1 ;
2223 if (ch < 0xE0 ) return 2 ;
2324 if (ch < 0xF0 ) return 3 ;
@@ -45,8 +46,12 @@ KlException KLCONFIG_LIBRARY_STRING_ENTRYFUNCNAME(KlState* state) {
4546 klapi_setcfunc (state , -1 , kllib_string_join );
4647 KLAPI_PROTECT (klapi_class_newshared_method (state , strclass , klapi_getstring (state , -2 )));
4748
48- KLAPI_PROTECT (klapi_setstring (state , -2 , "sub" ));
49- klapi_setcfunc (state , -1 , kllib_string_sub );
49+ KLAPI_PROTECT (klapi_setstring (state , -2 , "slice" ));
50+ klapi_setcfunc (state , -1 , kllib_string_slice );
51+ KLAPI_PROTECT (klapi_class_newshared_method (state , strclass , klapi_getstring (state , -2 )));
52+
53+ KLAPI_PROTECT (klapi_setstring (state , -2 , "split" ));
54+ klapi_setcfunc (state , -1 , kllib_string_split );
5055 KLAPI_PROTECT (klapi_class_newshared_method (state , strclass , klapi_getstring (state , -2 )));
5156
5257 KLAPI_PROTECT (klapi_setstring (state , -2 , "utf8len" ));
@@ -60,7 +65,7 @@ KlException KLCONFIG_LIBRARY_STRING_ENTRYFUNCNAME(KlState* state) {
6065 return klapi_return (state , 0 );
6166}
6267
63- static KlException kllib_string_sub (KlState * state ) {
68+ static KlException kllib_string_slice (KlState * state ) {
6469 if (kl_unlikely (klapi_narg (state ) != 2 && klapi_narg (state ) != 3 ))
6570 return klapi_throw_internal (state , KL_E_ARGNO , "expected two or three arguments" );
6671 if (kl_unlikely (!klapi_checktypeb (state , 0 , KL_STRING )))
@@ -124,6 +129,34 @@ static KlException kllib_string_join(KlState* state) {
124129 return klapi_return (state , 1 );
125130}
126131
132+ static KlException kllib_string_split (KlState * state ) {
133+ if (klapi_narg (state ) != 2 )
134+ return klapi_throw_internal (state , KL_E_ARGNO , "expected two arguments" );
135+ if (!klapi_checktype (state , -2 , KL_STRING ) || !klapi_checktype (state , -2 , KL_STRING ))
136+ return klapi_throw_internal (state , KL_E_ARGNO , "expected two strings, got %s, %s" ,
137+ klstring_content (klapi_typename (state , klapi_access (state , -2 ))),
138+ klstring_content (klapi_typename (state , klapi_access (state , -1 ))));
139+ KlString * self = klapi_getstring (state , -2 );
140+ KlString * delim = klapi_getstring (state , -1 );
141+ const char * self_raw = klstring_content (self );
142+ const char * delim_raw = klstring_content (delim );
143+ size_t selflen = klstring_length (self );
144+ size_t delimlen = klstring_length (delim );
145+ const char * begin = self_raw ;
146+ const char * end ;
147+ size_t nret = 0 ;
148+ while ((end = strstr (begin , delim_raw ))) {
149+ ++ nret ;
150+ KLAPI_PROTECT (klapi_checkstack (state , 1 ));
151+ KLAPI_PROTECT (klapi_pushstring_buf (state , begin , end - begin ));
152+ begin = end + delimlen ;
153+ }
154+ ++ nret ;
155+ KLAPI_PROTECT (klapi_checkstack (state , 1 ));
156+ KLAPI_PROTECT (klapi_pushstring_buf (state , begin , self_raw + selflen - begin ));
157+ return klapi_return (state , nret );
158+ }
159+
127160static KlException kllib_string_join_raw (KlState * state , size_t nval , KlValue * vals , KlValue * result ) {
128161 size_t totallen = 0 ;
129162 for (KlValue * val = vals ; val != vals + nval ; ++ val ) {
0 commit comments