diff --git a/psrcgen.c b/psrcgen.c index 6abda31..e6b7188 100644 --- a/psrcgen.c +++ b/psrcgen.c @@ -15,6 +15,8 @@ #include "dwarves.h" #include "dutil.h" +static bool g_strip_upper_directory = false; + #define IGNORE_UPPER_DIRECTORY 1 #define NO_WRITE_FILES 0 @@ -29,25 +31,25 @@ static bool endswith(const char *s1, const char *s2) { int len1 = strlen(s1); int len2 = strlen(s2); - + if( len1 < len2 ) return false; - + return !strncmp(s1 + len1 - len2, s2, len2); } - + static bool filename_looks_like_header(const char *s1) { return endswith(s1, ".h") || endswith(s1, ".H"); } - + static int startswith( const char *s1, const char *s2 ) { int len2 = strlen(s2); - + if( !strncmp(s1, s2, len2)) return len2; - + return 0; } @@ -58,18 +60,18 @@ static void mkdir_p(const char *path) #else char orig_dir[2048]; getcwd(orig_dir, sizeof( orig_dir )); - + for(const char *path2 = path; (path2 = strchr(path, '/')); path = path2 + 1) { char dir[128]; strncpy2(dir, path, path2 - path); - + mkdir(dir, 0777); - + chdir(dir); } - + chdir(orig_dir); #endif } @@ -173,28 +175,29 @@ static void include_detector_detect1(struct cu *cu) static srcfile_t *find_or_create_srcfile(const char *filename) { srcfile_t *srcfile; - + filename += startswith( filename, "/" ); - -#if IGNORE_UPPER_DIRECTORY - if( startswith( filename, "../" )) - return NULL; -#endif - + + + if( !g_strip_upper_directory ) + { + if( startswith( filename, "../" )) + return NULL; + } + if( startswith( filename, "usr/" )) return NULL; - + if( startswith( filename, "fs/root/build/host/glibc-2.29/" )) return NULL; - -#if !IGNORE_UPPER_DIRECTORY - filename += startswith( filename, "../" ); -#endif + + if( g_strip_upper_directory ) + filename += startswith( filename, "../" ); + filename += startswith( filename, "/fs/root/build/x86_64/lccrt/" ); filename += startswith( filename, "fs/root/build/x86_64/lccrt/" ); filename += startswith( filename, "./" ); filename += startswith( filename, ".obj/" ); - include_detector_push(filename); list_for_each_entry(srcfile, &g_SourceFiles, node) @@ -204,20 +207,20 @@ static srcfile_t *find_or_create_srcfile(const char *filename) return srcfile; } } - + srcfile = malloc( sizeof( srcfile_t )); srcfile->filename = strdup(filename); INIT_LIST_HEAD(&srcfile->lines); - + list_add_tail(&srcfile->node, &g_SourceFiles); - + return srcfile; } static bool find_or_insert_line(srcfile_t *sourceFile, int linenum, struct tag *tag, struct cu *cu, const char *include) { srcfile_line_t *line, *new; - + list_for_each_entry_reverse(line, &sourceFile->lines, node) { if( line->linenum == linenum ) // && tag__orig_id(line->tag, line->cu) == tag__orig_id(tag, cu)) @@ -230,18 +233,18 @@ static bool find_or_insert_line(srcfile_t *sourceFile, int linenum, struct tag * line->cu = cu; return false; } - + if( line->linenum <= linenum ) break; } - + new = malloc( sizeof( srcfile_line_t )); new->linenum = linenum; new->tag = tag; new->cu = cu; new->include = include ? strdup(include) : 0; list_add(&new->node, &line->node); - + return true; } @@ -249,12 +252,12 @@ static void add_srcfile_tag(struct tag *tag, struct cu *cu) { const char *file = tag__decl_file(tag, cu); srcfile_t *srcfile; - + if( !file ) return; - + srcfile = find_or_create_srcfile(file); - + if( srcfile ) find_or_insert_line(srcfile, tag__decl_line(tag, cu), tag, cu, NULL); } @@ -263,6 +266,7 @@ static void add_srcfile_tag(struct tag *tag, struct cu *cu) static struct conf_fprintf conf = { .emit_stats = 0, + .classes_as_structs = 1, }; static void print_type(struct tag *tag, struct cu *cu, FILE *fp) @@ -280,11 +284,11 @@ static void print_type(struct tag *tag, struct cu *cu, FILE *fp) static void print_function(struct tag *tag, struct cu *cu, FILE *fp) { conf.no_semicolon = true; - { + { struct function *f = tag__function(tag); int c = tag__fprintf(tag, cu, &conf, fp); if( c >= 70 ) c = 69; // nice - + fprintf(fp, "%-*.*s// %5u\n", 70 - c, 70 - c, " ", tag__decl_line(tag, cu)); lexblock__fprintf(&f->lexblock, cu, f, 0, &conf, fp); @@ -302,18 +306,18 @@ static void print_variable(struct tag *tag, struct cu *cu, FILE *fp) static void source_files_print( void ) { srcfile_t *srcfile; - + list_for_each_entry(srcfile, &g_SourceFiles, node) { printf( "SOURCE FILE: %s\n", srcfile->filename ); mkdir_p( srcfile->filename ); - + FILE *fp = fopen( srcfile->filename, "w+" ); - + srcfile_line_t *line; bool header = filename_looks_like_header( srcfile->filename ); - + fprintf( fp, "// Generated by psrcgen tool\n" ); if( header ) @@ -324,7 +328,7 @@ static void source_files_print( void ) { fprintf( fp, "#include \n#include \n#include \n" ); } - + list_for_each_entry(line, &srcfile->lines, node) { if( line->include ) @@ -344,7 +348,7 @@ static void source_files_print( void ) print_function(line->tag, line->cu, fp ); } } - + fclose(fp); } } @@ -354,7 +358,7 @@ static void source_files_print( void ) static void scan_type(struct tag *tag, struct cu *cu) { const char *name; - + switch(tag->tag) { case DW_TAG_base_type: @@ -369,29 +373,29 @@ static void scan_type(struct tag *tag, struct cu *cu) case DW_TAG_volatile_type: return; } - + name = type__name(tag__type(tag)); // probably included if( name == NULL ) return; - + if( name[0] == '\0' ) return; - + // probably a forward declaration, skip for now if( tag__size(tag, cu) == 0 ) return; - + add_srcfile_tag(tag, cu); } static void scan_variable(struct tag *tag, struct cu *cu) { struct variable *variable = tag__variable(tag); - + if( variable->scope == VSCOPE_LOCAL ) return; - + add_srcfile_tag(tag, cu); } @@ -400,21 +404,13 @@ static int cu__emit_tags(struct cu *cu) uint32_t i; struct tag *tag; struct function *function; - const char *name = cu->name; - -#if IGNORE_UPPER_DIRECTORY - if( startswith(name, "../" )) - return 0; -#else - name += startswith(name, "../" ); -#endif - + include_detector_init(); cu__for_each_type(cu, i, tag) { scan_type(tag, cu); } - + cu__for_each_variable(cu, i, tag) { scan_variable(tag, cu); } @@ -422,7 +418,7 @@ static int cu__emit_tags(struct cu *cu) cu__for_each_function(cu, i, function) { add_srcfile_tag(function__tag(function), cu); } - + include_detector_detect1(cu); return 0; @@ -433,7 +429,7 @@ static enum load_steal_kind pdwtags_stealer(struct cu *cu, void *thr_data __maybe_unused) { cu__emit_tags(cu); - + return LSK__KEEPIT; } @@ -452,7 +448,17 @@ static const struct argp_option pdwtags__options[] = { .name = "format_path", .key = 'F', .arg = "FORMAT_LIST", - .doc = "List of debugging formats to try" + .doc = "List of debugging formats to try", + }, + { + .name = "classes_as_structs", + .key = 'S', + .doc = "force classes to be presented as structs", + }, + { + .name = "strip_upper_directory", + .key = 'u', + .doc = "strip upper directory from file paths", }, { .key = 'V', @@ -474,6 +480,8 @@ static error_t pdwtags__options_parser(int key, char *arg __maybe_unused, break; case 'F': pdwtags_conf_load.format_path = arg; break; case 'V': conf.show_decl_info = 1; break; + case 'S': conf.classes_as_structs = 1; break; + case 'u': g_strip_upper_directory = true; break; default: return ARGP_ERR_UNKNOWN; } return 0; @@ -518,3 +526,4 @@ out: dwarves__exit(); return rc; } +