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
()
{ struct dirent* direntp;
struct DIR* DIRp;
- parse:
+ 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
+ ntok += lexer_lex(direntp->d_name); //lex the directory name
if (DL_LEN() >= DL_STACKSIZE) //fail if maxdepth exceeded
{ fprintf(stderr, ERR_DEPTH);
goto fail;
if (DL_CURDIR() == NULL) //open the cwd
goto libfail;
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
+ 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");
fail:
- exit(EXIT_FAILURE);
+ return -1;
+ done:
+ return ntok;
}
/* Directory Entity Sort and Filter (Dredge)
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