From 7798ef03207a0c15d2ec7325c1b84b4cb0d7330f Mon Sep 17 00:00:00 2001 From: Positron Date: Sun, 23 Apr 2017 16:01:50 -0400 Subject: [PATCH] Improve finding of include files --- src/common.c | 10 +++ src/common.h | 1 + src/parse/library.c | 16 +++-- src/parse/phase.h | 16 +---- src/parse/token/source.c | 133 ++++++++++++++++++++++++++------------- 5 files changed, 111 insertions(+), 65 deletions(-) diff --git a/src/common.c b/src/common.c index 1236bb3f..adda991e 100755 --- a/src/common.c +++ b/src/common.c @@ -702,6 +702,16 @@ void c_extract_dirname( struct str* path ) { } } +const char* c_get_file_ext( const char* path ) { + const char* string = strrchr( path, '.' ); + if ( string ) { + return string + 1; + } + else { + return ""; + } +} + void fs_get_file_contents( const char* path, struct file_contents* contents ) { FILE* fh = fopen( path, "rb" ); if ( ! fh ) { diff --git a/src/common.h b/src/common.h index 629d4d15..e07bc655 100755 --- a/src/common.h +++ b/src/common.h @@ -197,6 +197,7 @@ bool c_read_fileid( struct fileid*, const char* path ); bool c_same_fileid( struct fileid*, struct fileid* ); bool c_read_full_path( const char* path, struct str* ); void c_extract_dirname( struct str* ); +const char* c_get_file_ext( const char* path ); int alignpad( int size, int align_size ); diff --git a/src/parse/library.c b/src/parse/library.c index d7216290..8cbd8f1d 100755 --- a/src/parse/library.c +++ b/src/parse/library.c @@ -884,11 +884,9 @@ void read_imported_libs( struct parse* parse ) { } void import_lib( struct parse* parse, struct import_dirc* dirc ) { - struct file_query query; - t_init_file_query( &query, t_get_lang_lib_dir( parse->task, parse->lang ), - parse->task->library_main->file, dirc->file_path ); - t_find_file( parse->task, &query ); - if ( ! query.file ) { + struct file_entry* file = p_find_module_file( parse, + parse->task->library_main, dirc->file_path ); + if ( ! file ) { p_diag( parse, DIAG_POS_ERR, &dirc->pos, "library not found: %s", dirc->file_path ); p_bail( parse ); @@ -899,21 +897,21 @@ void import_lib( struct parse* parse, struct import_dirc* dirc ) { list_iterate( &parse->task->libraries, &i ); while ( ! list_end( &i ) ) { lib = list_data( &i ); - if ( lib->file == query.file ) { + if ( lib->file == file ) { goto have_lib; } list_next( &i ); } // Load library from cache. if ( parse->cache ) { - lib = cache_get( parse->cache, query.file ); + lib = cache_get( parse->cache, file ); if ( lib ) { goto have_lib; } } // Read library from source file. lib = t_add_library( parse->task ); - lib->lang = p_determine_lang_from_file_path( query.file->full_path.value ); + lib->lang = p_determine_lang_from_file_path( file->full_path.value ); list_append( &parse->task->libraries, lib ); if ( lib->lang == LANG_BCS && parse->lib->lang == LANG_ACS ) { p_diag( parse, DIAG_POS_ERR, &dirc->pos, @@ -923,7 +921,7 @@ void import_lib( struct parse* parse, struct import_dirc* dirc ) { parse->lang = lib->lang; parse->lang_limits = t_get_lang_limits( lib->lang ); parse->lib = lib; - p_load_imported_lib_source( parse, dirc, query.file ); + p_load_imported_lib_source( parse, dirc, file ); parse->ns_fragment = lib->upmost_ns_fragment; parse->ns = parse->ns_fragment->ns; p_clear_macros( parse ); diff --git a/src/parse/phase.h b/src/parse/phase.h index f6ef068a..6069e2fd 100755 --- a/src/parse/phase.h +++ b/src/parse/phase.h @@ -300,17 +300,6 @@ struct source_entry { bool line_beginning; }; -struct request { - const char* given_path; - struct file_entry* file; - struct file_entry* offset_file; - struct source* source; - bool err_open; - bool err_loading; - bool err_loaded_before; - bool bcs_ext; -}; - struct dec { enum { DEC_TOP, @@ -470,6 +459,8 @@ void p_bail( struct parse* parse ); void p_load_main_source( struct parse* parse ); void p_load_imported_lib_source( struct parse* parse, struct import_dirc* dirc, struct file_entry* file ); +struct file_entry* p_find_module_file( struct parse* parse, + struct library* importing_module, const char* path ); void p_read_tk( struct parse* parse ); void p_read_preptk( struct parse* parse ); void p_read_expanpreptk( struct parse* parse ); @@ -517,9 +508,6 @@ void p_unexpect_last_name( struct parse* parse, struct pos* pos, const char* subject ); void p_load_library( struct parse* parent ); void p_deinit_tk( struct parse* parse ); -void p_init_request( struct request* request, struct file_entry* offset_file, - const char* path, bool bcs_ext ); -void p_load_source( struct parse* parse, struct request* request ); void p_read_source( struct parse* parse, struct token* token ); bool p_read_dirc( struct parse* parse ); void p_confirm_ifdircs_closed( struct parse* parse ); diff --git a/src/parse/token/source.c b/src/parse/token/source.c index b5fefd60..676a4af9 100755 --- a/src/parse/token/source.c +++ b/src/parse/token/source.c @@ -7,8 +7,28 @@ enum { LINE_OFFSET = 1 }; +struct request { + const char* given_path; + const char* lang_dir; + struct file_entry* file; + struct file_entry* offset_file; + struct source* source; + bool err_open; + bool err_loading; + bool err_loaded_before; + bool implicit_bcs_ext; +}; + static void append_file( struct library* lib, struct file_entry* file ); +static void init_request( struct request* request, + struct file_entry* offset_file, const char* path ); +static void init_request_module( struct request* request, + struct file_entry* file ); +static void add_lang_dir( struct parse* parse, struct request* request ); +static void load_source( struct parse* parse, struct request* request ); +static void find_source( struct parse* parse, struct request* request ); static bool source_loading( struct parse* parse, struct request* request ); +static void load_module( struct parse* parse, struct request* request ); static void open_source_file( struct parse* parse, struct request* request ); static struct source* alloc_source( struct parse* parse ); static void reset_filepos( struct source* source ); @@ -29,8 +49,8 @@ static void append_ch( struct str* str, char ch ); void p_load_main_source( struct parse* parse ) { struct request request; - p_init_request( &request, NULL, parse->task->options->source_file, false ); - p_load_source( parse, &request ); + init_request( &request, NULL, parse->task->options->source_file ); + load_source( parse, &request ); if ( request.source ) { parse->lib->file = request.file; parse->lib->file_pos.id = request.file->id; @@ -50,9 +70,8 @@ void p_load_main_source( struct parse* parse ) { void p_load_imported_lib_source( struct parse* parse, struct import_dirc* dirc, struct file_entry* file ) { struct request request; - p_init_request( &request, NULL, file->full_path.value, false ); - request.file = file; - open_source_file( parse, &request ); + init_request_module( &request, file ); + load_module( parse, &request ); if ( request.source ) { parse->lib->file = file; parse->lib->file_pos.id = file->id; @@ -67,21 +86,21 @@ void p_load_imported_lib_source( struct parse* parse, struct import_dirc* dirc, } } +struct file_entry* p_find_module_file( struct parse* parse, + struct library* importing_module, const char* path ) { + struct request request; + init_request( &request, importing_module->file, path ); + add_lang_dir( parse, &request ); + find_source( parse, &request ); + return request.file; +} + void p_load_included_source( struct parse* parse, const char* file_path, struct pos* pos ) { - bool bcs_ext = false; - if ( parse->lang == LANG_BCS ) { - const char* ext = ""; - for ( int i = 0; file_path[ i ]; ++i ) { - if ( file_path[ i ] == '.' ) { - ext = file_path + i + 1; - } - } - bcs_ext = ( strcasecmp( ext, "h" ) == 0 ); - } struct request request; - p_init_request( &request, parse->source->file, file_path, bcs_ext ); - p_load_source( parse, &request ); + init_request( &request, parse->source->file, file_path ); + add_lang_dir( parse, &request ); + load_source( parse, &request ); if ( request.source ) { append_file( parse->lib, request.file ); create_entry( parse, &request, false ); @@ -130,59 +149,85 @@ void append_file( struct library* lib, struct file_entry* file ) { list_append( &lib->files, file ); } -void p_init_request( struct request* request, struct file_entry* offset_file, - const char* path, bool bcs_ext ) { +static void init_request( struct request* request, + struct file_entry* offset_file, const char* path ) { request->given_path = path; + request->lang_dir = NULL; request->file = NULL; request->offset_file = offset_file; request->source = NULL; request->err_open = false; request->err_loaded_before = false; request->err_loading = false; - request->bcs_ext = bcs_ext; + request->implicit_bcs_ext = false; +} + +static void init_request_module( struct request* request, + struct file_entry* file ) { + init_request( request, NULL, file->full_path.value ); + request->file = file; } -// TODO: Refactor. -void p_load_source( struct parse* parse, struct request* request ) { - if ( request->bcs_ext ) { +static void add_lang_dir( struct parse* parse, struct request* request ) { + const char* ext = c_get_file_ext( request->given_path ); + if ( strcasecmp( ext, "bcs" ) == 0 ) { + request->lang_dir = t_get_lang_lib_dir( parse->task, LANG_BCS ); + } + else if ( strcasecmp( ext, "h" ) == 0 && parse->lang == LANG_BCS ) { + request->lang_dir = t_get_lang_lib_dir( parse->task, LANG_BCS ); + request->implicit_bcs_ext = true; + } + else if ( strcasecmp( ext, "acs" ) == 0 ) { + request->lang_dir = t_get_lang_lib_dir( parse->task, LANG_ACS ); + } + else { + request->lang_dir = t_get_lang_lib_dir( parse->task, parse->lang ); + } +} + +void load_source( struct parse* parse, struct request* request ) { + find_source( parse, request ); + if ( request->file ) { + if ( ! source_loading( parse, request ) ) { + open_source_file( parse, request ); + } + else { + request->err_loading = true; + } + } + else { + request->err_open = true; + } +} + +static void find_source( struct parse* parse, struct request* request ) { + if ( request->implicit_bcs_ext ) { struct str path; str_init( &path ); str_append( &path, request->given_path ); str_append( &path, ".bcs" ); struct file_query query; t_init_file_query( &query, - t_get_lang_lib_dir( parse->task, parse->lang ), request->offset_file, + request->lang_dir, + request->offset_file, path.value ); t_find_file( parse->task, &query ); if ( query.success ) { request->file = query.file; - if ( ! source_loading( parse, request ) ) { - open_source_file( parse, request ); - } - else { - request->err_loading = true; - } } str_deinit( &path ); - if ( request->source || request->err_loading ) { + if ( request->source ) { return; } } struct file_query query; - t_init_file_query( &query, t_get_lang_lib_dir( parse->task, parse->lang ), - request->offset_file, request->given_path ); + t_init_file_query( &query, + request->lang_dir, + request->offset_file, + request->given_path ); t_find_file( parse->task, &query ); if ( query.success ) { request->file = query.file; - if ( ! source_loading( parse, request ) ) { - open_source_file( parse, request ); - } - else { - request->err_loading = true; - } - } - else { - request->err_open = true; } } @@ -195,6 +240,10 @@ bool source_loading( struct parse* parse, struct request* request ) { return ( entry != NULL ); } +static void load_module( struct parse* parse, struct request* request ) { + open_source_file( parse, request ); +} + void open_source_file( struct parse* parse, struct request* request ) { FILE* fh = fopen( request->file->full_path.value, "rb" ); if ( ! fh ) {