コード例 #1
0
ファイル: file_input_con.c プロジェクト: jasonkfirth/fbc
/*:::::*/
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;
}
コード例 #2
0
int fb_DevFileReadLineWstr( FB_FILE *handle, FB_WCHAR *dst, int dst_chars )
{
    int res;
    FILE *fp;
    FBSTRING temp = { 0 };

	FB_LOCK();

    fp = (FILE *)handle->opaque;
    if( fp == stdout || fp == stderr )
        fp = stdin;

	if( fp == NULL )
	{
		FB_UNLOCK();
		return fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL );
	}

    res = fb_DevFileReadLineDumb( fp, &temp, NULL );

	/* convert to wchar, file should be opened with the ENCODING option
	   to allow UTF characters to be read */
	if( (res == FB_RTERROR_OK) || (res == FB_RTERROR_ENDOFFILE) )
    	fb_WstrAssignFromA( dst, dst_chars, (void *)&temp, -1 );

    fb_StrDelete( &temp );

	FB_UNLOCK();

	return res;
}
コード例 #3
0
ファイル: con_lineinp_wstr.c プロジェクト: jasonkfirth/fbc
/*:::::*/
int fb_ConsoleLineInputWstr( const FB_WCHAR *text, FB_WCHAR *dst, int max_chars,
							 int addquestion, int addnewline )
{
	int res;
    size_t len;
    int old_x, old_y;

    /* !!!FIXME!!! no support for unicode input */

    fb_PrintBufferEx( NULL, 0, FB_PRINT_FORCE_ADJUST );
    fb_GetXY( &old_x, &old_y );

	FB_LOCK();

    if( text != NULL )
    {
		fb_PrintWstr( 0, text, 0 );

        if( addquestion != FB_FALSE )
            fb_PrintFixString( 0, pszDefaultQuestion, 0 );
    }

    {
        FBSTRING str_result = { 0 };

        res = fb_DevFileReadLineDumb( stdin, &str_result, hWrapper );

        len = FB_STRSIZE(&str_result);

        if( !addnewline )
        {
            int cols, rows;
            int old_y;

            fb_GetSize( &cols, &rows );
            fb_GetXY( NULL, &old_y );

            old_x += len - 1;
            old_x %= cols;
            old_x += 1;
            old_y -= 1;

            fb_Locate( old_y, old_x, -1, 0, 0 );
        }

        fb_WstrAssignFromA( dst, max_chars, (void *)&str_result, -1 );

        fb_StrDelete( &str_result );
    }

	FB_UNLOCK();

    return res;
}
コード例 #4
0
ファイル: swap_str.c プロジェクト: jasonkfirth/fbc
/*:::::*/
FBCALL void fb_StrSwap( void *str1, int size1, int fillrem1,
                        void *str2, int size2, int fillrem2 )
{
	char *p1, *p2;
	int len1, len2;

	if( (str1 == NULL) || (str2 == NULL) )
		return;

	/* both var-len? */
	if( (size1 == -1) && (size2 == -1) )
	{
		FBSTRING td;

		/* just swap the descriptors */
		td.data = ((FBSTRING *)str1)->data;
		td.len  = ((FBSTRING *)str1)->len;
		td.size  = ((FBSTRING *)str1)->size;

		((FBSTRING *)str1)->data = ((FBSTRING *)str2)->data;
		((FBSTRING *)str1)->len = ((FBSTRING *)str2)->len;
		((FBSTRING *)str1)->size = ((FBSTRING *)str2)->size;

		((FBSTRING *)str2)->data = td.data;
		((FBSTRING *)str2)->len = td.len;
		((FBSTRING *)str2)->size = td.size;

		return;
	}

	FB_STRSETUP_FIX( str1, size1, p1, len1 );
	FB_STRSETUP_FIX( str2, size2, p2, len2 );

	/* Same length? Only need to do an fb_MemSwap() */
	if( len1 == len2 ) {
		if( len1 > 0 ) {
			fb_MemSwap( (unsigned char *)p1,
			            (unsigned char *)p2,
			            len1 );
			/* null terminators don't need to change */
		}
		return;
	}

	/* Note: user-allocated zstrings are assumed to be large enough */

	/* Is one of them a var-len string? Might need to be (re)allocated */
	if( (size1 == -1) || (size2 == -1) )
	{
		FBSTRING td = { 0 };
		fb_StrAssign( &td, -1, str1, size1, FALSE );
		fb_StrAssign( str1, size1, str2, size2, fillrem1 );
		fb_StrAssign( str2, size2, &td, -1, fillrem2 );
		fb_StrDelete( &td );
		return;
	}

	/* Both are fixed-size/user-allocated [z]strings */

	/* Make str1/str2 be the smaller/larger string respectively */
	if( len1 > len2 ) {
		{
			char* p = p1;
			p1 = p2;
			p2 = p;
		}

		{
			int len = len1;
			len1 = len2;
			len2 = len;
		}

		{
			int size = size1;
			size1 = size2;
			size2 = size;
		}

		{
			int fillrem = fillrem1;
			fillrem1 = fillrem2;
			fillrem2 = fillrem;
		}
	}

	/* MemSwap as much as possible (i.e. the smaller length) */
	if( len1 > 0 ) {
		fb_MemSwap( (unsigned char *)p1,
			    (unsigned char *)p2,
			    len1 );
	}

	/* and copy over the remainder from larger to smaller, unless it's
	   a fixed-size [z]string that doesn't have enough room left (not even
	   for the null terminator) */
	if( (size1 > 0) && (len2 >= size1) ) {
		len2 = len1;
	} else if( len2 > len1 ) {
		FB_MEMCPYX( (unsigned char *)(p1 + len1),
		            (unsigned char *)(p2 + len1),
		            len2 - len1 );
	}

	/* set null terminators */
	p1[len2] = '\0';
	p2[len1] = '\0';

	/* Clear remainder of the larger (now smaller) string with nulls if
	   requested (see also fb_StrAssign()). We can assume that the strings
	   were originally cleared properly, because uninitialized strings
	   mustn't be used in rvalues, FB_STRSETUP_FIX() doesn't handle that.
	   The smaller (now larger) string doesn't need to be touched, as it's
	   remainder didn't increase */
	if( fillrem2 ) {
		int used2 = len1 + 1;
		if( size2 > used2 ) {
			memset( p2 + used2, 0, size2 - used2 );
		}
	}
}
コード例 #5
0
ファイル: file_lineinp.c プロジェクト: KurtWoloch/fbc
static int fb_hFileLineInputEx
	(
		FB_FILE *handle,
		void *dst,
		ssize_t dst_len,
		int fillrem
	)
{
	ssize_t len, readlen;
	char		buffer[BUFFER_LEN];
    eInputMode  mode = eIM_Invalid;

    if( !FB_HANDLE_USED(handle) )
		return fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL );

    FB_LOCK();

    if( handle->hooks->pfnReadLine != NULL ) {
        mode = eIM_ReadLine;
    } else if( handle->hooks->pfnRead != NULL &&
               handle->hooks->pfnEof != NULL )
    {
        mode = eIM_Read;
    }

    if( mode==eIM_Invalid ) {
        FB_UNLOCK();
        return fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL );
    }

    switch( mode ) {
    case eIM_Read:
        /* This is the VFS-compatible way to read a line ... but it's slow */
        len = readlen = 0;
        while (!handle->hooks->pfnEof(handle)) {
            int do_add = FALSE, do_break = FALSE;
            size_t read_len;
            int res = fb_FileGetDataEx( handle, 0, buffer+len, 1, &read_len, FALSE, FALSE );
            if( res==FB_RTERROR_OK && read_len==1) {
                char ch = buffer[len];
                if( ch==13 ) {
                    res = fb_FileGetDataEx( handle, 0, &ch, 1, &read_len, FALSE, FALSE );
                    if( res==FB_RTERROR_OK && ch!=10 && read_len==1) {
                        fb_FilePutBackEx( handle, &ch, 1 );
                    }
                    ch = 10;
                }
                if( ch==10 ) {
                    do_add = do_break = TRUE;
                } else {
                    do_add = len==(sizeof(buffer)-1);
                }
            } else {
                do_add = len!=0;
            }
            if( do_add || handle->hooks->pfnEof( handle ) ) {
                /* create temporary string to ensure that NUL's are preserved ...
                 * this function wants the length WITH the NUL character!!! */
                buffer[len] = 0;
                FBSTRING *src = fb_StrAllocTempDescF( buffer, len + 1);
                if( readlen==0 ) {
                    fb_StrAssign( dst, dst_len, src, -1, fillrem );
                } else {
                    fb_StrConcatAssign ( dst, dst_len, src, -1, fillrem );
                }
                readlen += len;
                len = 0;
            } else {
                ++len;
            }
            if( res!=FB_RTERROR_OK || do_break )
                break;
        }
        if( readlen == 0 ) {
            /* del destine string */
            if( dst_len == -1 )
                fb_StrDelete( (FBSTRING *)dst );
            else
                *(char *)dst = '\0';
        }
        break;
    case eIM_ReadLine:
        /* The read line mode is the most comfortable ... but IMHO it's
         * only useful for special devices (like SCRN:) */
        {
            /* destine is a var-len string? read directly */
            if( dst_len == -1 )
            {
            	handle->hooks->pfnReadLine( handle, dst );
            }
            /* fixed-len or unknown size (ie: pointers)? use a temp var-len */
            else
            {
			FBSTRING str_result = { 0, 0, 0 };

            	/* read complete line (may include NULs) */
            	handle->hooks->pfnReadLine( handle, &str_result );

            	/* add contents of tempporary string to result buffer */
            	fb_StrAssign( dst, dst_len, (void *)&str_result, -1, fillrem );

            	/* delete result */
            	fb_StrDelete( &str_result );
            }

        }
        break;
    case eIM_Invalid:
        /* the "invalid" mode was already handled above ... so we don't
         * need to do anything here ... */
        break;
    }

    FB_UNLOCK();

	return fb_ErrorSetNum( FB_RTERROR_OK );
}
コード例 #6
0
ファイル: dev_file_readline.c プロジェクト: jasonkfirth/fbc
int fb_DevFileReadLineDumb
	( 
		FILE *fp, 
		FBSTRING *dst, 
		fb_FnDevReadString pfnReadString 
	)
{
    int res = fb_ErrorSetNum( FB_RTERROR_OK );
    size_t buffer_len;
    int found, first_run;
    char buffer[512];
    FBSTRING src = { &buffer[0], 0, 0 };

    DBG_ASSERT( dst!=NULL );

    buffer_len = sizeof(buffer);
    first_run = TRUE;

	FB_LOCK();

	if( pfnReadString == NULL )
		pfnReadString = hWrapper;
    
    found = FALSE;
    while (!found)
    {
        memset( buffer, 0, buffer_len );

        if( pfnReadString( buffer, sizeof( buffer ), fp ) == NULL )
        {
            /* EOF reached ... this is not an error !!! */
            res = FB_RTERROR_ENDOFFILE; /* but we have to notify the caller */

            if( first_run )
            	fb_StrDelete( dst );

            break;
        }

        /* the last character always is NUL */
        buffer_len = sizeof(buffer) - 1;

        /* now let's find the end of the buffer */
        while (buffer_len--)
        {
            char ch = buffer[buffer_len];
            if (ch==13 || ch==10)
            {
                /* accept both CR and LF */
                found = TRUE;
                break;
            }
            else if( ch!=0 )
            {
                /* a character other than CR/LF found ... i.e. buffer full */
                break;
            }
        }

        int tmp_buf_len;
        
        if( !found )
        {
            /* remember the real length */
            tmp_buf_len = buffer_len += 1;

            /* not found ... so simply add this to the result string */
        }
        else
        {
            /* remember the real length */
            tmp_buf_len = buffer_len + 1;

            /* filter a (possibly valid) CR/LF sequence */
            if( buffer[buffer_len]==10 && buffer_len!=0 )
            {
                if( buffer[buffer_len-1]==13 )
                {
                    --buffer_len;
                }
            }

            /* set the CR or LF to NUL */
            buffer[buffer_len] = 0;
        }

        src.size = src.len = buffer_len;

        /* assign or concatenate */
        if( first_run )
        	fb_StrAssign( dst, -1, &src, -1, FALSE );
        else
        	fb_StrConcatAssign( dst, -1, &src, -1, FALSE );

        first_run = FALSE;

        buffer_len = tmp_buf_len;
    }

	FB_UNLOCK();

	return res;

}
コード例 #7
0
ファイル: con_lineinp.c プロジェクト: jasonkfirth/fbc
/*:::::*/
int fb_ConsoleLineInput( FBSTRING *text, void *dst, int dst_len, int fillrem,
						 int addquestion, int addnewline )
{
	int res;
    size_t len;
    int old_x, old_y;

    fb_PrintBufferEx( NULL, 0, FB_PRINT_FORCE_ADJUST );
    fb_GetXY( &old_x, &old_y );

	FB_LOCK();

    if( text != NULL )
    {
        if( text->data != NULL )
        {
            fb_PrintString( 0, text, 0 );
        }
    	/* del if temp */
    	else
    	{
    		fb_hStrDelTemp( text );
    	}

        if( addquestion != FB_FALSE )
        {
            fb_PrintFixString( 0, pszDefaultQuestion, 0 );
        }
    }

    {
        /* create temporary string */
        FBSTRING str_result = { 0 };

        res = fb_DevFileReadLineDumb( stdin, &str_result, hWrapper );

        len = FB_STRSIZE(&str_result);

        /* We have to handle the NEWLINE stuff here because we *REQUIRE*
         * the *COMPLETE* temporary input string for the correct position
         * adjustment. */
        if( !addnewline ) {
            /* This is the easy and dumb method to do the position adjustment.
             * The problem is that it doesn't take TAB's into account. */
            int cols, rows;
            int old_y;

            fb_GetSize( &cols, &rows );
            fb_GetXY( NULL, &old_y );

            old_x += len - 1;
            old_x %= cols;
            old_x += 1;
            old_y -= 1;

            fb_Locate( old_y, old_x, -1, 0, 0 );
        }


        /* add contents of tempporary string to result buffer */
        fb_StrAssign( dst, dst_len, (void *)&str_result, -1, fillrem );

        fb_StrDelete( &str_result );

    }

	FB_UNLOCK();

    return res;
}
コード例 #8
0
ファイル: strw_convassign.c プロジェクト: ErosOlmi/fbc
FBCALL void *fb_WstrAssignToAEx
	(
		void *dst,
		ssize_t dst_chars,
		FB_WCHAR *src,
		int fill_rem,
		int is_init
	)
{
	ssize_t src_chars;

	if( dst == NULL )
		return dst;

    if( src != NULL )
    	src_chars = fb_wstr_Len( src );
    else
    	src_chars = 0;

	/* is dst var-len? */
	if( dst_chars == -1 )
	{
		/* src NULL? */
		if( src_chars == 0 )
		{
			if( is_init == FB_FALSE )
			{
				fb_StrDelete( (FBSTRING *)dst );
			}
			else
			{
				((FBSTRING *)dst)->data = NULL;
				((FBSTRING *)dst)->len = 0;
				((FBSTRING *)dst)->size = 0;
			}
		}
		else
		{
        	/* realloc dst if needed and copy src */
			if( is_init == FB_FALSE )
			{
				if( FB_STRSIZE( dst ) != src_chars )
					fb_hStrRealloc( (FBSTRING *)dst, src_chars, FB_FALSE );
			}
			else
			{
				fb_hStrAlloc( (FBSTRING *)dst, src_chars );
			}

			fb_wstr_ConvToA( ((FBSTRING *)dst)->data, src, src_chars );
		}
	}
	/* fixed-len or zstring.. */
	else
	{
		/* src NULL? */
		if( src_chars == 0 )
		{
			*(char *)dst = '\0';
		}
		else
		{
			/* byte ptr? as in C, assume dst is large enough */
			if( dst_chars == 0 )
				dst_chars = src_chars;

			fb_wstr_ConvToA( (char *)dst,
							 src,
							 (dst_chars <= src_chars? dst_chars : src_chars) );
		}

		/* fill reminder with null's */
		if( fill_rem != 0 )
		{
			dst_chars -= src_chars;
			if( dst_chars > 0 )
				memset( &(((char *)dst)[src_chars]), 0, dst_chars );
		}
	}

	return dst;
}