bool ofc_parse_file_include( const ofc_sparse_t* src, ofc_parse_stmt_list_t* list, ofc_parse_debug_t* debug) { const char* ptr = ofc_sparse_strz(src); if (!list || !ptr) return false; unsigned dpos = ofc_parse_debug_position(debug); unsigned i; if (!ofc_parse_stmt_sublist( list, src, ptr, debug, &i)) return false; unsigned l = ofc_parse_stmt_program_end( src, &ptr[i], debug, list); if (l > 0) { ofc_sparse_warning(src, ofc_str_ref(&ptr[i], 0), "Implicit PROGRAM statement"); i += l; if (!ofc_parse_stmt_sublist( list, src, &ptr[i], debug, &l)) { ofc_parse_debug_rewind(debug, dpos); return false; } i += l; } if (ptr[i] != '\0') { ofc_sparse_error(src, ofc_str_ref(&ptr[i], 0), "Expected end of input"); ofc_parse_debug_rewind(debug, dpos); return false; } return true; }
unsigned ofc_parse_stmt_include( const ofc_sparse_t* src, const char* ptr, ofc_parse_debug_t* debug, ofc_parse_stmt_t* stmt, ofc_parse_stmt_list_t* list) { unsigned dpos = ofc_parse_debug_position(debug); unsigned i = ofc_parse_keyword( src, ptr, debug, OFC_PARSE_KEYWORD_INCLUDE); if (i == 0) return 0; unsigned l = 0; ofc_string_t* spath = ofc_parse_character( src, &ptr[i], debug, &l); if (!spath) { ofc_parse_debug_rewind(debug, dpos); return 0; } i += l; if (!ofc_is_end_statement(&ptr[i], NULL)) { ofc_parse_debug_rewind(debug, dpos); return 0; } /* Don't rewind debug after this point because we know we have a valid include statement. */ char path[spath->size + 1]; memcpy(path, spath->base, spath->size); path[spath->size] = '\0'; const char* include_path = ofc_sparse_get_include(src); char* rpath = ofc_sparse_include_path(src, path); stmt->include.file = ofc_file_create_include( rpath, ofc_sparse_lang_opts(src), include_path); if (!stmt->include.file) { ofc_sparse_error(src, ofc_str_ref(ptr, i), "Can't open include file '%s'", rpath); free(rpath); return 0; } free(rpath); stmt->include.src = ofc_prep(stmt->include.file); if (!ofc_parse_file_include( stmt->include.src, list, debug)) { ofc_sparse_delete(stmt->include.src); ofc_file_delete(stmt->include.file); return 0; } stmt->type = OFC_PARSE_STMT_INCLUDE; return i; }