From e4ad1c1a9499babb6804823e60377a14b6a0b583 Mon Sep 17 00:00:00 2001 From: ken Date: Fri, 17 Feb 2017 20:55:05 -0800 Subject: [PATCH] root class is name of package, apc_package_name available to extern --- src/apc.c | 40 +++++++++++++++++++++++++++++++++++++--- src/ir.c | 39 +++++++++++++++++++++++++++------------ src/scanner.c | 17 ----------------- 3 files changed, 64 insertions(+), 32 deletions(-) diff --git a/src/apc.c b/src/apc.c index 4e71155..494be6e 100644 --- a/src/apc.c +++ b/src/apc.c @@ -18,12 +18,15 @@ /* Posix */ #include //exit #include //getopt, sysconf +#include //opendir /* Internal */ +#include "apc.h" #include "parser.tab.h" //bison #include "ir.h" #define DEFAULT_PAGESIZE 4096 const char** cargs; +const char* apc_package_name; long sys_pagesize; int main(int, char*[]); @@ -35,7 +38,7 @@ int scanner_init(void); extern //scanner.c void scanner_quit(void); extern //scanner.c -int scanner_scanpath(char const*); +int scanner_scandir(DIR*); extern //ir.c int ir_init(void); extern //ir.c @@ -63,8 +66,11 @@ int main "\t\t-o\tOutput filename \t\t[a.asspak]\n" \ "\t\t-h\tPrint this help\n" #define DONE -1 -#define SCANPATH (cargs['d'] ? cargs['d'] : "./") { int opt; + const char* scanpath; + char* path_iter; + char path_buf[APC_NAME_MAX]; + DIR* dirp; cargs = (const char**) malloc('Z'); getopt: switch (opt = getopt(argc, argv, OPTS)) @@ -92,7 +98,35 @@ int main free(cargs); exit(EXIT_FAILURE); } - if (scanner_scanpath(SCANPATH)) + + scanpath = cargs['d'] ? cargs['d'] : "./"; + errno = 0; + dirp = opendir(scanpath); + if (dirp == NULL || errno) + { fprintf(stderr, "Path %s could not be accessed\n", scanpath); + return -1; + } + if (chdir(scanpath)) + { fprintf(stderr, "Could not change directory to %s \n", scanpath); + return -1; + } + apc_package_name = path_iter = getcwd(path_buf, APC_NAME_MAX - 1); + basename: + while (*path_iter != '\0') + { if (*path_iter == '/') + apc_package_name = path_iter + 1; + path_iter++; + } + if (apc_package_name == path_buf) + { fprintf(stderr, "Error resolving package name from path %s\n", path_buf); + free(cargs); + exit(EXIT_FAILURE); + } + if (apc_package_name == path_iter) + { *--path_iter = '\0'; + goto basename; + } + if (scanner_scandir(dirp)) { perror("scanner"); free(cargs); exit(EXIT_FAILURE); diff --git a/src/ir.c b/src/ir.c index 4ef2e5a..3577d48 100644 --- a/src/ir.c +++ b/src/ir.c @@ -67,6 +67,7 @@ struct ir_link_t { struct ir_setdata_header_t header; struct ir_classld_t* classld; struct ir_setld_t* setld; + struct ir_set_t* trg_set; enum ltype type; }; union ir_setdata_t @@ -98,6 +99,8 @@ struct ir_framebox_t* ir_set_add_framebox(struct ir_set_t*,uint8_t*); static inline union ir_setdata_t* ir_framedata (enum dtype,const uint8_t*,apc_facing,int,int); static inline +void ir_linkdata_resolve_set(union ir_setdata_t*); +static inline int bytes_identical(const uint8_t*,const uint8_t*); static inline int classnames_identical(const uint8_t*,const uint8_t*); @@ -110,10 +113,12 @@ uint8_t* classname_alloc(const uint8_t*); #define struct_alloc(_T) ((struct _T*) stack_alloc(&datapages, sizeof(struct _T))) extern //apc.c long sys_pagesize; +extern //apc.c +char* apc_package_name; static struct pagelist_t datapages, namepages, refhashpages; static -struct ir_class_t root_class = { .name = (uint8_t*)"." }; +struct ir_class_t root_class; /* Init */ int ir_init @@ -121,7 +126,7 @@ int ir_init { pagelist_init(datapages, (size_t)SYS_PAGESIZE); pagelist_init(namepages, (size_t)NAME_PAGESIZE); pagelist_init(refhashpages, (size_t)SYS_PAGESIZE); - + root_class.name = (uint8_t*) apc_package_name; return 0; } @@ -615,27 +620,38 @@ union ir_setdata_t* ir_set_link ( struct ir_set_t* set ) { return (union ir_setdata_t*) set->links; } +#define assert_link(linkdata) do { \ + if (linkdata->header.type != LDAT) \ + eprintf("Data %s is not a link\n", linkdata->header.data_name); \ + } while (0) + /* Return the link type */ enum ltype ir_linkdata_type ( union ir_setdata_t* linkdata ) -{ if (linkdata->header.type != LDAT) - eprintf("Data %s is not a link\n", linkdata->header.data_name); +{ assert_link(linkdata); return linkdata->link.type; } /* Return the link type */ uint32_t ir_linkdata_ref ( union ir_setdata_t* linkdata ) -{ if (linkdata->header.type != LDAT) - eprintf("Data %s is not a link\n", linkdata->header.data_name); +{ assert_link(linkdata); return linkdata->link.setld->ref; } -/* Resolve and return the link's target set - Fails on error, cannot return NULL -*/ +/* Return the current target set, resolving it first if not present */ struct ir_set_t* ir_linkdata_set ( union ir_setdata_t* linkdata ) +{ assert_link(linkdata); + if (linkdata->link.trg_set == NULL) + ir_linkdata_resolve_set(linkdata); + return linkdata->link.trg_set; +} + +/* Resolve and assign the link's target set */ +static inline +void ir_linkdata_resolve_set +( union ir_setdata_t* linkdata ) { struct ir_class_t* class_iter; struct ir_namelist_t* namelist_iter,* namelist_iter_last; struct ir_setld_t* setld; @@ -643,8 +659,7 @@ struct ir_set_t* ir_linkdata_set struct ir_set_t* set; set = NULL; class_iter = NULL; - if (linkdata->header.type != LDAT) - eprintf("Data %s is not a link\n", linkdata->header.data_name); + assert_link(linkdata); setld = linkdata->link.setld; if (linkdata->link.setld == NULL) eprintf("Link data is invalid\n"); @@ -705,7 +720,7 @@ struct ir_set_t* ir_linkdata_set class_iter->name); } } - return set; + linkdata->link.trg_set = set; } /* Get a setdata's next sibling */ diff --git a/src/scanner.c b/src/scanner.c index d01be15..0b733c8 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -25,7 +25,6 @@ #include "parser.tab.h" /* Public */ void scanner_quit(void); -int scanner_scanpath(char const*); int scanner_scandir(DIR*); /* Private */ static @@ -40,22 +39,6 @@ extern //lexer.rl int lexer_lexdir(uint8_t*); extern //lexer.rl void lexer_closedir(void); -/* Scan the provided path - Changes working directory to the provided pathname and, if successful, sends - a directory stream of the provided path to scanner_scandir -*/ -int scanner_scanpath -( char const* pathname ) -{ DIR* dirp; - errno = 0; - if ((dirp = opendir(pathname)) == NULL || errno) - { fprintf(stderr, "Path %s could not be accessed\n", pathname); - return -1; - } - if (chdir(pathname)) - return -1; - return scanner_scandir(dirp); -} /* Scan directory stream Recursively scans the provided directory, sending CLOPEN and CLCLOSE tokens -- 2.18.0