----------------------------------------------------------------------------*/
/* Standard */
#include <stdio.h> //print
+#include <string.h> //strncmp
#include <errno.h> //errno
+#include <ctype.h> //tolower
/* Posix */
#include <err.h> //warnx
#include <stdlib.h> //exit
#include <unistd.h> //chdir
#include <dirent.h> //opendir
-/* Libs */
-#include <png.h>
+#include <unistr.h> //unicode strings
/* Internal */
#include "parser.tab.h"
/* Public */
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.
#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)
()
{ 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);
}
*/
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()
()
-{ struct dirent* direntp;
- struct DIR* DIRp;
+{ static ucs4_t uc_dname[MAX_DNAME] = {0};
int ntok = 0;
scan:
if (DL_CD_LEN() >= DL_CD_STACKSIZE)//fail if maxchildren exceeded
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
- ntok += 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
{ if (closedir(DL_POP())) //close the directory we just left
goto libfail;
if (DL_LEN() == -1) //If we just popped root,
- goto done; //we're done
+ goto done; //we're done
lexer_pushtok(CLCLOSE, 0); //Else push "Close Directory" token,
ntok++;
if (!chdir("..")) //move up a directory and
- goto scan; //start over
+ goto scan; //start over
}
fprintf(stderr, ERR_DL);
libfail:
- perror("parsedir");
+ perror("scanner: ");
fail:
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)
This filter removes all unhandled file types, and places any 'DT_DIR' type
files in the current Directory List's directory stack. Upon finishing,
qsort(lexer_direntpa, DPS_LEN(), sizeof direntp, (qcomp)alphasort);
return DPS_LEN();
}
-
-
-/* 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 x
-)
-{ int pixels = 0;
- //Open the current file if not yet open
- //Identify file type
- //Verify file contents and header
- //Read pixels into buffer
- return pixels;
-}