LIST * regex_split( FRAME * frame, int flags ) { LIST * args = lol_get( frame->args, 0 ); OBJECT * s; OBJECT * separator; regexp * re; const char * pos; LIST * result = L0; LISTITER iter = list_begin( args ); s = list_item( iter ); separator = list_item( list_next( iter ) ); re = regex_compile( separator ); pos = object_str( s ); while ( regexec( re, pos ) ) { result = list_push_back( result, object_new_range( pos, re->startp[ 0 ] - pos ) ); pos = re->endp[ 0 ]; } result = list_push_back( result, object_new( pos ) ); return result; }
OBJECT * object_new( char const * const string ) { return object_new_range( string, strlen( string ) ); }
static void canonicWindowsPath( char const * const path, int const path_length, string * const out ) { char const * last_element; unsigned long saved_size; char const * p; /* This is only called via path_key(), which initializes the cache. */ assert( path_key_cache ); if ( !path_length ) return; if ( path_length == 1 && path[ 0 ] == '\\' ) { string_push_back( out, '\\' ); return; } if ( path[ 1 ] == ':' && ( path_length == 2 || ( path_length == 3 && path[ 2 ] == '\\' ) ) ) { string_push_back( out, toupper( path[ 0 ] ) ); string_push_back( out, ':' ); string_push_back( out, '\\' ); return; } /* Find last '\\'. */ for ( p = path + path_length - 1; p >= path && *p != '\\'; --p ); last_element = p + 1; /* Special case '\' && 'D:\' - include trailing '\'. */ if ( p == path || p == path + 2 && path[ 1 ] == ':' ) ++p; if ( p >= path ) { char const * const dir = path; int const dir_length = p - path; OBJECT * const dir_obj = object_new_range( dir, dir_length ); int found; path_key_entry * const result = (path_key_entry *)hash_insert( path_key_cache, dir_obj, &found ); if ( !found ) { result->path = dir_obj; canonicWindowsPath( dir, dir_length, out ); result->key = object_new( out->value ); } else { object_free( dir_obj ); string_append( out, object_str( result->key ) ); } } if ( out->size && out->value[ out->size - 1 ] != '\\' ) string_push_back( out, '\\' ); saved_size = out->size; string_append_range( out, last_element, path + path_length ); { char const * const n = last_element; int const n_length = path + path_length - n; if ( !( n_length == 1 && n[ 0 ] == '.' ) && !( n_length == 2 && n[ 0 ] == '.' && n[ 1 ] == '.' ) ) { WIN32_FIND_DATA fd; HANDLE const hf = FindFirstFileA( out->value, &fd ); if ( hf != INVALID_HANDLE_VALUE ) { string_truncate( out, saved_size ); string_append( out, fd.cFileName ); FindClose( hf ); } } } }