// Attempt to parse the source files in the specified directory and add them to // the given package AST // @return true on success, false on error static bool parse_files_in_dir(ast_t* package, const char* dir_path, pass_opt_t* options) { PONY_ERRNO err = 0; PONY_DIR* dir = pony_opendir(dir_path, &err); if(dir == NULL) { switch(err) { case EACCES: errorf(dir_path, "permission denied"); break; case ENOENT: errorf(dir_path, "does not exist"); break; case ENOTDIR: errorf(dir_path, "not a directory"); break; default: errorf(dir_path, "unknown error"); break; } return false; } PONY_DIRINFO dirent; PONY_DIRINFO* d; bool r = true; while(pony_dir_entry_next(dir, &dirent, &d) && (d != NULL)) { // Handle only files with the specified extension that don't begin with // a dot. This avoids including UNIX hidden files in a build. char* name = pony_dir_info_name(d); if(name[0] == '.') continue; const char* p = strrchr(name, '.'); if((p != NULL) && (strcmp(p, EXTENSION) == 0)) { char fullpath[FILENAME_MAX]; path_cat(dir_path, name, fullpath); r &= parse_source_file(package, fullpath, options); } } pony_closedir(dir); return r; }
// Attempt to parse the source files in the specified directory and add them to // the given package AST // @return true on success, false on error static bool parse_files_in_dir(ast_t* package, const char* dir_path, pass_opt_t* opt) { PONY_ERRNO err = 0; PONY_DIR* dir = pony_opendir(dir_path, &err); errors_t* errors = opt->check.errors; if(dir == NULL) { switch(err) { case EACCES: errorf(errors, dir_path, "permission denied"); break; case ENOENT: errorf(errors, dir_path, "does not exist"); break; case ENOTDIR: errorf(errors, dir_path, "not a directory"); break; default: errorf(errors, dir_path, "unknown error"); break; } return false; } size_t count = 0; size_t buf_size = 4 * sizeof(const char*); const char** entries = (const char**)ponyint_pool_alloc_size(buf_size); PONY_DIRINFO* d; while((d = pony_dir_entry_next(dir)) != NULL) { // Handle only files with the specified extension that don't begin with // a dot. This avoids including UNIX hidden files in a build. const char* name = stringtab(pony_dir_info_name(d)); if(name[0] == '.') continue; const char* p = strrchr(name, '.'); if((p != NULL) && (strcmp(p, EXTENSION) == 0)) { if((count * sizeof(const char*)) == buf_size) { size_t new_buf_size = buf_size * 2; entries = (const char**)ponyint_pool_realloc_size(buf_size, new_buf_size, entries); buf_size = new_buf_size; } entries[count++] = name; } } pony_closedir(dir); // In order for package signatures to be deterministic, file parsing order // must be deterministic too. qsort(entries, count, sizeof(const char*), string_compare); bool r = true; for(size_t i = 0; i < count; i++) { char fullpath[FILENAME_MAX]; path_cat(dir_path, entries[i], fullpath); r &= parse_source_file(package, fullpath, opt); } ponyint_pool_free_size(buf_size, entries); return r; }