fixed string bug; improved file list behavior

master
Allen Webster 2017-02-10 13:02:17 -05:00
parent 2308856c05
commit 9ef04f5dc5
6 changed files with 89 additions and 84 deletions

View File

@ -2152,16 +2152,16 @@ Get_File_List(Application_Links *app, char *dir, int32_t len)
/* /*
DOC_PARAM(dir, This parameter specifies the directory whose files will be enumerated in the returned list; it need not be null terminated.) DOC_PARAM(dir, This parameter specifies the directory whose files will be enumerated in the returned list; it need not be null terminated.)
DOC_PARAM(len, This parameter the length of the dir string.) DOC_PARAM(len, This parameter the length of the dir string.)
DOC_RETURN( DOC_RETURN(This call returns a File_List struct containing pointers to the names of the files in the specified directory. The File_List returned should be passed to free_file_list when it is no longer in use.)
This call returns a File_List struct containing pointers to the names of the files in
the specified directory. The File_List returned should be passed to free_file_list
when it is no longer in use.
)
*/{ */{
Command_Data *cmd = (Command_Data*)app->cmd_context; Command_Data *cmd = (Command_Data*)app->cmd_context;
System_Functions *system = cmd->system; System_Functions *system = cmd->system;
Partition *part = &cmd->models->mem.part;
File_List result = {}; File_List result = {};
system->set_file_list(&result, make_string(dir, len)); Temp_Memory temp = begin_temp_memory(part);
String str = make_string_terminated(part, dir, len);
system->set_file_list(&result, str.str);
end_temp_memory(temp);
return(result); return(result);
} }
@ -2173,7 +2173,7 @@ DOC(After this call the file list passed in should not be read or written to.)
*/{ */{
Command_Data *cmd = (Command_Data*)app->cmd_context; Command_Data *cmd = (Command_Data*)app->cmd_context;
System_Functions *system = cmd->system; System_Functions *system = cmd->system;
system->set_file_list(&list, make_string(0, 0)); system->set_file_list(&list, 0);
} }
API_EXPORT void API_EXPORT void

View File

@ -21,8 +21,7 @@ handle_equal(Plat_Handle a, Plat_Handle b){
return(result); return(result);
} }
// TODO(allen): make directory a char* to signal that it must be null terminated #define Sys_Set_File_List_Sig(name) void name(File_List *file_list, char *directory)
#define Sys_Set_File_List_Sig(name) void name(File_List *file_list, String directory)
typedef Sys_Set_File_List_Sig(System_Set_File_List); typedef Sys_Set_File_List_Sig(System_Set_File_List);
#define Sys_Get_Canonical_Sig(name) i32 name(char *filename, i32 len, char *buffer, i32 max) #define Sys_Get_Canonical_Sig(name) i32 name(char *filename, i32 len, char *buffer, i32 max)

View File

