X-Git-Url: https://www.kengrimes.com/gitweb/?p=henge%2Fwebcc.git;a=blobdiff_plain;f=src%2Fapc%2Fscanner.c;h=07f18ce113effebd6c4414eee8d5bc83fa329f25;hp=8490e02e2b95fa8956550a7b4d0c960ac1249f8b;hb=df52756177b6e4fd9465cbb1b17a35eb48bb67c9;hpb=4da3506e5cf1a3eee35b60722b9c801867ef3f36 diff --git a/src/apc/scanner.c b/src/apc/scanner.c index 8490e02..07f18ce 100644 --- a/src/apc/scanner.c +++ b/src/apc/scanner.c @@ -13,40 +13,47 @@ ----------------------------------------------------------------------------*/ /* Standard */ #include //print +#include //strncmp #include //errno +#include //tolower /* Posix */ #include //warnx #include //exit #include //chdir #include //opendir - +#include //unicode strings +/* Internal */ #include "parser.tab.h" /* Public */ -int scanner_init(void); -void scanner_quit(void); -int scanner(void); +int scanner_init(void); +void scanner_quit(void); +int scanner(void); +int scanner_scanpixels(int*,int); /* Private */ -#ifndef DL_STACKSIZE -#define DL_STACKSIZE 64 -#endif -#ifndef DL_CD_STACKSIZE -#define DL_CD_STACKSIZE DL_STACKSIZE //square tree -#endif extern //lexer.c -int lexer_lex(const char*); +int lexer_lexstring(const ucs4_t*); extern //lexer.c -void lexer_pushtok(int, int); +void lexer_pushtok(int, int); static -int dredge_current_depth(void); +int dredge_current_depth(void); +/* Mem */ extern //lexer.c struct dirent* lexer_direntpa[], **lexer_direntpp; extern //SRC_DIR/bin/tools/apc.c const char* cargs['Z']; - +#ifndef DL_STACKSIZE +#define DL_STACKSIZE 64 +#endif +#ifndef DL_CD_STACKSIZE +#define DL_CD_STACKSIZE DL_STACKSIZE //square tree +#endif +static struct dirlist { DIR* dirp; struct dirent* child_directory_stack[DL_CD_STACKSIZE],** cds; } directory_list_stack[DL_STACKSIZE + 1],* dls; //+1 for the root dir +static +FILE* current_open_file = NULL; /* Directory Listing Stack FILO Stack for keeping an open DIR* at each directory depth for treewalk. @@ -72,6 +79,8 @@ struct dirlist #define DL_INIT() (DL_STACKP = DL_STACK) #define DL_CD_INIT() (DL_CD_STACKP = DL_CD_STACK) #define DL_POP() ((*DL_STACKP--).dirp) +#define DL_CD() (*DL_CD_STACKP) +#define DL_CD_CURNAME() (DL_CD()->d_name) #define DL_CD_POP() (*--DL_CD_STACKP) #define DL_PUSH(D) ((*++DL_STACKP).dirp = D) #define DL_CD_PUSH(E) (*DL_CD_STACKP++ = E) @@ -88,6 +97,10 @@ int scanner_init () { DL_INIT(); DL_STACK[0].dirp = opendir(ROOTDIR); + if (current_open_file != NULL) + { fclose(current_open_file); + current_open_file = NULL; + } printf("Root dir %s\n",ROOTDIR); return !chdir(ROOTDIR) && (DL_STACK[0].dirp == NULL || dredge_current_depth() == -1); } @@ -110,57 +123,95 @@ void scanner_quit array, while placing all subdirectory entries in the current depth's child directory stack to be scanned later. - Returns the number of elements added to the lexer's file array, or -1 on - error + Returns the number of tokens generated on success, -1 on error. */ int scanner #define $($)#$ //stringifier -#define ERR_CHILD "Fatal: Maximum of " $(DL_CD_STACKSIZE) \ - " child directories exceeded for directory at depth %i\n" \ +#ifdef _DIRENT_HAVE_D_NAMLEN +#define MAX_DNAME _D_ALLOC_NAMLEN(DL_CD()) +#else +#define MAX_DNAME 1024 +#endif +#define ERR_CHILD "Fatal: Maximum of " $(DL_CD_STACKSIZE) \ + " child directories exceeded for directory at depth %i\n" \ ,DL_LEN() -#define ERR_DEPTH "Fatal: Maximum directory depth of " $(DL_STACKSIZE) \ +#define ERR_DEPTH "Fatal: Maximum directory depth of " $(DL_STACKSIZE) \ " exceeded during directory scan\n" #define ERR_DL "Fatal: Directory List Stack Corruption %x\n", DL_LEN() -#define TOK_CLOPEN 0x55, 1 //TODO -#define TOK_CLCLOSE 0x56, 1 //TODO () -{ struct dirent* direntp; - struct DIR* DIRp; - parse: +{ static ucs4_t uc_dname[MAX_DNAME] = {0}; + int ntok = 0; + scan: if (DL_CD_LEN() >= DL_CD_STACKSIZE)//fail if maxchildren exceeded { fprintf(stderr, ERR_CHILD); goto fail; } if (DL_CD_LEN() > 0) //There are entities to process - { if ((direntp = DL_CD_POP()) == NULL)//If the dirent is null, the library - goto libfail; //function in dirent has failed - lexer_lex(direntp->d_name); //lex the directory name + { if (DL_CD_POP() == NULL) //If the dirent is null, then the + goto libfail; //lib function in dirent has failed + if (u8_mbtouc(uc_dname, DL_CD_CURNAME(), MAX_DNAME) < 0) //convert to ucs4 + goto libfail; + ntok += lexer_lexstring(uc_dname); //lex the directory name if (DL_LEN() >= DL_STACKSIZE) //fail if maxdepth exceeded { fprintf(stderr, ERR_DEPTH); goto fail; } - if (chdir(direntp->d_name)) //move into the new directory + if (chdir(DL_CD_CURNAME())) //move into the new directory goto libfail; DL_PUSH(opendir(CWDSTR)); if (DL_CURDIR() == NULL) //open the cwd goto libfail; - lexer_pushtok(TOK_CLOPEN); //Push "Open Directory" token + lexer_pushtok(CLOPEN, 0); //Push "Open Directory" token + ntok++; return dredge_current_depth(); //Filter and sort the current depth } else if (DL_LEN() >= 0) //Any dirs left? (Including root) { if (closedir(DL_POP())) //close the directory we just left goto libfail; if (DL_LEN() == -1) //If we just popped root, - return 0; //we're done - lexer_pushtok(TOK_CLCLOSE); //Else push "Close Directory" token, + goto done; //we're done + lexer_pushtok(CLCLOSE, 0); //Else push "Close Directory" token, + ntok++; if (!chdir("..")) //move up a directory and - goto parse; //start over + goto scan; //start over } fprintf(stderr, ERR_DL); libfail: - perror("parsedir"); + perror("scanner: "); fail: - exit(EXIT_FAILURE); + return -1; + done: + return ntok; +} + +/* Scan Pixels + Scans up to 'len' pixels from the current file into 'buf'. + Returns the number of pixels scanned from the file, or -1 on error +*/ +int scanner_scanpixels +( int* buf, + int max_len +) +{ static int col_len, row_len, row; + //Open the current file if not yet open + if (current_open_file == NULL) + { if ((current_open_file = fopen(DL_CD_CURNAME(),"rb")) == NULL) + { perror("fopen: "); + return -1; + } + //Verify file header, get row_len/col_len + if (read_img_header(&row_len, &col_len)) + return -1; + row = 0; + } + //Read pixels into the buffer if there are rows left in the image + if (row++ < row_len) + //TODO: return read_img_pixels(buf, col_len); + printf("SCANPIXELS NOT IMPLEMENTED\n."); + //Close the file and return 0 + fclose(current_open_file); + current_open_file = NULL; + return 0; } /* Directory Entity Sort and Filter (Dredge) @@ -172,7 +223,7 @@ int scanner Returns -1 if 'readdir' encounters an error, otherwise returns the number of directory entries sent to the external 'lexer_direntpa' array. */ -typedef +typedef //so we can typecast dirent's 'alphasort()' to take const void*s int (*qcomp)(const void*, const void*); static inline int dredge_current_depth @@ -207,4 +258,3 @@ int dredge_current_depth qsort(lexer_direntpa, DPS_LEN(), sizeof direntp, (qcomp)alphasort); return DPS_LEN(); } -