home *** CD-ROM | disk | FTP | other *** search
/ Best Tools for JAVA / Best Tools for JAVA.iso / JAVA_ALL / JAVA_UTL / HYPERPRO / SRC / PVS / UTILS / FMT.JAV < prev    next >
Encoding:
Text File  |  1996-09-14  |  11.2 KB  |  358 lines

  1. // Fmt - some simple single-arg sprintf-like routines
  2. //
  3. // It is apparently impossible to declare a Java method that accepts
  4. // variable numbers of any type of argument.  You can declare it to take
  5. // Objects, but numeric variables and constants are not in fact Objects.
  6. //
  7. // However, using the built-in string concatenation, it's almost as
  8. // convenient to make a series of single-argument formatting routines.
  9. //
  10. // Fmt can format the following types:
  11. //     int long float double char String Object
  12. // For each type there is a set of overloaded methods, each returning
  13. // a formatted String.  There's the plain formatting version:
  14. //     Fmt.fmt( x )
  15. // There's a version specifying a minimum field width:
  16. //     Fmt.fmt( x, minWidth )
  17. // And there's a version that takes flags:
  18. //     Fmt.fmt( x, minWidth, flags )
  19. // Currently available flags are:
  20. //     Fmt.ZF - zero-fill
  21. //     Fmt.LJ - left justify
  22. //     Fmt.HX - hexadecimal
  23. //     Fmt.OC - octal
  24. // For doubles and floats, there's a significant-figures parameter before
  25. // the flags:
  26. //     Fmt.fmt( d )
  27. //     Fmt.fmt( d, minWidth )
  28. //     Fmt.fmt( d, minWidth, sigFigs )
  29. //     Fmt.fmt( d, minWidth, sigFigs, flags )
  30. //
  31. // Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>.  All rights reserved.
  32. //
  33. // Redistribution and use in source and binary forms, with or without
  34. // modification, are permitted provided that the following conditions
  35. // are met:
  36. // 1. Redistributions of source code must retain the above copyright
  37. //    notice, this list of conditions and the following disclaimer.
  38. // 2. Redistributions in binary form must reproduce the above copyright
  39. //    notice, this list of conditions and the following disclaimer in the
  40. //    documentation and/or other materials provided with the distribution.
  41. //
  42. // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  43. // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  44. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  45. // ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  46. // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  47. // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  48. // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  49. // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  50. // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  51. // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  52. // SUCH DAMAGE.
  53. //
  54. // Visit the ACME Labs Java page for up-to-date versions of this and other
  55. // fine Java utilities: http://www.acme.com/java/
  56.  
  57. package PVS.Utils;
  58.  
  59. public class Fmt
  60.     {
  61.  
  62.     // Flags.
  63.     public static final int ZF = 1;        // zero-fill
  64.     public static final int LJ = 2;        // left justify
  65.     public static final int HX = 4;        // hexadecimal
  66.     public static final int OC = 8;        // octal
  67.     private static final int WN = 16;        // was a number - internal use
  68.  
  69.     // int
  70.     public static String fmt( int i )
  71.     {
  72.     return fmt( i, 0, 0 );
  73.     }
  74.     public static String fmt( int i, int minWidth )
  75.     {
  76.     return fmt( i, minWidth, 0 );
  77.     }
  78.     public static String fmt( int i, int minWidth, int flags )
  79.     {
  80.     boolean hexadecimal = ( ( flags & HX ) != 0 );
  81.     boolean octal = ( ( flags & OC ) != 0 );
  82.     if ( hexadecimal )
  83.         return fmt( Integer.toString( i, 16 ), minWidth, flags | WN );
  84.     else if ( octal )
  85.         return fmt( Integer.toString( i, 8 ), minWidth, flags | WN );
  86.     else
  87.         return fmt( Integer.toString( i ), minWidth, flags | WN );
  88.     }
  89.  
  90.     // long
  91.     public static String fmt( long l )
  92.     {
  93.     return fmt( l, 0, 0 );
  94.     }
  95.     public static String fmt( long l, int minWidth )
  96.     {
  97.     return fmt( l, minWidth, 0 );
  98.     }
  99.     public static String fmt( long l, int minWidth, int flags )
  100.     {
  101.     boolean hexadecimal = ( ( flags & HX ) != 0 );
  102.     boolean octal = ( ( flags & OC ) != 0 );
  103.     if ( hexadecimal )
  104.         return fmt( Long.toString( l, 16 ), minWidth, flags | WN );
  105.     else if ( octal )
  106.         return fmt( Long.toString( l, 8 ), minWidth, flags | WN );
  107.     else
  108.         return fmt( Long.toString( l ), minWidth, flags | WN );
  109.     }
  110.  
  111.     // float
  112.     public static String fmt( float f )
  113.     {
  114.     return fmt( f, 0, 0, 0 );
  115.     }
  116.     public static String fmt( float f, int minWidth )
  117.     {
  118.     return fmt( f, minWidth, 0, 0 );
  119.     }
  120.     public static String fmt( float f, int minWidth, int sigFigs )
  121.     {
  122.     return fmt( f, minWidth, sigFigs, 0 );
  123.     }
  124.     public static String fmt( float f, int minWidth, int sigFigs, int flags )
  125.     {
  126.     if ( sigFigs != 0 )
  127.         return fmt(
  128.         sigFigFix( Float.toString( f ), sigFigs ), minWidth,
  129.         flags | WN );
  130.     else
  131.         return fmt( Float.toString( f ), minWidth, flags | WN );
  132.     }
  133.  
  134.     // double
  135.     public static String fmt( double d )
  136.     {
  137.     return fmt( d, 0, 0, 0 );
  138.     }
  139.     public static String fmt( double d, int minWidth )
  140.     {
  141.     return fmt( d, minWidth, 0, 0 );
  142.     }
  143.     public static String fmt( double d, int minWidth, int sigFigs )
  144.     {
  145.     return fmt( d, minWidth, sigFigs, 0 );
  146.     }
  147.     public static String fmt( double d, int minWidth, int sigFigs, int flags )
  148.     {
  149.     if ( sigFigs != 0 )
  150.         // Should really use something better than Double.toString() here.
  151.         return fmt(
  152.         sigFigFix( Double.toString( d ), sigFigs ), minWidth,
  153.         flags | WN );
  154.     else
  155.         return fmt( Double.toString( d ), minWidth, flags | WN );
  156.     }
  157.  
  158.     // char
  159.     public static String fmt( char c )
  160.     {
  161.     return fmt( c, 0, 0 );
  162.     }
  163.     public static String fmt( char c, int minWidth )
  164.     {
  165.     return fmt( c, minWidth, 0 );
  166.     }
  167.     public static String fmt( char c, int minWidth, int flags )
  168.     {
  169.     // return fmt( Character.toString( c ), minWidth, flags );
  170.     // Character currently lacks a static toString method.  Workaround
  171.     // is to make a temporary instance and use the instance toString.
  172.     return fmt( new Character( c ).toString(), minWidth, flags );
  173.     }
  174.  
  175.     // Object
  176.     public static String fmt( Object o )
  177.     {
  178.     return fmt( o, 0, 0 );
  179.     }
  180.     public static String fmt( Object o, int minWidth )
  181.     {
  182.     return fmt( o, minWidth, 0 );
  183.     }
  184.     public static String fmt( Object o, int minWidth, int flags )
  185.     {
  186.     return fmt( o.toString(), minWidth, flags );
  187.     }
  188.  
  189.     // String
  190.     public static String fmt( String s )
  191.     {
  192.     return fmt( s, 0, 0 );
  193.     }
  194.     public static String fmt( String s, int minWidth )
  195.     {
  196.     return fmt( s, minWidth, 0 );
  197.     }
  198.     public static String fmt( String s, int minWidth, int flags )
  199.     {
  200.     int len = s.length();
  201.     boolean zeroFill = ( ( flags & ZF ) != 0 );
  202.     boolean leftJustify = ( ( flags & LJ ) != 0 );
  203.     boolean hexadecimal = ( ( flags & HX ) != 0 );
  204.     boolean octal = ( ( flags & OC ) != 0 );
  205.     boolean wasNumber = ( ( flags & WN ) != 0 );
  206.     if ( ( hexadecimal || octal || zeroFill ) && ! wasNumber )
  207.         {
  208.         System.err.println( "Acme.Fmt: number flag on a non-number" );
  209.         return "***";
  210.         }
  211.     if ( zeroFill && leftJustify )
  212.         {
  213.         System.err.println( "Acme.Fmt: zero-fill left-justify is silly" );
  214.         return "***";
  215.         }
  216.     if ( hexadecimal && octal )
  217.         {
  218.         System.err.println( "Acme.Fmt: can't do both hex and octal" );
  219.         return "***";
  220.         }
  221.     if ( len >= minWidth )
  222.         return s;
  223.     int fillWidth = minWidth - len;
  224.     StringBuffer fill = new StringBuffer( fillWidth );
  225.     for ( int i = 0; i < fillWidth; ++i )
  226.         if ( zeroFill )
  227.         fill.append( '0' );
  228.         else
  229.         fill.append( ' ' );
  230.     if ( leftJustify )
  231.         return s + fill;
  232.     else if ( zeroFill && s.startsWith( "-" ) )
  233.         return "-" + fill + s.substring( 1 );
  234.     else
  235.         return fill + s;
  236.     }
  237.  
  238.  
  239.     private static String sigFigFix( String s, int sigFigs )
  240.     {
  241.     // First dissect the floating-point number string into sign,
  242.     // integer part, fraction part, and exponent.
  243.     String sign;
  244.     String unsigned;
  245.     if ( s.startsWith( "-" ) || s.startsWith( "+" ) )
  246.         {
  247.         sign = s.substring( 0, 1 );
  248.         unsigned = s.substring( 1 );
  249.         }
  250.     else
  251.         {
  252.         sign = "";
  253.         unsigned = s;
  254.         }
  255.     String mantissa;
  256.     String exponent;
  257.     int eInd = unsigned.indexOf( 'e' );
  258.     if ( eInd == -1 )
  259.         {
  260.         mantissa = unsigned;
  261.         exponent = "";
  262.         }
  263.     else
  264.         {
  265.         mantissa = unsigned.substring( 0, eInd );
  266.         exponent = unsigned.substring( eInd );
  267.         }
  268.     StringBuffer number, fraction;
  269.     int dotInd = mantissa.indexOf( '.' );
  270.     if ( dotInd == -1 )
  271.         {
  272.         number = new StringBuffer( mantissa );
  273.         fraction = new StringBuffer( "" );
  274.         }
  275.     else
  276.         {
  277.         number = new StringBuffer( mantissa.substring( 0, dotInd ) );
  278.         fraction = new StringBuffer( mantissa.substring( dotInd + 1 ) );
  279.         }
  280.  
  281.     int numFigs = number.length();
  282.     int fracFigs = fraction.length();
  283.     if ( ( numFigs == 0 || number.equals( "0" ) ) && fracFigs > 0 )
  284.         {
  285.         // Don't count leading zeros in the fraction.
  286.         numFigs = 0;
  287.         for ( int i = 0; i < fraction.length(); ++i )
  288.         {
  289.         if ( fraction.charAt( i ) != '0' )
  290.             break;
  291.         --fracFigs;
  292.         }
  293.         }
  294.     int mantFigs = numFigs + fracFigs;
  295.     if ( sigFigs > mantFigs )
  296.         {
  297.         // We want more figures; just append zeros to the fraction.
  298.         for ( int i = mantFigs; i < sigFigs; ++i )
  299.         fraction.append( '0' );
  300.         }
  301.     else if ( sigFigs < mantFigs && sigFigs >= numFigs )
  302.         {
  303.         // Want fewer figures in the fraction; chop.
  304.         fraction.setLength(
  305.         fraction.length() - ( fracFigs - ( sigFigs - numFigs ) ) );
  306.         // Round?
  307.         }
  308.     else if ( sigFigs < numFigs )
  309.         {
  310.         // Want fewer figures in the number; turn them to zeros.
  311.         fraction.setLength( 0 );    // should already be zero, but make sure
  312.         for ( int i = sigFigs; i < numFigs; ++i )
  313.         number.setCharAt( i, '0' );
  314.         // Round?
  315.         }
  316.     // Else sigFigs == mantFigs, which is fine.
  317.  
  318.     if ( fraction.length() == 0 )
  319.         return sign + number + exponent;
  320.     else
  321.         return sign + number + "." + fraction + exponent;
  322.     }
  323.  
  324.  
  325.     // Test program.
  326.     public static void main( String[] args )
  327.     {
  328.     System.out.println( "Starting tests." );
  329.     System.out.println( Fmt.fmt( "Hello there." ) );
  330.     System.out.println( "#" + Fmt.fmt( 123 ) + "#" );
  331.     System.out.println( "#" + Fmt.fmt( 123, 10 ) + "#" );
  332.     System.out.println( "#" + Fmt.fmt( 123, 10, Fmt.ZF ) + "#" );
  333.     System.out.println( "#" + Fmt.fmt( 123, 10, Fmt.LJ ) + "#" );
  334.     System.out.println( "#" + Fmt.fmt( -123 ) + "#" );
  335.     System.out.println( "#" + Fmt.fmt( -123, 10 ) + "#" );
  336.     System.out.println( "#" + Fmt.fmt( -123, 10, Fmt.ZF ) + "#" );
  337.     System.out.println( "#" + Fmt.fmt( -123, 10, Fmt.LJ ) + "#" );
  338.     System.out.println( "#" + Fmt.fmt( 123, 0, Fmt.HX ) + "#" );
  339.     System.out.println( "#" + Fmt.fmt( 123, 0, Fmt.OC ) + "#" );
  340.     System.out.println( "#" + Fmt.fmt( 123.456 ) + "#" );
  341.     System.out.println( "#" + Fmt.fmt( 123456000000000000.0 ) + "#" );
  342.     System.out.println( "#" + Fmt.fmt( 123.456, 0, 8 ) + "#" );
  343.     System.out.println( "#" + Fmt.fmt( 123.456, 0, 7 ) + "#" );
  344.     System.out.println( "#" + Fmt.fmt( 123.456, 0, 6 ) + "#" );
  345.     System.out.println( "#" + Fmt.fmt( 123.456, 0, 5 ) + "#" );
  346.     System.out.println( "#" + Fmt.fmt( 123.456, 0, 4 ) + "#" );
  347.     System.out.println( "#" + Fmt.fmt( 123.456, 0, 3 ) + "#" );
  348.     System.out.println( "#" + Fmt.fmt( 123.456, 0, 2 ) + "#" );
  349.     System.out.println( "#" + Fmt.fmt( 123.456, 0, 1 ) + "#" );
  350.     System.out.println( "#" + Fmt.fmt( 123456000000000000.0, 0, 4 ) + "#" );
  351.     System.out.println( "#" + Fmt.fmt( -123.456, 0, 4 ) + "#" );
  352.     System.out.println( "#" + Fmt.fmt( -123456000000000000.0, 0, 4 ) + "#" );
  353.     System.out.println( "#" + Fmt.fmt( 'c' ) + "#" );
  354.     System.out.println( "#" + Fmt.fmt( new java.util.Date() ) + "#" );
  355.     System.out.println( "Done with tests." );
  356.     }
  357.     }
  358.