• R/O
  • HTTP
  • SSH
  • HTTPS

bif-6809: コミット

ソースコード及び仕様書など
Source and documentation


コミットメタ情報

リビジョン1164a0ae2bea97cfd8a57f7c4a1888482004b59c (tree)
日時2019-04-29 16:55:09
作者Joel Matthew Rees <joel.rees@gmai...>
コミッターJoel Matthew Rees

ログメッセージ

Flaky arguments, but SCREEN to variable lines is working for variable widths and blocks, I think.

変更サマリ

差分

--- a/bif-img.c
+++ b/bif-img.c
@@ -1 +1 @@
1-/* Tool for working with BIF-6809 images. // Written by Joel Matthew Rees, Amagasaki, Japan, April 2019, // Parts adapted from the author's 32col.c, written 1999. // Copyright 1999, 2019, Joel Matthew Rees. // Permission granted in advance for all uses // with the condition that this copyright and permission notice are retained. // // BIF-6809 project page: https://osdn.net/projects/bif-6809/ */ #include <limits.h> #include <stdio.h> #include <stdlib.h> /* for EXIT_SUCCESS */ #include <string.h> #include <ctype.h> #define ScreenWidth 32 #define ScreenHeight 32 #define BufferPlay 3 /* room for CR/LF and NUL */ #define BufferWidth ( ScreenWidth + BufferPlay ) #define TO_SCREEN 1 const char kTo_ScreenStr[] = "--to-screens"; #define TO_EOLN_TEXT 2 const char kTo_EOLN_textStr[] = "--to-eoln-text"; const char kBlockSize[] = "-size"; const char kBlockOffset[] = "-off"; const char kBlockCount[] = "-count"; void toEOLNtext( FILE * input, FILE * output, unsigned blocksize, unsigned offset, unsigned count /*, int linecountflag */ ) { char buffer[ ScreenHeight ][ BufferWidth ]; unsigned long start = blocksize * offset; unsigned long bytecount = blocksize * count; unsigned long totalBytes = 0; /* dbg */ printf( "size: %u; off: %u; count: %u\n", blocksize, offset, count ); if ( start > 0 ) { fseek( input, start, SEEK_SET ); } while ( !feof( input ) && ( totalBytes < bytecount ) ) { int lineCount; for ( lineCount = 0; lineCount < ScreenHeight && !feof( input ); ++lineCount ) { int length = fread( buffer[ lineCount ], sizeof (char), ScreenWidth, input ); totalBytes += length; while ( --length >= 0 && ( isspace( buffer[ lineCount ][ length ] ) || !isprint( buffer[ lineCount ][ length ] ) ) ) /* "empty" loop */; buffer[ lineCount ][ ++length ] = '\0'; } if ( lineCount > 1 || ( lineCount == 1 && buffer[ 0 ][ 0 ] != '\0' ) ) { int line = 0; while ( --lineCount > 0 && buffer[ lineCount ][ 0 ] == '\0' ) /* This actually is probably a bug. */ /* "empty" loop */; for ( line = 0; line <= lineCount; ++line ) /* check end conditions again. */ { fputs( buffer[ line ], output ); fputc( '\n', output ); } /* fputc( '\f', output ); This is not useful. */ } } } #define FILE_START 0x200 /* beyond char range. */ #define LINE_START 0x400 /* beyond char range. */ void toScreens( FILE * input, FILE * output /*, int linecountflag */ ) { char buffer[ ScreenHeight ][ BufferWidth ]; int eolFlag = FILE_START; while ( !feof( input ) ) { int lineCount; for ( lineCount = 0; lineCount < ScreenHeight; ++lineCount ) { int length = 0; char * line = buffer[ lineCount ]; int ch = LINE_START; while ( ( length < ScreenWidth ) && !feof( input ) ) { ch = fgetc( input ); if ( ( length == 0 ) && ( ( ( ch == '\r' ) && ( eolFlag == '\n' ) ) || ( ( ch == '\n' ) && ( eolFlag == '\r' ) ) ) ) { ch = fgetc( input ); } eolFlag = ch; if ( ( ch == '\n' ) || ( ch == '\r' ) || feof( input ) ) { break; /* The habit is to set a NUL, but not for SCREENs. */ } line[ length++ ] = ch; /* dbg * / putchar( ch ); */ } /* dbg * / printf( "||end:%d:", length ); */ while ( length < ScreenWidth ) { line[ length++ ] = ' '; /* dbg * / putchar( '*' );*/ } /* dbg * / printf( "||:%d:%d\n", length, lineCount ); */ } /* dbg * / printf( "<<screen:%d:>>\n", lineCount ); */ if ( lineCount > 0 ) { int line = 0; for ( line = 0; line < lineCount; ++line ) { fwrite( buffer[ line ], sizeof (char), ScreenWidth, output ); } } } } int getNumericParameter( const char parameter[], char * argstr, unsigned long * rval, long low, unsigned long limit ) { char * scanpt = argstr; unsigned long result = 0; size_t eqpt = strlen( parameter ); if ( strncmp( parameter, argstr, eqpt ) == 0 ) { if ( argstr[ eqpt ] != '=' ) { printf( "\t%s needs '=' in '%s'\n,", parameter, argstr ); return INT_MIN | 16; } ++eqpt; scanpt += eqpt; result = strtoul( scanpt, &scanpt, 0 ); if ( scanpt <= argstr + eqpt ) { printf( "\tBad %s value specified in '%s'\n,", parameter, argstr ); return INT_MIN | 32; } if ( ( result < low ) || ( result >= limit ) ) { printf( "\t%s value %lu out of range in '%s', try %lu\n,", parameter, result, argstr, * rval ); return INT_MIN | 64; } * rval = result; return 1; } return 0; } int main(int argc, char * argv[] ) { FILE * input = stdin; FILE * output = stdout; int direction = 0; int errval = 0; unsigned long blocksize = 1024; unsigned long offset = 0; unsigned long count = UINT_MAX; int i; for ( i = 4; i < argc; ++i ) { int berr = 0; int oerr = 0; int cerr = 0; if ( ( ( berr |= getNumericParameter( kBlockSize, argv[ i ], &blocksize, 1, 0x8000UL ) ) <= 0 ) && ( ( oerr |= getNumericParameter( kBlockOffset, argv[ i ], &offset, 1, USHRT_MAX ) ) <= 0 ) && ( ( cerr |= getNumericParameter( kBlockCount, argv[ i ], &count, 1, USHRT_MAX ) ) <= 0 ) ) { printf( "Unrecognized %s\n", argv[ i ] ); errval |= berr | oerr | cerr; } } if ( ( errval >= 0 ) && ( argc > 3 ) ) { if ( strcmp( argv[ 1 ], kTo_ScreenStr ) == 0 ) { direction = TO_SCREEN; } else if ( strcmp( argv[ 1 ], kTo_EOLN_textStr ) == 0 ) { direction = TO_EOLN_TEXT; } if ( direction != 0 ) { if ( strcmp( argv[ 2 ], "--" ) != 0 ) { input = fopen( argv[ 2 ], "rb" ); } if ( input == NULL ) { printf( "Error opening file <%s> for input.\n", argv[ 2 ] ); direction |= INT_MIN | 4; } if ( strcmp( argv[ 3 ], "--" ) != 0 ) { output = fopen( argv[ 3 ], "wb" ); } if ( output == NULL ) { printf( "Error opening file <%s> for output.\n", argv[ 3 ] ); fclose( input ); direction |= INT_MIN | 8; } } } if ( direction < -1 ) { printf( "*** %s quitting. ***\n", argv[ 0 ] ); return EXIT_FAILURE; } else if ( direction == 0 ) { puts( "usage:" ); printf( "\t%s %s <infile> <outfile>\n", argv[ 0 ], kTo_ScreenStr ); printf( "\t%s %s <infile> <outfile> [ %s=<block-size> ] [ %s=<offset> ] [ %s=<count> ]\n", argv[ 0 ], kTo_EOLN_textStr, kBlockSize, kBlockOffset, kBlockCount ); printf( "** Default block size is 1024, compatible with Forth SCREENs.\n" ); printf( "** Default count is length of input file.\n" ); printf( "** 0xhexadecimal and 0octal permitted for size, etc.\n" ); printf( "** Replace <file> with -- for stdfiles in pipes\n" ); /* printf( "\t%s --to-image <filename> <imagename> <offset>\n", argv[ 0 ] ); */ return EXIT_SUCCESS; } switch ( direction ) { case TO_SCREEN: toScreens( input, output ); break; case TO_EOLN_TEXT: toEOLNtext( input, output, blocksize, offset, count ); break; } return EXIT_SUCCESS; }
\ No newline at end of file
1+/* Tool for working with BIF-6809 images. // Written by Joel Matthew Rees, Amagasaki, Japan, April 2019, // Parts adapted from the author's 32col.c, written 1999. // Copyright 1999, 2019, Joel Matthew Rees. // Permission granted in advance for all uses // with the condition that this copyright and permission notice are retained. // // BIF-6809 project page: https://osdn.net/projects/bif-6809/ */ #include <limits.h> #include <stdio.h> #include <stdlib.h> /* for EXIT_SUCCESS */ #include <string.h> #include <ctype.h> #define ScreenSize 1024 #define ScreenWidth 32 #define ScreenHeight ( ScreenSize / ScreenWidth ) #define BufferPlay 3 /* room for CR/LF and NUL */ #define BufferWidth ( ScreenWidth + BufferPlay ) #define TO_SCREEN 1 const char kTo_ScreenStr[] = "--to-screens"; #define TO_EOLN_TEXT 2 const char kTo_EOLN_textStr[] = "--to-eoln-text"; const char kBlockSizeStr[] = "-size"; const char kBlockWidthStr[] = "-width"; const char kBlockOffsetStr[] = "-off"; const char kBlockCountStr[] = "-count"; const char kSuppressEndLinesStr[] = "-suppressEndLines"; void toEOLNtext( FILE * input, FILE * output, char * buffer /* Must have room for BufferPlay extra bytes per line. */, unsigned blocksize, unsigned width, unsigned offset, unsigned count, int suppressEndLines /*, int linecountflag */ ) { unsigned long start = blocksize * offset; unsigned long bytecount = blocksize * count; unsigned long totalBytes = 0; /* dbg */ fprintf( stderr, "size: %u; width: %u; off: %u; count: %u\n", blocksize, width, offset, count ); if ( start > 0 ) { fseek( input, start, SEEK_SET ); } while ( !feof( input ) && ( totalBytes < bytecount ) ) { int lineCount; for ( lineCount = 0; lineCount < ScreenHeight && !feof( input ); ++lineCount ) { char * linestart = buffer + lineCount * ( width + BufferPlay ); int length = fread( linestart, sizeof (char), width, input ); totalBytes += length; while ( --length >= 0 && ( isspace( linestart[ length ] ) || !isprint( linestart[ length ] ) ) ) /* "empty" loop */; linestart[ ++length ] = '\0'; } if ( lineCount > 1 || ( lineCount == 1 && buffer[ 0 ] != '\0' ) ) { int line = 0; if ( suppressEndLines ) { while ( --lineCount > 0 && buffer[ lineCount * ( width + BufferPlay ) ] == '\0' ) { /* "empty" loop: note tested NUL is first character of line. */ } } else { --lineCount; } for ( line = 0; line <= lineCount; ++line ) /* End condition intentional! */ { fputs( buffer + line * ( width + BufferPlay ), output ); fputc( '\n', output ); } /* fputc( '\f', output ); This is not useful. */ } } } #define FILE_START 0x200 /* beyond char range. */ #define LINE_START 0x400 /* beyond char range. */ void toScreens( FILE * input, FILE * output, char * bugffer /* Must have room for BufferPlay extra bytes per line. */, unsigned blocksize, unsigned width, unsigned offset, unsigned count /*, int linecountflag */ ) { char buffer[ ScreenHeight ][ BufferWidth ]; int eolFlag = FILE_START; while ( !feof( input ) ) { int lineCount; for ( lineCount = 0; lineCount < ScreenHeight; ++lineCount ) { int length = 0; char * line = buffer[ lineCount ]; int ch = LINE_START; while ( ( length < ScreenWidth ) && !feof( input ) ) { ch = fgetc( input ); if ( ( length == 0 ) && ( ( ( ch == '\r' ) && ( eolFlag == '\n' ) ) || ( ( ch == '\n' ) && ( eolFlag == '\r' ) ) ) ) { ch = fgetc( input ); } eolFlag = ch; if ( ( ch == '\n' ) || ( ch == '\r' ) || feof( input ) ) { break; /* The habit is to set a NUL, but not for SCREENs. */ } line[ length++ ] = ch; /* dbg * / putchar( ch ); */ } /* dbg * / printf( "||end:%d:", length ); */ while ( length < ScreenWidth ) { line[ length++ ] = ' '; /* dbg * / putchar( '*' );*/ } /* dbg * / printf( "||:%d:%d\n", length, lineCount ); */ } /* dbg * / printf( "<<screen:%d:>>\n", lineCount ); */ if ( lineCount > 0 ) { int line = 0; for ( line = 0; line < lineCount; ++line ) { fwrite( buffer[ line ], sizeof (char), ScreenWidth, output ); } } } } int getNumericParameter( const char parameter[], char * argstr, unsigned long * rval, long low, unsigned long high ) { char * scanpt = argstr; unsigned long result = 0; size_t eqpt = strlen( parameter ); if ( strncmp( parameter, argstr, eqpt ) == 0 ) { if ( argstr[ eqpt ] != '=' ) { printf( "\t%s needs '=' in '%s', ", parameter, argstr ); return INT_MIN | 16; } ++eqpt; scanpt += eqpt; result = strtoul( scanpt, &scanpt, 0 ); if ( scanpt <= argstr + eqpt ) { printf( "\tBad %s value specified in '%s'\n,", parameter, argstr ); return INT_MIN | 32; } if ( ( result < low ) || ( result > high ) ) { fprintf( stderr, "\t%s value %lu out of range in '%s', try %lu\n,", parameter, result, argstr, * rval ); return INT_MIN | 64; } * rval = result; return 1; } return 0; } int main(int argc, char * argv[] ) { FILE * input = stdin; FILE * output = stdout; char * buffer = NULL; int direction = 0; int errval = 0; unsigned long blocksize = ScreenSize; unsigned long width = ScreenWidth; unsigned long offset = 0; unsigned long count = UINT_MAX; unsigned long suppressEndLines = 0; int i; for ( i = 4; i < argc; ++i ) { int berr = 0; int werr = 0; int oerr = 0; int cerr = 0; int serr = 0; if ( ( ( berr |= getNumericParameter( kBlockSizeStr, argv[ i ], &blocksize, 1, 0x8000UL ) ) > 0 ) || ( ( werr |= getNumericParameter( kBlockWidthStr, argv[ i ], &width, 1, 1024 ) ) > 0 ) || ( ( oerr |= getNumericParameter( kBlockOffsetStr, argv[ i ], &offset, 0, USHRT_MAX ) ) > 0 ) || ( ( cerr |= getNumericParameter( kBlockCountStr, argv[ i ], &count, 1, USHRT_MAX ) ) > 0 ) || ( ( serr |= getNumericParameter( kSuppressEndLinesStr, argv[ i ], &suppressEndLines, 0, 1 ) ) > 0 ) ) { /* empty */ } else { printf( "\tUnrecognized %s\n", argv[ i ] ); /* This isn't firing for gobbledygook. */ } errval |= berr | werr | oerr | cerr | serr; } if ( ( blocksize % width ) != 0 ) { errval |= INT_MIN | 1024; printf( "Block size %lu is not even multiple of edit width %lu.\n", blocksize, width ); } if ( ( errval >= 0 ) && ( argc > 3 ) ) { if ( strcmp( argv[ 1 ], kTo_ScreenStr ) == 0 ) { direction = TO_SCREEN; } else if ( strcmp( argv[ 1 ], kTo_EOLN_textStr ) == 0 ) { direction = TO_EOLN_TEXT; } if ( direction != 0 ) { if ( strcmp( argv[ 2 ], "--" ) != 0 ) { input = fopen( argv[ 2 ], "rb" ); } if ( input == NULL ) { fprintf( stderr, "Error opening file <%s> for input.\n", argv[ 2 ] ); direction |= INT_MIN | 4; } if ( strcmp( argv[ 3 ], "--" ) != 0 ) { output = fopen( argv[ 3 ], "wb" ); } if ( output == NULL ) { fprintf( stderr, "Error opening file <%s> for output.\n", argv[ 3 ] ); fclose( input ); direction |= INT_MIN | 8; } if ( ( buffer = malloc( blocksize + BufferPlay * ( blocksize / width ) ) ) == NULL ) { fprintf( stderr, "Buffer allocation failure\n" ); direction |= INT_MIN | 16; } } } if ( direction < -1 ) { fprintf( stderr, "*** %s quitting. ***\n", argv[ 0 ] ); return EXIT_FAILURE; } else if ( direction == 0 ) { puts( "usage:" ); printf( "\t%s %s <infile> <outfile>\n", argv[ 0 ], kTo_ScreenStr ); printf( "\t%s %s <infile> <outfile> [ %s=<block-size> ] [ %s=<width> ] [ %s=<offset> ] [ %s=<count> ] [ %s={0|1} ]\n", argv[ 0 ], kTo_EOLN_textStr, kBlockSizeStr, kBlockWidthStr, kBlockOffsetStr, kBlockCountStr, kSuppressEndLinesStr ); printf( "** Default block size is %d, compatible with Forth SCREENs.\n", ScreenSize ); printf( "** Default width is %d, compatible with Color Computer 1 & 2 text display.\n", ScreenWidth ); printf( "** Default count is length of input file.\n" ); printf( "** %s=1 to suppress trailing blank lines in SCREEN, default 0.\n", kSuppressEndLinesStr ); printf( "** 0xhexadecimal and 0octal permitted for size, etc.\n" ); printf( "** Replace <file> with -- for stdfiles in pipes\n" ); /* printf( "\t%s --to-image <filename> <imagename> <offset>\n", argv[ 0 ] ); */ return EXIT_SUCCESS; } switch ( direction ) { case TO_SCREEN: toScreens( input, output, buffer, blocksize, width, offset, count ); break; case TO_EOLN_TEXT: toEOLNtext( input, output, buffer, blocksize, width, offset, count, suppressEndLines ); break; } return EXIT_SUCCESS; }
\ No newline at end of file
旧リポジトリブラウザで表示