@ -59,14 +59,14 @@ hot_directory_fixup(Hot_Directory *hot_directory){
inline void inline void
hot_directory_set(System_Functions *system, Hot_Directory *hot_directory, String str){ hot_directory_set(System_Functions *system, Hot_Directory *hot_directory, String str){
b32 success = copy_checked_ss(&hot_directory->string, str); copy_checked_ss(&hot_directory->string, str);
terminate_with_null(&hot_directory->string); b32 success = terminate_with_null(&hot_directory->string);
if (success){ if (success){
if (str.size > 0){ if (str.size > 0){
system->set_file_list(&hot_directory->file_list, str); system->set_file_list(&hot_directory->file_list, hot_directory->string.str);
} }
else{ else{
system->set_file_list(&hot_directory->file_list, make_string((char*)1, 0)); system->set_file_list(&hot_directory->file_list, 0);
} }
} }
hot_directory_fixup(hot_directory); hot_directory_fixup(hot_directory);
@ -74,8 +74,7 @@ hot_directory_set(System_Functions *system, Hot_Directory *hot_directory, String
inline void inline void
hot_directory_reload(System_Functions *system, Hot_Directory *hot_directory){ hot_directory_reload(System_Functions *system, Hot_Directory *hot_directory){
system->set_file_list(&hot_directory->file_list, hot_directory->string); hot_directory_set(system, hot_directory, hot_directory->string);
hot_directory_fixup(hot_directory);
} }
internal void internal void

View File

@ -337,77 +337,76 @@ Sys_Set_File_List_Sig(system_set_file_list){
struct dirent *entry; struct dirent *entry;
char *fname, *cursor, *cursor_start; char *fname, *cursor, *cursor_start;
File_Info *info_ptr; File_Info *info_ptr;
i32 count, file_count, size, required_size; i32 character_count, file_count, size, required_size, length;
b32 clear_list = false;
if(directory.size <= 0){ if(directory == 0){
if(!directory.str){ system_free_memory(file_list->block);
system_free_memory(file_list->block); file_list->block = 0;
file_list->block = 0; file_list->block_size = 0;
file_list->block_size = 0;
}
file_list->infos = 0; file_list->infos = 0;
file_list->count = 0; file_list->count = 0;
return; return;
} }
char* dir = (char*) alloca(directory.size + 1); LINUX_FN_DEBUG("%s", directory);
memcpy(dir, directory.str, directory.size);
dir[directory.size] = 0;
LINUX_FN_DEBUG("%s", dir); d = opendir(directory);
d = opendir(dir);
if (d){ if (d){
count = 0; character_count = 0;
file_count = 0; file_count = 0;
for (entry = readdir(d); for (entry = readdir(d);
entry != 0; entry != 0;
entry = readdir(d)){ entry = readdir(d)){
fname = entry->d_name; fname = entry->d_name;
if(fname[0] == '.' && (fname[1] == 0 || (fname[1] == '.' && fname[2] == 0))){ if (match_cc(fname, ".") || match_cc(fname, "..")){
continue; continue;
} }
++file_count; ++file_count;
for (size = 0; fname[size]; ++size); for (size = 0; fname[size]; ++size);
count += size + 1; character_count += size + 1;
} }
required_size = count + file_count * sizeof(File_Info); required_size = character_count + file_count * sizeof(File_Info);
if (file_list->block_size < required_size){ if (file_list->block_size < required_size){
system_free_memory(file_list->block); system_free_memory(file_list->block);
file_list->block = system_get_memory(required_size); file_list->block = system_get_memory(required_size);
file_list->block_size = required_size;
} }
file_list->infos = (File_Info*)file_list->block; file_list->infos = (File_Info*)file_list->block;
cursor = (char*)(file_list->infos + file_count); cursor = (char*)(file_list->infos + file_count);
rewinddir(d); if (file_list->block != 0){
info_ptr = file_list->infos; rewinddir(d);
for (entry = readdir(d); info_ptr = file_list->infos;
entry != 0; for (entry = readdir(d);
entry = readdir(d)){ entry != 0;
fname = entry->d_name; entry = readdir(d)){
if(fname[0] == '.' && (fname[1] == 0 || (fname[1] == '.' && fname[2] == 0))){ fname = entry->d_name;
continue; if (match_cc(fname, ".") || match_cc(fname, "..")){
} continue;
cursor_start = cursor;
for (; *fname; ) *cursor++ = *fname++;
if(entry->d_type == DT_LNK){
struct stat st;
if(stat(entry->d_name, &st) != -1){
info_ptr->folder = S_ISDIR(st.st_mode);
} else {
info_ptr->folder = 0;
} }
} else { cursor_start = cursor;
info_ptr->folder = entry->d_type == DT_DIR; length = copy_fast_unsafe_cc(cursor_start, fname);
} cursor += length;
info_ptr->filename = cursor_start; if(entry->d_type == DT_LNK){
info_ptr->filename_len = (int)(cursor - cursor_start); struct stat st;
*cursor++ = 0; if(stat(entry->d_name, &st) != -1){
++info_ptr; info_ptr->folder = S_ISDIR(st.st_mode);
} else {
info_ptr->folder = 0;
}
} else {
info_ptr->folder = (entry->d_type == DT_DIR);
}
info_ptr->filename = cursor_start;
info_ptr->filename_len = length;
*cursor++ = 0;
++info_ptr;
}
} }
file_list->count = file_count; file_list->count = file_count;

View File

@ -819,12 +819,15 @@ DOC_SEE(find_substr)*/{
i32_4tech i, j, k; i32_4tech i, j, k;
b32_4tech hit; b32_4tech hit;
char a_upper, b_upper; char a_upper, b_upper;
char first_test_char;
if (seek.size == 0){ if (seek.size == 0){
return str_size(str); return str_size(str);
} }
first_test_char = char_to_upper(seek.str[0]);
for (i = start; str[i]; ++i){ for (i = start; str[i]; ++i){
if (str[i] == seek.str[0]){ a_upper = char_to_upper(str[i]);
if (a_upper == first_test_char){
hit = 1; hit = 1;
for (j = 1, k = i+1; j < seek.size; ++j, ++k){ for (j = 1, k = i+1; j < seek.size; ++j, ++k){
a_upper = char_to_upper(str[k]); a_upper = char_to_upper(str[k]);
@ -854,13 +857,16 @@ DOC_SEE(find_substr)*/{
i32_4tech stop_at; i32_4tech stop_at;
b32_4tech hit; b32_4tech hit;
char a_upper, b_upper; char a_upper, b_upper;
char first_test_char;
if (seek.size == 0){ if (seek.size == 0){
return str.size; return str.size;
} }
stop_at = str.size - seek.size + 1; stop_at = str.size - seek.size + 1;
first_test_char = char_to_upper(seek.str[0]);
for (i = start; i < stop_at; ++i){ for (i = start; i < stop_at; ++i){
if (str.str[i] == seek.str[0]){ a_upper = char_to_upper(str.str[i]);
if (a_upper == first_test_char){
hit = 1; hit = 1;
for (j = 1, k = i+1; j < seek.size; ++j, ++k){ for (j = 1, k = i+1; j < seek.size; ++j, ++k){
a_upper = char_to_upper(str.str[k]); a_upper = char_to_upper(str.str[k]);

View File

@ -739,10 +739,11 @@ Sys_File_Can_Be_Made_Sig(system_file_can_be_made){
internal internal
Sys_Set_File_List_Sig(system_set_file_list){ Sys_Set_File_List_Sig(system_set_file_list){
if (directory.size > 0){ b32 clear_list = false;
if (directory != 0){
char dir_space[MAX_PATH + 32]; char dir_space[MAX_PATH + 32];
String dir = make_string_cap(dir_space, 0, MAX_PATH + 32); String dir = make_string_cap(dir_space, 0, MAX_PATH + 32);
append_ss(&dir, directory); append_sc(&dir, directory);
append_ss(&dir, make_lit_string("\\*")); append_ss(&dir, make_lit_string("\\*"));
terminate_with_null(&dir); terminate_with_null(&dir);
@ -753,49 +754,48 @@ Sys_Set_File_List_Sig(system_set_file_list){
search = FindFirstFileA(c_str_dir, &find_data); search = FindFirstFileA(c_str_dir, &find_data);
if (search != INVALID_HANDLE_VALUE){ if (search != INVALID_HANDLE_VALUE){
i32 count = 0; i32 character_count = 0;
i32 file_count = 0; i32 file_count = 0;
BOOL more_files = 1; BOOL more_files = true;
do{ do{
if (!match_cs(find_data.cFileName, make_lit_string(".")) && if (!match_cs(find_data.cFileName, make_lit_string(".")) &&
!match_cs(find_data.cFileName, make_lit_string(".."))){ !match_cs(find_data.cFileName, make_lit_string(".."))){
++file_count; ++file_count;
i32 size = 0; i32 size = 0;
for(;find_data.cFileName[size];++size); for(;find_data.cFileName[size];++size);
count += size + 1; character_count += size + 1;
} }
more_files = FindNextFile(search, &find_data); more_files = FindNextFile(search, &find_data);
}while(more_files); }while(more_files);
FindClose(search); FindClose(search);
i32 required_size = count + file_count * sizeof(File_Info); i32 required_size = character_count + file_count * sizeof(File_Info);
if (file_list->block_size < required_size){ if (file_list->block_size < required_size){
Win32FreeMemory(file_list->block); system_free_memory(file_list->block);
file_list->block = Win32GetMemory(required_size); file_list->block = system_get_memory(required_size);
file_list->block_size = required_size; file_list->block_size = required_size;
} }
file_list->infos = (File_Info*)file_list->block; file_list->infos = (File_Info*)file_list->block;
char *name = (char*)(file_list->infos + file_count); char *name = (char*)(file_list->infos + file_count);
if (file_list->block){ if (file_list->block != 0){
search = FindFirstFileA(c_str_dir, &find_data); search = FindFirstFileA(c_str_dir, &find_data);
if (search != INVALID_HANDLE_VALUE){ if (search != INVALID_HANDLE_VALUE){
File_Info *info = file_list->infos; File_Info *info = file_list->infos;
more_files = 1; more_files = true;
do{ do{
if (!match_cs(find_data.cFileName, make_lit_string(".")) && if (!match_cs(find_data.cFileName, make_lit_string(".")) &&
!match_cs(find_data.cFileName, make_lit_string(".."))){ !match_cs(find_data.cFileName, make_lit_string(".."))){
info->folder = (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; info->folder = (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
info->filename = name; info->filename = name;
i32 i = 0; i32 length = copy_fast_unsafe_cc(name, find_data.cFileName);
for(;find_data.cFileName[i];++i) *name++ = find_data.cFileName[i]; name += length;
info->filename_len = i;
info->filename_len = length;
*name++ = 0; *name++ = 0;
String fname = make_string_cap(info->filename, String fname = make_string_cap(info->filename, info->filename_len, info->filename_len+1);
info->filename_len,
info->filename_len+1);
replace_char(&fname, '\\', '/'); replace_char(&fname, '\\', '/');
++info; ++info;
} }
@ -804,21 +804,23 @@ Sys_Set_File_List_Sig(system_set_file_list){
FindClose(search); FindClose(search);
file_list->count = file_count; file_list->count = file_count;
}else{ }else{
Win32FreeMemory(file_list->block); clear_list = true;
file_list->block = 0;
file_list->block_size = 0;
} }
} }
} }
else{
clear_list = true;
}
} }
else{ else{
if (directory.str == 0){ clear_list = true;
Win32FreeMemory(file_list->block); }
file_list->block = 0;
file_list->block_size = 0; if (clear_list){
} Win32FreeMemory(file_list->block);
file_list->block = 0;
file_list->block_size = 0;
file_list->infos = 0; file_list->infos = 0;
file_list->count = 0; file_list->count = 0;
} }