diff options
Diffstat (limited to 'git_part.c')
-rw-r--r-- | git_part.c | 218 |
1 files changed, 163 insertions, 55 deletions
@@ -12,6 +12,21 @@ static const char *special_chars[256] ['>']=">", }; +struct Index_File *get_index_file(int dir_fd,const char *name) +{ + struct Index_File *ret; + ret=calloc(sizeof(struct Index_File),1); + ret->out=create_file(dir_fd,name); + + fprintf(ret->out,"<pre>\n"); + return ret; +} +void release_index_file(struct Index_File *index) +{ + fprintf(index->out,"</pre>\n"); + close_file(index->out); + free(index); +} int print_diff_line(const git_diff_delta *delta,const git_diff_hunk *hunk,const git_diff_line *line,FILE *out) { @@ -25,9 +40,9 @@ int print_diff_line(const git_diff_delta *delta,const git_diff_hunk *hunk,const fprintf(out,"%c ",line->origin); for(i=0;i<line->content_len;++i) - if(special_chars[line->content[i]]) + if(special_chars[(unsigned char)line->content[i]]) { - fwrite(special_chars[line->content[i]],1,strlen(special_chars[line->content[i]]),out); + fwrite(special_chars[line->content[i]],1,strlen(special_chars[(unsigned char)line->content[i]]),out); }else { fwrite(line->content+i,1,1,out); @@ -162,95 +177,188 @@ void print_branches(git_repository *repo) git_branch_iterator_free(it); } -void print_files(int dir_fd,git_tree *tree,git_repository *repo) +void print_files(struct Index_File *index_file,int dir_fd,git_tree *tree,git_repository *repo) { size_t number_of_entries; size_t i; const git_tree_entry *current_entry; - FILE *index_file; number_of_entries=git_tree_entrycount(tree); - index_file=create_file(dir_fd,"index"); for(i=0;i<number_of_entries;++i) { current_entry=git_tree_entry_byindex(tree,i); + + if(i<number_of_entries-1) + indentation_set_is_not_final(index_file,1); + else + indentation_set_is_not_final(index_file,0); + + + if(state.output_is_tree_like) + { + print_indentation_for_treelike_output(index_file); + if(i<number_of_entries-1) + fprintf(index_file->out,"├── "); + else + fprintf(index_file->out,"└── "); + } print_entry(index_file,current_entry,dir_fd,repo); - fprintf(index_file,"\n<br>\n"); + if(i<number_of_entries-1) + fprintf(index_file->out,"\n"); } - close_file(index_file); } void print_files_top(int dir_fd,git_commit *top_commit,git_repository *repo) { + struct Index_File *index_file; git_tree *tree; git_commit_tree(&tree,top_commit); - print_files(dir_fd,tree,repo); + index_file=get_index_file(dir_fd,"index"); + + if(state.output_is_tree_like) + fprintf(index_file->out,"|\n"); + + print_files(index_file,dir_fd,tree,repo); + + + release_index_file(index_file); } -int print_entry(FILE *index_file,const git_tree_entry *entry,int base_dir_fd,git_repository *repo) +int print_entry(struct Index_File *index_file,const git_tree_entry *entry,int base_dir_fd,git_repository *repo) { git_object *obj; - const git_oid *obj_oid; const char *entry_name; - const char *entry_oid; git_tree_entry_to_object(&obj,repo,entry); - obj_oid=git_object_id(obj); - entry_name=git_tree_entry_name(entry); - entry_oid=git_oid_tostr_s(obj_oid); switch(git_object_type(obj)) { case GIT_OBJECT_TREE: - push_html_link_for_tree(index_file,entry_name,entry_oid); - { - int new_dir_fd; - git_tree *tree; - - tree=(git_tree*)obj; - - new_dir_fd=create_dir(base_dir_fd,entry_oid); - print_files(new_dir_fd,tree,repo); - } + print_tree_entry(index_file,entry_name,obj,base_dir_fd,repo); break; case GIT_OBJECT_BLOB: - push_html_link_for_blob(index_file,entry_name,entry_oid); - { - FILE *blob_file; - const unsigned char *blob_data; - size_t blob_size; - size_t i; - git_blob *blob; - - - blob=(git_blob*)obj; - - blob_file=create_file(base_dir_fd,entry_oid); - - blob_size=git_blob_rawsize(blob); - blob_data=git_blob_rawcontent(blob); - - fprintf(blob_file,"<code><pre>\n"); - for(i=0;i<blob_size;++i) - { - if(special_chars[blob_data[i]]) - { - fwrite(special_chars[blob_data[i]],1,strlen(special_chars[blob_data[i]]),blob_file); - }else - { - fwrite(blob_data+i,1,1,blob_file); - } - } - fprintf(blob_file,"</pre></code>\n"); - - close_file(blob_file); - } + print_blob_entry(index_file,entry_name,obj,base_dir_fd,repo); break; } git_object_free(obj); return 0; } +static inline void print_tree_entry(struct Index_File *index_file,const char *name,git_object *obj,int base_dir_fd,git_repository *repo) +{ + const git_oid *obj_oid; + const char *entry_oid; + git_tree *tree; + + obj_oid=git_object_id(obj); + entry_oid=git_oid_tostr_s(obj_oid); + tree=(git_tree*)obj; + + + + if(state.output_is_tree_like) + { + if(index_file->indentation==state.tree_cutoff) + { + push_html_link_for_tree(index_file->out,name,entry_oid); + print_files_in_another_index(base_dir_fd,entry_oid,name,tree,repo); + + }else + { + fprintf(index_file->out,"%s ─┐",name); + increment_indentation(index_file,name); + + fprintf(index_file->out,"\n"); + print_files(index_file,base_dir_fd,tree,repo); + + decrement_indentation(index_file); + } + }else + { + push_html_link_for_tree(index_file->out,name,entry_oid); + print_files_in_another_index(base_dir_fd,entry_oid,name,tree,repo); + } +} +static inline void print_blob_entry(struct Index_File *index_file,const char *name,git_object *obj,int base_dir_fd,git_repository *repo) +{ + const git_oid *obj_oid; + const char *entry_oid; + + FILE *blob_file; + const unsigned char *blob_data; + size_t blob_size; + size_t i; + git_blob *blob; + + obj_oid=git_object_id(obj); + entry_oid=git_oid_tostr_s(obj_oid); + + push_html_link_for_blob(index_file->out,name,entry_oid); + + blob=(git_blob*)obj; + blob_file=create_file(base_dir_fd,entry_oid); + + blob_size=git_blob_rawsize(blob); + blob_data=git_blob_rawcontent(blob); + + fprintf(blob_file,"<code><pre>\n"); + for(i=0;i<blob_size;++i) + { + if(special_chars[blob_data[i]]) + { + fwrite(special_chars[blob_data[i]],1,strlen(special_chars[blob_data[i]]),blob_file); + }else + { + fwrite(blob_data+i,1,1,blob_file); + } + } + fprintf(blob_file,"</pre></code>\n"); + + close_file(blob_file); +} +void print_indentation_for_treelike_output(struct Index_File *out) +{ + int i; + int j; + for(i=0;i<out->indentation;++i) + { + if(out->branches[i]) + fprintf(out->out,"|"); + else + fprintf(out->out," "); + + for(j=0;j<out->offset[i]+5;++j) + fprintf(out->out," "); + } +} +void increment_indentation(struct Index_File *index,const char *name) +{ + index->offset[index->indentation]=strnlen(name,1000); + ++index->indentation; +} +void decrement_indentation(struct Index_File *index) +{ + --index->indentation; +} +void indentation_set_is_not_final(struct Index_File *index,_Bool is_final) +{ + index->branches[index->indentation]=is_final; +} + +void print_files_in_another_index(int base_dir_fd,const char *entry_oid,const char *name,git_tree *tree,git_repository *repo) +{ + int new_dir_fd; + struct Index_File *new_index; + + new_dir_fd=create_dir(base_dir_fd,entry_oid); + new_index=get_index_file(new_dir_fd,"index"); + if(state.output_is_tree_like) + fprintf(new_index->out,"%s\n|\n",name); + print_files(new_index,new_dir_fd,tree,repo); + + release_index_file(new_index); + close(new_dir_fd); +} #endif |