1 package gnu.kawa.functions;
2 import gnu.kawa.io.CharArrayOutPort;
3 import gnu.kawa.io.OutPort;
4 import gnu.lists.*;
5 import gnu.mapping.*;
6 import gnu.kawa.format.ReportFormat;
7 import java.io.OutputStream;
8 import java.io.Writer;
9 import java.text.MessageFormat;
10 
11 public class Format extends ProcedureN
12 {
13   public static final Format format = new Format();
14   static {
15     format.setName("format");
format.setProperty(Procedure.validateApplyKey, R)16     format.setProperty(Procedure.validateApplyKey,
17                        "gnu.kawa.functions.CompileMisc:validateApplyFormat");
18   }
19 
format(Writer dst, Object[] args, int arg_offset)20   public static void format (Writer dst, Object[] args, int arg_offset)
21   {
22     Object format = args[arg_offset++];
23     Object[] vals = new Object[args.length - arg_offset];
24     System.arraycopy(args, arg_offset, vals, 0, vals.length);
25     formatToWriter(dst, format, vals);
26   }
27 
formatToWriter(Writer dst, Object format, Object... vals)28   public static void formatToWriter (Writer dst, Object format, Object... vals)
29   {
30     if (dst == null)
31       dst = OutPort.outDefault();
32     try
33       {
34         if (format instanceof MessageFormat)
35           {
36             String out = ((MessageFormat) format).format(vals);
37             dst.write(out);
38           }
39         else
40           {
41             if (! (format instanceof ReportFormat))
42               format = ParseFormat.asFormat(format, '~');
43 	    ((ReportFormat) format).format(vals, 0, dst, null);
44 	  }
45       }
46     catch (java.io.IOException ex)
47       {
48         throw new RuntimeException("Error in format: "+ ex);
49       }
50   }
51 
formatToOutputStream(OutputStream dst, Object format, Object... vals)52   public static void formatToOutputStream (OutputStream dst, Object format, Object... vals)
53   {
54     OutPort port = new OutPort(dst);
55     format(port, format, vals);
56     port.closeThis();
57   }
58 
formatToString(int arg_offset, Object... args)59   public static String formatToString (int arg_offset, Object... args)
60   {
61     CharArrayOutPort port = new CharArrayOutPort();
62     format(port, args, arg_offset);
63     String str = port.toString();
64     port.close ();
65     return str;
66   }
67 
sprintfToString(Object fmt, Object... args)68     public static String sprintfToString(Object fmt, Object... args) {
69         ReportFormat rfmt = ParseFormat.asFormat(fmt, '%');
70         CharArrayOutPort port = new CharArrayOutPort();
71         try {
72             rfmt.format(args, 0, port, null);
73         } catch (java.io.IOException ex) {
74             WrappedException.rethrow(ex);
75         }
76         String str = port.toString();
77         port.close();
78         return str;
79     }
80 
81   /**
82    * Apply format and argument, yielding an FString.
83    * @param style either '%' (C/Emacs-style format specifiers), or
84    *   '~' (Common Lisp-style format specifiers).
85    * @param fmt the format string or specification
86    * @param args the arguments to be formatted
87    */
formatToFString(char style, Object fmt, Object[] args)88   public static FString formatToFString (char style, Object fmt, Object[] args)
89   {
90     ReportFormat rfmt = ParseFormat.asFormat(fmt, style);
91     CharArrayOutPort port = new CharArrayOutPort();
92     try
93       {
94 	rfmt.format(args, 0, port, null);
95       }
96     catch (java.io.IOException ex)
97       {
98         WrappedException.rethrow(ex);
99       }
100     char[] chars = port.toCharArray();
101     port.close ();
102     return new FString(chars);
103   }
104 
applyN(Object[] args)105   public Object applyN (Object[] args)
106   {
107     /* #ifdef JAVA5 */
108     return format(args);
109     /* #else */
110     // return format$V(args);
111     /* #endif */
112   }
113 
114   /* #ifdef JAVA5 */
format(Object... args)115   public static Object format (Object... args)
116   /* #else */
117   // public static Object format$V (Object[] args)
118   /* #endif */
119   {
120     Object port_arg = args[0];
121     if (port_arg == Boolean.TRUE)
122       {
123 	format(OutPort.outDefault(), args, 1);
124 	return Values.empty;
125       }
126     else if (port_arg == Boolean.FALSE)
127       {
128 	return formatToString(1, args);
129       }
130     else if (port_arg instanceof MessageFormat
131              /* #ifdef use:java.lang.CharSequence */
132              || port_arg instanceof CharSequence
133              /* #else */
134              // || port_arg instanceof String || port_arg instanceof CharSeq
135              /* #endif */
136 	     || port_arg instanceof ReportFormat)
137       {
138 	return formatToString(0, args);
139       }
140     else if (port_arg instanceof Writer)
141       {
142 	format((Writer) port_arg, args, 1);
143 	return Values.empty;
144       }
145     else if (port_arg instanceof OutputStream)
146       {
147         formatToOutputStream((OutputStream) port_arg,
148                              args[1], drop2(args));
149 	return Values.empty;
150       }
151     else
152       throw new RuntimeException("bad first argument to format");
153   }
154 
drop2(Object[] vals)155   static Object[] drop2 (Object[] vals)
156   {
157     int xlen = vals.length - 2;
158     Object[] xvals = new Object[xlen];
159     System.arraycopy(vals, 2, xvals, 0, xlen);
160     return xvals;
161   }
162 }
163