#include <math.h> #include <stdlib.h> #include <stdio.h> #include <sys/stat.h> #include "forge.h" #include "imagine.h" #include "assemble_json.h" #include "observatory_internal.h" ObsFile *observatory_files_gather_recursivly(ObsFile *files, uint *count, char *file_name_buffer, uint used) { char copy[1024]; IDir *dir; uint i, j, progress, write; progress = *count; dir = imagine_path_dir_open(file_name_buffer); /* Opens a path for traversial. If the path is not legal or not a directry the fuction will return NULL. */ while(imagine_path_dir_next(dir, &file_name_buffer[used], 1024 - used)) { if(file_name_buffer[used] != '.') { if(imagine_path_is_dir(file_name_buffer)) { // printf("dir: %s\n", file_name_buffer); if(!f_text_filter_case_insensitive(&file_name_buffer[used], "debug") && !f_text_filter_case_insensitive(&file_name_buffer[used], "deprecated")) { for(i = used; file_name_buffer[i] != 0; i++); file_name_buffer[i] = '/'; file_name_buffer[i + 1] = 0; files = observatory_files_gather_recursivly(files, &progress, file_name_buffer, i + 1); file_name_buffer[used] = 0; } }else { if(!f_text_filter_case_insensitive(&file_name_buffer[used], "old")) { size_t modify_time; imagine_path_file_stats(file_name_buffer, NULL, NULL, &modify_time); /* Outputs stats about a file. */ for(i = 0; i < progress; i++) { for(j = 0; file_name_buffer[used + j] != 0 && file_name_buffer[used + j] == files[i].path[files[i].file_start + j]; j++); if(file_name_buffer[used + j] == files[i].path[files[i].file_start + j]) { if(files[i].time < modify_time) { for(j = 0; file_name_buffer[j] != 0 && j < 1024 - 1; j++) files[i].path[j] = file_name_buffer[j]; files[i].path[j] = 0; files[i].file_start = used; files[i].time = modify_time; } // printf("duplicate\n"); break; } } if(i == progress) { if(progress % 256 == 0) files = realloc(files, (sizeof *files) * (progress + 256)); for(i = 0; file_name_buffer[i] != 0 && i < 1024 - 1; i++) files[progress].path[i] = file_name_buffer[i]; files[progress].path[i] = 0; files[progress].file_start = used; files[progress].file = NULL; files[progress].time = modify_time; // printf("%u %s\n",progress, &files[progress].path[files[progress].file_start]); progress++; } } } } } *count = progress; return files; } ObsFile *observatory_files_gather(ObsFile *file, uint *count, char *path) { char file_name_buffer[1024]; uint i; for(i = 0; i < 1024 - 1 && path[i] != 0; i++) file_name_buffer[i] = path[i]; file_name_buffer[i] = 0; return observatory_files_gather_recursivly(file, count, file_name_buffer, i); } boolean oservatory_files_file_in_module(ObsState *state, uint module_id, ObsFile *file) { uint i, j; for(i = 0; i < state->modules[module_id].prefix_count; i++) { for(j = 0; state->modules[module_id].prefixes[i][j] != 0 && state->modules[module_id].prefixes[i][j] == file->path[file->file_start + j]; j++); if(state->modules[module_id].prefixes[i][j] == 0) return TRUE; } if(state->modules[module_id].header[0] == 0) return FALSE; for(j = 0; state->modules[module_id].header[j] != 0 && state->modules[module_id].header[j] == file->path[file->file_start + j]; j++); if(state->modules[module_id].header[j] == 0) return TRUE; return FALSE; } void observatory_files_module_file_list(FILE *f, ObsState *state, uint module_id) { FILE *file; uint i, j, k; char buffer[1024]; if(state->modules[module_id].prefix_count == 0) return; observatory_html_card_begin(f, NULL); observatory_html_headline(f, "File list:", NULL); observatory_html_bullet_point_begin(f, NULL); for(i = 0; i < state->source_file_count; i++) { if((state->modules[module_id].header[0] != 0 && f_text_compare(&state->source_files[i].path[state->source_files[i].file_start], state->modules[module_id].header)) || oservatory_files_file_in_module(state, module_id, &state->source_files[i])) { sprintf(buffer, "./output/source/%s", &state->source_files[i].path[state->source_files[i].file_start]); // file = imagine_path_open(buffer, "wt"); file = fopen(buffer, "wt"); if(file != NULL) { if(state->source_files[i].file == NULL) state->source_files[i].file = f_text_load(state->source_files[i].path, &state->source_files[i].size); j = fwrite(state->source_files[i].file, 1, state->source_files[i].size, file); fclose(file); } sprintf(buffer, "./source/%s", &state->source_files[i].path[state->source_files[i].file_start]); observatory_html_bullet_point(f, &state->source_files[i].path[state->source_files[i].file_start], buffer, NULL, 0, 0, 0); } } observatory_html_bullet_point_end(f); observatory_html_card_end(f); } void observatory_files_module_make_file_add_files(FILE *file, ObsState *state, uint module_id, char *type, char *ending) { uint i, j, k, type_length; char c; for(type_length = 0; type[type_length] != 0; type_length++); for(i = 0; i < state->source_file_count; i++) { if(oservatory_files_file_in_module(state, module_id, &state->source_files[i])) { for(j = state->source_files[i].file_start; state->source_files[i].path[j] != 0; j++); if(j > type_length) { j -= type_length; for(k = 0; state->source_files[i].path[j + k] == type[k] && k < type_length; k++); if(k == type_length) { c = state->source_files[i].path[j]; state->source_files[i].path[j] = 0; fprintf(file, "%s%s ", &state->source_files[i].path[state->source_files[i].file_start], ending); state->source_files[i].path[j] = c; } } } } } boolean observatory_files_dependency_test(ObsState *state, uint module_id, uint dependency_id) { uint j; if(dependency_id != module_id && state->modules[dependency_id].header[0] != 0) { for(j = 0; j < state->source_file_count; j++) { if(oservatory_files_file_in_module(state, module_id, &state->source_files[j])) { if(state->source_files[j].file == NULL) state->source_files[j].file = f_text_load(state->source_files[j].path, &state->source_files[j].size); if(f_text_filter(state->source_files[j].file, state->modules[dependency_id].header)) return TRUE; } } } return FALSE; } void observatory_files_dependency_list(FILE *f, ObsState *state, uint module_id) { uint i, j, count = 0; if(state->modules[module_id].prefix_count == 0) return; for(i = 0; i < state->module_count; i++) { if(observatory_files_dependency_test(state, module_id, i)) { if(count == 0) { observatory_html_card_begin(f, NULL); observatory_html_headline(f, "Dependency list:", NULL); observatory_html_bullet_point_begin(f, NULL); } count++; observatory_html_set_accent_color(state->modules[i].color[0], state->modules[i].color[1], state->modules[i].color[2]); observatory_html_bullet_point(f, state->modules[i].name, NULL, NULL, 0, 0, 0); } } if(count != 0) { observatory_html_bullet_point_end(f); observatory_html_card_end(f); observatory_html_set_accent_color(state->modules[module_id].color[0], state->modules[module_id].color[1], state->modules[module_id].color[2]); } } void observatory_files_module_make_file(ObsState *state, uint module_id) { uint i, j, k; FILE *file; char file_name[256]; if(state->modules[module_id].header[0] != 0) return; sprintf(file_name, "%s_makefile.txt", state->modules[module_id].name); file = fopen(file_name, "w"); fprintf(file, "CC=gcc\n"); fprintf(file, "CFLAGS=-I.\n"); fprintf(file, "DEPS = "); observatory_files_module_make_file_add_files(file, state, module_id, ".h", ".h"); for(i = 0; i < state->module_count; i++) if(observatory_files_dependency_test(state, module_id, i)) observatory_files_module_make_file_add_files(file, state, i, ".h", ".h"); fprintf(file, "\nOBJ = "); observatory_files_module_make_file_add_files(file, state, module_id, ".c", ".o"); for(i = 0; i < state->module_count; i++) if(observatory_files_dependency_test(state, module_id, i)) observatory_files_module_make_file_add_files(file, state, i, ".c", ".o"); fprintf(file, "\n"); fprintf(file, "%%.o: %%.c $(DEPS)\n"); fprintf(file, "$(CC) -c -o $@ $< $(CFLAGS)\n\n"); fprintf(file, "%s: $(OBJ)\n", state->modules[module_id].name); fprintf(file, "$(CC) -o $@ $^ $(CFLAGS)\n"); fclose(file); } /* CC=gcc CFLAGS=-I. DEPS = hellomake.h OBJ = hellomake.o hellofunc.o %.o: %.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) hellomake: $(OBJ) $(CC) -o $@ $^ $(CFLAGS) */ void observatory_files_documentation(FILE *f, ObsState *state) { char buffer[64]; uint i, percentage; float color; observatory_html_card_begin(f, NULL); observatory_html_headline(f, "Documentation:", NULL); observatory_html_bullet_point_begin(f, NULL); for(i = 0; i < state->module_count; i++) { if(state->modules[i].documented != 0 || state->modules[i].undocumented != 0) { observatory_html_set_accent_color(state->modules[i].color[0], state->modules[i].color[1], state->modules[i].color[2]); color = (float)(state->modules[i].documented) / (float)(state->modules[i].documented + state->modules[i].undocumented); percentage = (state->modules[i].documented * 1000) / (state->modules[i].documented + state->modules[i].undocumented); sprintf(buffer, "%u.%u%%", percentage / 10, percentage % 10); observatory_html_bullet_point(f, state->modules[i].name, NULL, buffer, (1 - color) * 255, color * 255, 0); } } observatory_html_bullet_point_end(f); observatory_html_card_end(f); } void observatory_files_help(FILE *f, ObsState *state, uint module_id) { char *text; if(state->modules[module_id].help_string == NULL) return; text = observatory_release_extract_module(state, module_id, state->modules[module_id].help_string); if(text == NULL) return; observatory_html_card_begin(f, NULL); observatory_html_headline(f, "Help:", NULL); observatory_html_text(f, text); free(text); observatory_html_card_end(f); } extern char *observatory_files_read(ObsState *state, char *name, size_t *size) { uint i, j; for(i = 0; i < state->source_file_count; i++) { for(j = 0; name[j] != 0 && name[j] == state->source_files[i].path[state->source_files[i].file_start + j]; j++); if(name[j] == state->source_files[i].path[state->source_files[i].file_start + j]) { if(state->source_files[i].file == NULL) state->source_files[i].file = f_text_load(state->source_files[i].path, &state->source_files[i].size); if(size != NULL) *size = state->source_files[i].size; return state->source_files[i].file; } } return NULL; }