ucs4_t
authorken <ken@mihrtec.com>
Thu, 3 Nov 2016 20:01:16 +0000 (13:01 -0700)
committerken <ken@mihrtec.com>
Thu, 3 Nov 2016 20:01:16 +0000 (13:01 -0700)
src/apc/scanner.c

index a999c7b..07f18ce 100644 (file)
   ----------------------------------------------------------------------------*/
 /* 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 */
@@ -29,27 +30,30 @@ 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.
@@ -75,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)
@@ -91,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);
 }
@@ -117,15 +127,19 @@ void scanner_quit
 */
 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
@@ -133,14 +147,16 @@ int scanner
       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
@@ -153,21 +169,51 @@ int scanner
     { 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,
@@ -212,20 +258,3 @@ int dredge_current_depth
   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;
-}