home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-05-12 | 11.8 KB | 582 lines | [TEXT/CWIE] |
- // #define DEBUG_ANSI 1
- // Basic Toolkit, 1994 (C) Mizutori Tetsuya
- // - MessageUtils.c, 1994/10/6, 1995/8/6
-
- #include <stdio.h>
- #include <stdarg.h>
-
- #include "NCR_Message.h"
-
-
- #ifdef COMMENT
- [Flag character]
- - Left-justify
- + print with a plus sign '+'
- ' ' Prefix a number with a space
- # %#s for Pascal-style string
- 0 pad the field with leading zeros
-
- [Field size]
- * Use the next argument (integer) as the field size
-
- [Argument size]
- h for short
- l,L for long
-
- [Conversion characters]
- c a single character
- s a string, with # for Str255
- e,E,f a signed decimal floating/fixed - point number
- g,G
- d,i,u a signed/unsigned decimal integer
- o an unsigned octal integer
- x,X an unsigned hexadecimal integer
- n,p an eight-digit hexadecimal value
- % a percent sign
- S,P Macintosh Pascal-style string for Str255
- t,T Macintosh Toolbox types, eg. OSType, four-byte constant
- #endif /*COMMENT */
-
-
- // define constants
- #define EOS '¥0'
-
- enum {
- kflag_none = 0, /* no */
- kflag_short = 1, /* h */
- kflag_long = 2, /* l */
- kflag_ldouble = 3, /* L */
- kflag_pound = 4, /* # */
- kflag_aster = 5, /* * */
- kflag_left = 6, /* - */
- kflag_plus = 7, /* + */
- kflag_space = 8, /* ' ' */
- kflag_zeros = 9, /* %0 */
- kflag_dot = 10 /* . */
- };
-
- #define kHexShortFS 4
- #define kHexLongFS 8
- #define kOctShortFS 6
- #define kOctLongFS 11
-
-
- // prptotype
- /***** static functions *****/
- static void vsMessage ( char *text, const char *format, va_list ap );
- static Boolean TestType ( short c );
- static char * GetDirective ( char *p, long *flag, long *fieldSize );
-
- static void WriteChars ( char *cstr );
- static void WriteChar( short c );
-
- static StringPtr NumToHex ( unsigned long n, StringPtr format, short digits );
- static StringPtr NumToOct ( unsigned long n, StringPtr format, short digits );
-
-
- /***** message test *****/
- #ifdef TEST
- void MessageTest ( void )
- {
- short i;
- char c = 'm';
- short n = 33;
- long x = 3333333;
- double f = 333.333;
- OSType t = 'odoc';
- char s[8] = "yes!";
- char s2[16] = "01234567890123";
- Str31 p = "¥ppascal!";
-
-
- // for (i=1;i<=100;++i) {
- // Message( "This is %3d lines. Mizutori Tetsuya + Mizutori Misuzu¥n", i );
- // }
-
- Message("¥n");
- Message("test '%010d'='%-10d' +'%010s'='%-010s'¥n",n,n,s,s);
- Message("test '%010s'='%s' +'%010s'='%s'¥n",s,s,s2,s2);
- Message("OSType('%4s') = ('%-10t')¥n",&t, t);
- Message("string('%10s'), ('%-10S')¥n",s,p);
-
- Message("short=%d, hex=0x%*lx¥ndouble=%lf, pointer=%p¥n" ¥
- "cstr=%s, char='%c'¥n" ¥
- "pstr=%#s¥n",
- n,7,x,f,&s,s,c,p);
- }
- #endif /* TEST */
-
- /***** set up *****/
- #define MAXLENGTH 2048
- void Message ( const char *format, ... )
- {
- va_list ap;
- char text[MAXLENGTH];
-
- va_start( ap, format );
- vsMessage( text, format, ap );
- va_end( ap );
-
- WriteChars( text );
- }
-
- void sMessage ( char *text, const char *format, ... )
- {
- va_list ap;
-
- va_start( ap, format );
- vsMessage( text, format, ap );
- va_end( ap );
- }
-
-
- /***** Message Window *****/
- #define kBaseResID 128
- #define kMoveToFront (WindowPtr) -1L
-
- /***** Constants & Globals *****/
- short kLeftMargin = 4;
- short kRowStart = 285;
- short kFontSize = 9;
- short kRowHeight = 11; /* kFontSize+2 */
- short kHorizontalOffset = 0;
-
- WindowPtr gMsgWindow = nil;
-
- /***** create MessageBoard window *****/
- void NewMessage ( void )
- {
- WindowPtr window;
- Rect windRect;
- GrafPtr oldPort;
-
- window = GetNewWindow( kBaseResID, nil, kMoveToFront );
- if ( window == nil ) {
- SysBeep(10);
- ExitToShell(); }
-
- GetPort( &oldPort );
- SetPort( window );
-
- TextSize( kFontSize );
-
- ShowWindow( window );
-
- gMsgWindow = window;
-
- SetPort( oldPort );
- }
-
- /***** WriteTextln *****/
- static void WriteChars ( char *text )
- {
- long i = 0, k = 0;
- char c;
- Str255 str = "¥p";
-
- // while ( (c=text[i++]) != EOS ) WriteChar( (unsigned char) c );
-
- while ( (c=text[i++]) != EOS ) {
- if (c == '¥n' || c == '¥r' ) {
- str[0] = k;
- WriteTextln(str);
- k = 0;
- } else if ( k > 250 ) {
- str[0] = k;
- WriteText(str);
- k = 0;
- } else {
- str[++k] = c;
- }
- }
-
- if ( k > 0 ) {
- str[0] = k;
- WriteText( str );
- }
- }
-
- static void WriteChar( short c )
- {
- GrafPtr oldPort;
-
- if ( gMsgWindow == nil ) return;
-
- GetPort( &oldPort );
- SetPort( gMsgWindow );
-
- if ( c == '¥n' || c == '¥r' ) WriteTextln("¥p");
- else DrawChar( c );
-
- SetPort( oldPort );
- }
-
- void WriteTextln ( StringPtr text )
- {
- RgnHandle tempRgn;
- WindowPtr window;
- GrafPtr oldPort;
-
- if ( gMsgWindow == nil ) return;
-
- GetPort( &oldPort );
- SetPort( gMsgWindow );
-
- DrawString( text );
-
- window = FrontWindow();
- tempRgn = NewRgn();
- ScrollRect( &window->portRect, kHorizontalOffset, -kRowHeight, tempRgn );
- DisposeRgn( tempRgn );
-
- MoveTo( kLeftMargin, (window->portRect).bottom - 2 );
-
- SetPort( oldPort );
- }
-
- void WriteText ( StringPtr text )
- {
- GrafPtr oldPort;
-
- if ( gMsgWindow == nil ) return;
-
- GetPort( &oldPort );
- SetPort( gMsgWindow );
-
- DrawString( text );
-
- SetPort( oldPort );
- }
-
- void WriteTextNumb ( long value )
- {
- Str31 text;
- GrafPtr oldPort;
-
- if ( gMsgWindow == nil ) return;
-
- GetPort( &oldPort );
- SetPort( gMsgWindow );
-
- NumToString( value, text );
- DrawString( text );
-
- SetPort( oldPort );
- }
-
- void WriteTextType ( OSType type )
- {
- Str32 text = "¥p****";
- GrafPtr oldPort;
-
- if ( gMsgWindow == nil ) return;
-
- GetPort( &oldPort );
- SetPort( gMsgWindow );
-
- BlockMove( &type, &text[1], 4);
- DrawString( text );
-
- SetPort( oldPort );
- }
-
- void WriteTextPeek ( Ptr dataPtr, Size length )
- {
- long i;
- // Size hSize;
- unsigned char *p, c;
- Str31 text = "¥p*";
- Str31 text2 = "¥p¥¥**";
- unsigned char hex[17] = "0123456789abcdef";
- GrafPtr oldPort;
-
- if ( gMsgWindow == nil ) return;
-
- GetPort( &oldPort );
- SetPort( gMsgWindow );
-
- p = (unsigned char *) dataPtr;
- // hSize = GetPtrSize( dataPtr );
-
- if ( length > 8 ) WriteTextln("¥p");
-
- for ( i=0; i<length; ++i ) {
- if ( (i > 0) && ( (i % 16) == 0 ) ) WriteTextln("¥p");
- c = p[i];
- //if ( c < ' ' || c > 0x7E ) c = '.';
- if ( c < ' ' || c > 0x7E ) {
- text2[2] = hex[(c>>4) & 0x0f]; text2[3]=hex[c & 0x0f];
- DrawString( text2 );
- } else {
- text[1] = c;
- DrawString( text );
- }
- }
-
- SetPort( oldPort );
- }
-
- /***** static functions *****/
-
- #define bitTst(flag,bit) ( (Boolean) ( ((flag) & (1 << (bit))) != 0 ) )
- #define bitSet(flag,bit) ( flag |= (1 << (bit)) )
-
- #define va_arg_int( ap, flag ) ¥
- ( bitTst(flag,kflag_long) ? va_arg(ap,long) : va_arg(ap,short) )
-
- #define va_arg_uint( ap, flag ) ¥
- ( bitTst(flag,kflag_long) ? va_arg(ap,unsigned long) : va_arg(ap,unsigned short) )
-
- #define va_arg_float( ap, flag ) ¥
- ( bitTst(flag,kflag_long) ? va_arg(ap,long double) : va_arg(ap,short double) )
-
- #define FieldSize(fs,shortfs,longfs) ¥
- ( (fs) > 0 ? (fs) : ( bitTst(flag,kflag_long) ? (longfs) : (shortfs) ) )
-
-
- static void vsMessage ( char *text, const char *format, va_list ap )
- {
- // va_list ap;
- long n;
- short i, j, k, h;
- char c, d, zeroChar;
- char *p, *q, *s;
- long value;
- unsigned long uvalue;
- long double fvalue;
- long flag;
- long digits;
- Boolean shiftLeft;
- Str63 str;
-
-
- // va_start( ap, format );
-
- n = 0; p = (char *) format;
- while ( (c=*(p++)) != EOS /* && n<MAXLENGTH-20 */ ) {
-
- if ( c != '%' ) { text[n++] = c; continue; }
-
- digits = 0;
-
- q = p;
- p = GetDirective ( p, &flag, &digits );
-
- if ( (c=*(p++)) == EOS ) { --p; break; }
-
- zeroChar = ( bitTst(flag,kflag_zeros) ? '0' : ' ' );
- shiftLeft = bitTst( flag, kflag_left );
-
- if ( bitTst( flag, kflag_aster ) && TestType( (unsigned char) c ) ) {
- digits = va_arg( ap, short ); }
-
- switch ( c ) {
- case_int:
- case 'i':
- case 'd':
- value = va_arg_int( ap, flag );
- NumToString( value, str );
- goto case_printdigit;
- break;
- case 'u':
- value = va_arg_uint( ap, flag );
- NumToString( value, str );
- goto case_printdigit;
- break;
- case_hex:
- case 'x':
- case 'X':
- value = va_arg_uint( ap, flag );
- NumToHex( value, str, FieldSize(digits,kHexShortFS,kHexLongFS) );
- goto case_printdigit;
- break;
- case_oct:
- case 'o':
- value = va_arg_uint( ap, flag );
- NumToOct( value, str, FieldSize(digits,kOctShortFS,kOctLongFS) );
- goto case_printdigit;
- break;
- case_float:
- case 'f':
- case 'e':
- case 'E':
- case 'g':
- case 'G':
- fvalue = va_arg_float( ap, flag );
- value = fvalue;
- NumToString( value, str );
- goto case_printdigit;
- break;
- case_pointer:
- case 'p':
- case 'n':
- value = (unsigned long) va_arg( ap, void * );
- NumToHex( value, str, kHexLongFS );
- goto case_printdigit;
- break;
- case 't':
- case 'T':
- value = (unsigned long) va_arg( ap, void * );
- str[0] = sizeof(OSType);
- BlockMove( &value, &str[1], str[0] );
- goto case_printdigit;
- break;
- case_printdigit:
- k = str[0];
- s = (char *) &str[1];
- goto case_printstr;
- break;
- case 's':
- s = va_arg( ap, char * );
- if ( bitTst( flag, kflag_pound ) ) {
- if ( digits == 0 )
- goto case_pstr0;
- else
- goto case_pstr1;
- } else {
- if ( digits == 0 )
- goto case_cstr0;
- else
- goto case_cstr1;
- }
- break;
- case 'S':
- case 'P':
- s = va_arg( ap, char * );
- goto case_pstr0;
- break;
- case_cstr0:
- k = 0; while ( s[k] != EOS ) ++k;
- goto case_printstr;
- break;
- case_cstr1:
- k = 0; while ( s[k] != EOS && k<digits ) ++k;
- goto case_printstr;
- break;
- case_pstr0:
- case_pstr1:
- k = * (unsigned char *) s;
- ++s;
- goto case_printstr;
- break;
- case_printstr:
- // digits = field width
- // k = string length
- // *s = start of string
- h = digits - k; if ( h < 0 ) h = 0;
- if ( ! shiftLeft )
- while ( --h >= 0 ) text[n++] = zeroChar;
- while ( --k >= 0 ) text[n++] = *(s++);
- if ( shiftLeft )
- while ( --h >= 0 ) text[n++] = zeroChar;
- break;
- case_char:
- case 'c':
- value = va_arg( ap, unsigned short ); /* not 'char' */
- text[n++] = value;
- break;
- case '%':
- text[n++] = c;
- break;
- case_none:
- default:
- p = q;
- text[n++] = '%';
- break;
- }
- }
- text[n++] = EOS;
-
- // va_end( ap );
-
- for (i=1;i<=n;++i) if ( text[i] == '¥n' ) text[i] = '¥r';
- }
-
-
- static Boolean TestType ( short c )
- {
- register short n = 0;
- register short d;
- char types[] = "dioxXucsfeEgGpntTSP";
-
- while ( (d=types[n++]) != EOS )
- if ( c == d ) return true;
-
- return false;
- }
-
-
- static char * GetDirective ( char *p, long *flag, long *fieldSize )
- {
- char c;
- long fflag = 0;
- long n = 0;
- Boolean done = false;
- char text[32] = "";
-
- while ( (c=*p) != EOS && ! done ) { ++p;
- if ( '0' <= c && c <= '9' ) {
- if ( n < 31 && ! bitTst(fflag,kflag_dot) ) {
- text[n++] = c; text[n] = EOS; }
- continue; }
- switch ( c ) {
- case '+': bitSet( fflag, kflag_plus ); break;
- case '-': bitSet( fflag, kflag_left ); break;
- case ' ': bitSet( fflag, kflag_space ); break;
- case '.': bitSet( fflag, kflag_dot ); break;
- case 'h': bitSet( fflag, kflag_short ); break;
- case 'l': bitSet( fflag, kflag_long ); break;
- case 'L': bitSet( fflag, kflag_long ); break;
- case '*': bitSet( fflag, kflag_aster ); break;
- case '#': bitSet( fflag, kflag_pound ); break;
- default: --p; done = true; break;
- }
- }
-
- if ( n > 0 && text[0] == '0' ) bitSet( fflag, kflag_zeros );
-
- c2pstr( text );
- StringToNum( (StringPtr) text, fieldSize );
-
- *flag = fflag;
-
- return p;
- }
-
-
- /***** hex & oct number conversion *****/
- static char *conv = "0123456789abcdef";
-
- static StringPtr NumToHex ( unsigned long n, StringPtr format, short digits )
- {
- // static StringPtr format = "¥p00000000";
- unsigned long i;
-
- if ( digits > 8 || digits < 0 ) digits = 8;
-
- format[0] = digits; /* adjust length byte of output string */
-
- for ( i=0; i<digits; ( n>>=4, ++i) )
- format[ digits-i ] = conv[ n & 0x0f ];
-
- return format;
- }
-
- static StringPtr NumToOct ( unsigned long n, StringPtr format, short digits )
- {
- // static StringPtr format = "¥p000000000000";
- unsigned long i;
-
- if ( digits > 12 || digits < 0 ) digits = 12;
-
- format[0] = digits; /* adjust length byte of output string */
-
- for ( i=0; i<digits; ( n>>=3, ++i) )
- format[ digits-i ] = conv[ n & 0x07 ];
-
- return format;
- }
-
-
- // end of program
-