static char *find_next ( int *attrib ) { FB_DIRCTX *ctx = FB_TLSGETCTX( DIR ); char *name = NULL; struct stat info; struct dirent *entry; char buffer[MAX_PATH]; do { entry = readdir( ctx->dir ); if( !entry ) { close_dir( ); return NULL; } name = entry->d_name; strcpy( buffer, ctx->dirname ); strncat( buffer, name, MAX_PATH - strlen( buffer ) - 1 ); buffer[MAX_PATH-1] = '\0'; if( stat( buffer, &info ) ) continue; *attrib = get_attrib( name, &info ); } while( ( *attrib & ~ctx->attrib ) || !match_spec( name ) ); return name; }
/*:::::*/ FBCALL int fb_ConsoleInput( FBSTRING *text, int addquestion, int addnewline ) { FB_INPUTCTX *ctx; int res; fb_DevScrnInit_Read( ); if( fb_IsRedirected( TRUE ) ) { /* del if temp */ fb_hStrDelTemp( text ); return fb_FileInput( 0 ); } ctx = FB_TLSGETCTX( INPUT ); fb_StrDelete( &ctx->str ); ctx->handle = 0; ctx->status = 0; ctx->index = 0; res = fb_LineInput( text, &ctx->str, -1, 0, addquestion, addnewline ); return res; }
/*:::::*/ FB_ERRHANDLER fb_ErrorThrowEx ( int err_num, int line_num, const char *mod_name, void *res_label, void *resnext_label ) { FB_ERRORCTX *ctx = FB_TLSGETCTX( ERROR ); if( ctx->handler ) { ctx->err_num = err_num; ctx->line_num = line_num; if( mod_name != NULL ) ctx->mod_name = mod_name; ctx->res_lbl = res_label; ctx->resnxt_lbl = resnext_label; return ctx->handler; } /* if no user handler defined, die */ fb_Die( err_num, line_num, (mod_name != NULL? mod_name: ctx->mod_name), ctx->fun_name ); return NULL; }
static void close_dir ( void ) { FB_DIRCTX *ctx = FB_TLSGETCTX( DIR ); closedir( ctx->dir ); ctx->in_use = FALSE; }
/*:::::*/ FB_ERRHANDLER fb_ErrorThrowAt ( int line_num, const char *mod_name, void *res_label, void *resnext_label ) { FB_ERRORCTX *ctx = FB_TLSGETCTX( ERROR ); return fb_ErrorThrowEx( ctx->err_num, line_num, mod_name, res_label, resnext_label ); }
/*:::::*/ FBCALL FB_ERRHANDLER fb_ErrorSetHandler ( FB_ERRHANDLER newhandler ) { FB_ERRORCTX *ctx = FB_TLSGETCTX( ERROR ); FB_ERRHANDLER oldhandler; oldhandler = ctx->handler; ctx->handler = newhandler; return oldhandler; }
/*:::::*/ void *fb_ErrorResumeNext ( void ) { FB_ERRORCTX *ctx = FB_TLSGETCTX( ERROR ); void *label = ctx->resnxt_lbl; /* not defined? die */ if( label == NULL ) fb_Die( FB_RTERROR_ILLEGALRESUME, -1, ctx->mod_name, ctx->fun_name ); /* don't loop forever */ ctx->res_lbl = NULL; ctx->resnxt_lbl = NULL; return label; }
static int match_spec( char *name ) { FB_DIRCTX *ctx = FB_TLSGETCTX( DIR ); char *any = NULL; char *spec; spec = ctx->filespec; while( ( *spec ) || ( *name ) ) { switch( *spec ) { case '*': any = spec; spec++; while( ( *name != *spec ) && ( *name ) ) name++; break; case '?': spec++; if( *name ) name++; break; default: if( *spec != *name ) { if( ( any ) && ( *name ) ) spec = any; else return FALSE; } else { spec++; name++; } break; } } return TRUE; }
/*:::::*/ void fb_FileInputNextTokenWstr ( FB_WCHAR *buffer, int max_chars, int is_string ) { /* max_chars does not include the null terminator, the buffer is assumed to be big enough to hold at least the null terminator */ int len, isquote, skipdelim; FB_WCHAR c; FB_INPUTCTX *ctx = FB_TLSGETCTX( INPUT ); /* */ skipdelim = TRUE; isquote = 0; len = 0; c = hSkipWhiteSpc( ctx ); while( (c != WEOF) && (len < max_chars) ) { switch( c ) { case _LC('\n'): skipdelim = FALSE; goto exit; case _LC('\r'): if( (c = hReadChar( ctx )) != _LC('\n') ) hUnreadChar( ctx, c ); skipdelim = FALSE; goto exit; case _LC('"'): if( !isquote ) { if( len == 0 ) isquote = 1; else goto savechar; } else { isquote = 0; if( is_string ) { c = hReadChar( ctx ); goto exit; } } break; case _LC(','): if( !isquote ) { skipdelim = FALSE; goto exit; } goto savechar; case _LC('\t'): case _LC(' '): if( !isquote ) { if( !is_string ) { goto exit; } } default: savechar: *buffer++ = c; ++len; break; } c = hReadChar( ctx ); } exit: *buffer = _LC('\0'); /* skip comma or newline */ if( skipdelim ) hSkipDelimiter( ctx, c ); }
FBCALL FBSTRING *fb_Dir( FBSTRING *filespec, int attrib, int *out_attrib ) { FB_DIRCTX *ctx; FBSTRING *res; ssize_t len; int tmp_attrib; char *name, *p; struct stat info; if( out_attrib == NULL ) out_attrib = &tmp_attrib; len = FB_STRSIZE( filespec ); name = NULL; ctx = FB_TLSGETCTX( DIR ); if( len > 0 ) { /* findfirst */ if( ctx->in_use ) close_dir( ); if( strchr( filespec->data, '*' ) || strchr( filespec->data, '?' ) ) { /* we have a pattern */ p = strrchr( filespec->data, '/' ); if( p ) { strncpy( ctx->filespec, p + 1, MAX_PATH ); ctx->filespec[MAX_PATH-1] = '\0'; len = (p - filespec->data) + 1; if( len > MAX_PATH - 1 ) len = MAX_PATH - 1; memcpy( ctx->dirname, filespec->data, len ); ctx->dirname[len] = '\0'; } else { strncpy( ctx->filespec, filespec->data, MAX_PATH ); ctx->filespec[MAX_PATH-1] = '\0'; strcpy( ctx->dirname, "./"); } /* Make sure these patterns work just like on Win32/DOS */ if( (!strcmp( ctx->filespec, "*.*" )) || (!strcmp( ctx->filespec, "*." )) ) strcpy( ctx->filespec, "*" ); if( (attrib & 0x10) == 0 ) attrib |= 0x20; ctx->attrib = attrib; ctx->dir = opendir( ctx->dirname ); if( ctx->dir ) { name = find_next( out_attrib ); if( name ) ctx->in_use = TRUE; } } else { /* no pattern, use stat on single file */ if( !stat( filespec->data, &info ) ) { tmp_attrib = get_attrib( filespec->data, &info ); if( (tmp_attrib & ~attrib ) == 0 ) { name = strrchr( filespec->data, '/' ); if( !name ) name = filespec->data; else name++; *out_attrib = tmp_attrib; } } } } else { /* findnext */ if( ctx->in_use ) name = find_next( out_attrib ); } FB_STRLOCK(); /* store filename if found */ if( name ) { len = strlen( name ); res = fb_hStrAllocTemp_NoLock( NULL, len ); if( res ) fb_hStrCopy( res->data, name, len ); else res = &__fb_ctx.null_desc; } else { res = &__fb_ctx.null_desc; *out_attrib = 0; } fb_hStrDelTemp_NoLock( filespec ); FB_STRUNLOCK(); return res; }
/*:::::*/ int fb_FileInputNextToken ( char *buffer, int max_chars, int is_string, int *isfp ) { /* max_chars does not include the null terminator, the buffer is assumed to be big enough to hold at least the null terminator */ int c, len, isquote, hasamp, skipdelim; FB_INPUTCTX *ctx = FB_TLSGETCTX( INPUT ); *isfp = FALSE; /* */ skipdelim = TRUE; isquote = FALSE; hasamp = FALSE; len = 0; c = hSkipWhiteSpc( ctx ); while( (c != EOF) && (len < max_chars) ) { switch( c ) { case '\n': skipdelim = FALSE; goto exit; case '\r': if( (c = hReadChar( ctx )) != '\n' ) hUnreadChar( ctx, c ); skipdelim = FALSE; goto exit; case '"': if( !isquote ) { if( len == 0 ) isquote = TRUE; else goto savechar; } else { isquote = FALSE; if( is_string ) { c = hReadChar( ctx ); goto exit; } } break; case ',': if( !isquote ) { skipdelim = FALSE; goto exit; } goto savechar; case '&': hasamp = TRUE; goto savechar; case 'd': case 'D': /* NOTE: if exponent letter is d|D, and * is_string == FALSE, then convert the d|D * to an e|E. strtod() which * will later be used to convert the string * to float won't accept d|D anywhere but * on windows. (jeffm) */ if( !hasamp && !is_string ) { ++c; } /* fall through */ case 'e': case 'E': case '.': if( !hasamp ) { *isfp = TRUE; } goto savechar; case '\t': case ' ': if( !isquote ) { if( !is_string ) { goto exit; } } default: savechar: *buffer++ = c; ++len; break; } c = hReadChar( ctx ); } exit: /* add the null-term */ *buffer = '\0'; /* skip comma or newline */ if( skipdelim ) hSkipDelimiter( ctx, c ); return len; }