001: package sisc.util;
002:
003: import java.util.*;
004: import java.security.AccessControlException;
005: import java.text.*;
006: import java.net.*;
007:
008: import sisc.compiler.*;
009: import sisc.data.*;
010: import sisc.env.SymbolicEnvironment;
011: import sisc.exprs.*;
012: import sisc.io.*;
013: import sisc.interpreter.*;
014: import sisc.nativefun.NativeLibrary;
015: import java.io.IOException;
016: import java.io.EOFException;
017: import java.io.InputStream;
018: import java.io.OutputStream;
019: import java.io.PushbackReader;
020: import java.io.Reader;
021: import java.io.StringReader;
022: import java.io.UnsupportedEncodingException;
023: import java.io.Writer;
024: import java.lang.reflect.Constructor;
025: import sisc.reader.Lexer;
026: import sisc.reader.Parser;
027:
028: public abstract class Util implements Version {
029:
030: static String safeGetProperty(String key, String def) {
031: try {
032: return System.getProperty(key, def);
033: } catch (AccessControlException ex) {
034: return def;
035: }
036: }
037:
038: public static final boolean caseSensitive = safeGetProperty(
039: "sisc.caseSensitive",
040: new Boolean(Defaults.CASE_SENSITIVE).toString()).equals(
041: "true");
042: public static final boolean permitInterrupts = safeGetProperty(
043: "sisc.permitInterrupts",
044: new Boolean(Defaults.PERMIT_INTERRUPTS).toString()).equals(
045: "true");
046: public static final int minFloatPrecision = Integer
047: .parseInt(safeGetProperty("sisc.minFloatPrecision", Integer
048: .toString(Defaults.MIN_FLOAT_PRECISION)));
049: public static final int maxFloatPrecision = Integer
050: .parseInt(safeGetProperty("sisc.maxFloatPrecision", Integer
051: .toString(Defaults.MAX_FLOAT_PRECISION)));
052:
053: public static final Value[] ZV = new Value[0];
054: public static final Quantity FIVE = Quantity.valueOf(5);
055:
056: public static EOFObject EOF = EOFObject.EOF;
057: public static Syntax QUOTE = new Syntax(
058: sisc.compiler.Compiler.QUOTE);
059: public static EmptyList EMPTYLIST = EmptyList.EMPTYLIST;
060: public static SchemeVoid VOID = SchemeVoid.VOID;
061: public static SchemeBoolean TRUE = SchemeBoolean.TRUE,
062: FALSE = SchemeBoolean.FALSE;
063: public static SchemeVector EMPTYVEC = new SchemeVector(
064: new Value[] {});
065:
066: public static Symbol BEGIN = Symbol.get("begin"), ERRORK = Symbol
067: .get("error-continuation"), EXPSC = Symbol
068: .get("*sc-expander*"), EXPTOP = Symbol.get("*top*"),
069: FCONT = Symbol.get("failure-continuation"),
070: JEXCEPTION = Symbol.get("java-exception"), LAMBDA = Symbol
071: .get("lambda"), LOCATION = Symbol.get("location"),
072: MESSAGE = Symbol.get("message"), NAME = Symbol.get("name"),
073: OTHER = Symbol.get("other"), PARENT = Symbol.get("parent"),
074: QUOTESYM = Symbol.get("quote"), REPORT = Symbol
075: .get("*report*"), SETBANG = Symbol.get("set!"),
076: SISC = Symbol.get("*sisc*"), SISC_SPECIFIC = Symbol
077: .get("*sisc-specific*"), SYMENV = Symbol
078: .get("*symenv*"), THIS = Symbol.get("this"),
079: TOPLEVEL = Symbol.get("*toplevel*"), BACKQUOTE = Symbol
080: .get("quasiquote"),
081: UNQUOTE = Symbol.get("unquote"), UNQUOTE_SPLICING = Symbol
082: .get("unquote-splicing"), SOURCE_LINE = Symbol
083: .get("line-number"), SOURCE_COLUMN = Symbol
084: .get("column-number"), SOURCE_FILE = Symbol
085: .get("source-file"), EVAL = Symbol.get("eval");
086:
087: public static String warn(String messageClass) {
088: StringBuffer b = new StringBuffer("{");
089: b.append(liMessage(SISCB, "warning"));
090: b.append(": ");
091: b.append(liMessage(SISCB, messageClass));
092: b.append(')');
093: return b.toString();
094: }
095:
096: public static String warn(String messageClass, String sourceFile,
097: int lineNumber, int columnNumber) {
098: StringBuffer b = new StringBuffer("{");
099: b.append(liMessage(SISCB, "warning"));
100: b.append(": ");
101: b.append(liMessage(SISCB, messageClass));
102: b.append("\n ");
103: b.append(sourceFile).append(':').append(lineNumber);
104: b.append(':').append(columnNumber).append(": }");
105: return b.toString();
106: }
107:
108: public static String warn(String messageClass, String arg) {
109: StringBuffer b = new StringBuffer("{");
110: b.append(liMessage(SISCB, "warning"));
111: b.append(": ");
112: b.append(liMessage(SISCB, messageClass, arg));
113: b.append(')');
114: return b.toString();
115: }
116:
117: static Class JOBJ = null;
118: static Class[] OBJARRY = new Class[] { Object.class };
119: static Constructor JOBJCONST = null;
120: static {
121: try {
122: JOBJ = Class.forName("sisc.modules.s2j.JavaObject");
123: JOBJCONST = JOBJ.getConstructor(OBJARRY);
124: } catch (Exception cnf) {
125: }
126: }
127:
128: public static Value javaWrap(Object o) {
129: if (JOBJ != null)
130: try {
131: return (Value) JOBJCONST
132: .newInstance(new Object[] { o });
133: } catch (Exception ie) {
134: }
135: return FALSE;
136: }
137:
138: public static void error(Interpreter r, Value where,
139: String errormessage, Pair moreData)
140: throws ContinuationException {
141: error(r, append(moreData, list(new Pair(MESSAGE,
142: new SchemeString(errormessage)), new Pair(LOCATION,
143: where))));
144: }
145:
146: public static void error(Interpreter r, Value where,
147: String errormessage, Exception e)
148: throws ContinuationException {
149: error(r, list(
150: new Pair(MESSAGE, new SchemeString(errormessage)),
151: new Pair(LOCATION, where), new Pair(JEXCEPTION,
152: javaWrap(e))));
153: }
154:
155: public static void error(Interpreter r, Value where,
156: String errormessage) throws ContinuationException {
157: error(r, list(
158: new Pair(MESSAGE, new SchemeString(errormessage)),
159: new Pair(LOCATION, where)));
160: }
161:
162: public static void error(Interpreter r, String errormessage,
163: Pair moreData) throws ContinuationException {
164: error(r, new Pair(new Pair(MESSAGE, new SchemeString(
165: errormessage)), moreData));
166: }
167:
168: public static void error(Interpreter r, String errormessage)
169: throws ContinuationException {
170: error(r,
171: list(new Pair(MESSAGE, new SchemeString(errormessage))));
172: }
173:
174: public static void error(Interpreter r, Value errormessage)
175: throws ContinuationException {
176: error(r, list(new Pair(MESSAGE, errormessage)));
177: }
178:
179: public static String simpleErrorToString(Pair p) {
180: StringBuffer b = new StringBuffer();
181: String location = null;
182: String message = null;
183: Pair parent = null;
184: while (p != EMPTYLIST && (location == null || message == null)) {
185: Pair cp = (Pair) p.car();
186: if (cp.car().equals(MESSAGE))
187: message = cp.cdr().toString();
188: else if (cp.car().equals(LOCATION))
189: location = cp.cdr().toString();
190: else if (cp.car().equals(PARENT))
191: parent = (Pair) cp.cdr();
192: p = (Pair) p.cdr();
193: }
194: if (location == null)
195: b.append(liMessage(SISCB, "error"));
196: else
197: b.append(liMessage(SISCB, "errorinwhere", location));
198: if (message != null)
199: b.append(": ").append(message);
200: else
201: b.append('.');
202: if (parent != null)
203: b.append("\n ").append(simpleErrorToString(parent));
204: return b.toString();
205: }
206:
207: public static ClassLoader currentClassLoader() {
208: ClassLoader cl = null;
209: try {
210: cl = Thread.currentThread().getContextClassLoader();
211: } catch (java.security.AccessControlException e) {
212: }
213: if (cl == null) {
214: try {
215: cl = Util.class.getClassLoader();
216: } catch (java.security.AccessControlException e) {
217: }
218: }
219: if (cl == null) {
220: try {
221: cl = ClassLoader.getSystemClassLoader();
222: } catch (java.security.AccessControlException e) {
223: }
224: }
225: if (cl == null) {
226: throw new RuntimeException(liMessage(SISCB,
227: "notclassloader"));
228: }
229: return cl;
230: }
231:
232: public static Value read(String expr) throws IOException {
233: PushbackReader ip = new PushbackReader(new StringReader(expr));
234: Parser p = new Parser(new Lexer());
235: Value res = p.nextExpression(ip);
236: try {
237: Value v = p.nextExpression(ip);
238: } catch (EOFException eof) {
239: return res;
240: }
241: throw new IOException(liMessage(SISCB, "stringreaderror", expr));
242: }
243:
244: public static void error(Interpreter r, Pair error)
245: throws ContinuationException {
246: r.error(error);
247: }
248:
249: public static String justify(String v, int p, char c) {
250: StringBuffer b = new StringBuffer();
251: while (b.length() < (p - v.length())) {
252: b.append(c);
253: }
254: return b.append(v).toString();
255: }
256:
257: public static final void argCheck(Pair argl, int arity)
258: throws Exception {
259: int x = length(argl);
260: if (x != arity && arity != -1) {
261: throw new RuntimeException(liMessage(SISCB,
262: "notenoughargs", new Object[] { new Integer(arity),
263: new Integer(x) }));
264: }
265: }
266:
267: public static void updateName(Value v, Symbol s) {
268: if (v instanceof NamedValue) {
269: NamedValue nv = (NamedValue) v;
270: if (nv.getName() == null) {
271: nv.setName(s);
272: }
273: }
274: }
275:
276: public static int length(Pair p) {
277: Pair s = p;
278: try {
279: int i = 0;
280: for (; p != EMPTYLIST; i++) {
281: p = (Pair) p.cdr();
282: }
283: return i;
284: } catch (ClassCastException ce) {
285: throw new RuntimeException(liMessage(SISCB,
286: "notaproperlist", s.synopsis()));
287: }
288: }
289:
290: /**
291: * @param p the head of a list
292: * @return a Vector containing the same elements as the list
293: *
294: * @deprecated Obsoleted by pairToExpressions and pairToValues.
295: */
296: public static Vector pairToExpVect(Pair p) {
297: Vector v = new Vector();
298: for (; p != EMPTYLIST; p = (Pair) p.cdr()) {
299: v.addElement(p.car());
300: }
301:
302: return v;
303: }
304:
305: public static Expression[] pairToExpressions(Pair p) {
306: int len = length(p);
307: Expression[] es = new Expression[len];
308:
309: for (int i = 0; i < len; ++i) {
310: es[i] = p.car();
311: p = (Pair) p.cdr();
312: }
313:
314: return es;
315: }
316:
317: public static Value[] pairToValues(Pair p) {
318: int len = length(p);
319: if (len == 0)
320: return ZV;
321:
322: Value[] vs = new Value[len];
323: for (int i = 0; i < len; ++i) {
324: vs[i] = p.car();
325: p = (Pair) p.cdr();
326: }
327:
328: return vs;
329: }
330:
331: public static Symbol[] argsToSymbols(Pair p) {
332: if (p == EMPTYLIST) {
333: return new Symbol[0];
334: }
335:
336: // Count the proper elements ignoring the tail:
337: int l = 1;
338: Value q = p.cdr();
339: while ((q instanceof Pair) && (q != EMPTYLIST)) {
340: ++l;
341: q = ((Pair) q).cdr();
342: }
343:
344: // Allocate result array:
345: Symbol[] result;
346:
347: if (q == EMPTYLIST) {
348: result = new Symbol[l];
349: } else {
350: // improper list: the tail is expected to contain a symbol
351: result = new Symbol[l + 1];
352: result[l] = (Symbol) q;
353: }
354:
355: // Copy the proper elements into the result
356: int i = 0;
357: for (;;) {
358: result[i++] = (Symbol) p.car();
359:
360: if (i == l) {
361: // An update of p as done below would throw a
362: // ClassCastException for improper lists.
363: break;
364: }
365:
366: p = (Pair) p.cdr();
367: }
368:
369: return result;
370: }
371:
372: /* Casting checks */
373: public static void typeError(String type, Value o) {
374: typeError(SISCB, type, o);
375: }
376:
377: public static void typeError(Symbol bundleName, String type, Value o) {
378: if (o instanceof Values)
379: throw new RuntimeException(liMessage(SISCB,
380: "multiplevalues"));
381: throw new RuntimeException(liMessage(SISCB, "unexpectedarg",
382: liMessage(bundleName, type), o.synopsis()));
383: }
384:
385: // Synonym for Symbol.get(s) (i.e. a lowercased sym)
386: public static final Symbol sym(String s) {
387: return Symbol.get(s);
388: }
389:
390: public static final String symval(Value o) {
391: if (o instanceof Symbol) {
392: return ((Symbol) o).symval;
393: } else {
394: typeError("symbol", o);
395: return null;
396: }
397: }
398:
399: public static final Quantity num(Value o) {
400: if (o instanceof Quantity) {
401: return (Quantity) o;
402: } else {
403: typeError("number", o);
404: return null;
405: }
406: }
407:
408: public static final Pair pair(Value o) {
409: if (o instanceof Pair) {
410: return (Pair) o;
411: } else {
412: typeError("pair", o);
413: return null;
414: }
415: }
416:
417: public static final Procedure proc(Value o) {
418: if (o instanceof Procedure) {
419: return (Procedure) o;
420: } else {
421: typeError("procedure", o);
422: return null;
423: }
424: }
425:
426: public static final Pair truePair(Value o) {
427: if (o == EMPTYLIST)
428: typeError("pair", o);
429: return pair(o);
430: }
431:
432: public static final char character(Value c) {
433: return chr(c).c;
434: }
435:
436: public static final SchemeCharacter chr(Value o) {
437: if (o instanceof SchemeCharacter) {
438: return (SchemeCharacter) o;
439: } else {
440: typeError("character", o);
441: return null;
442: }
443: }
444:
445: public static final String string(Value o) {
446: return str(o).asString();
447: }
448:
449: public static final SchemeString str(Value o) {
450: if (o instanceof SchemeString) {
451: return (SchemeString) o;
452: } else {
453: typeError("string", o);
454: return null;
455: }
456: }
457:
458: public static final Symbol symbol(Value o) {
459: if (o instanceof Symbol) {
460: return (Symbol) o;
461: } else {
462: typeError("symbol", o);
463: return null;
464: }
465: }
466:
467: public static final SchemeVector vec(Value o) {
468: if (o instanceof SchemeVector) {
469: return (SchemeVector) o;
470: } else {
471: typeError("vector", o);
472: return null;
473: }
474: }
475:
476: /* IO Type casts */
477:
478: public static final OutputPort outport(Value o) {
479: if (o instanceof OutputPort) {
480: return (OutputPort) o;
481: } else {
482: typeError("output-port", o);
483: return null;
484: }
485: }
486:
487: public static final SchemeBinaryOutputPort binoutport(Value o) {
488: if (o instanceof SchemeBinaryOutputPort) {
489: return (SchemeBinaryOutputPort) o;
490: } else {
491: typeError("binary-output-port", o);
492: return null;
493: }
494: }
495:
496: public static final OutputStream binoutstream(Value o) {
497: return binoutport(o).getOutputStream();
498: }
499:
500: public static final SchemeCharacterOutputPort charoutport(Value o) {
501: if (o instanceof SchemeCharacterOutputPort) {
502: return (SchemeCharacterOutputPort) o;
503: } else {
504: typeError("character-output-port", o);
505: return null;
506: }
507: }
508:
509: public static final Writer charoutwriter(Value o) {
510: return charoutport(o).getWriter();
511: }
512:
513: public static final InputPort inport(Value o) {
514: if (o instanceof InputPort) {
515: return (InputPort) o;
516: } else {
517: typeError("input-port", o);
518: return null;
519: }
520: }
521:
522: public static final SchemeBinaryInputPort bininport(Value o) {
523: if (o instanceof SchemeBinaryInputPort) {
524: return (SchemeBinaryInputPort) o;
525: } else {
526: typeError("binary-input-port", o);
527: return null;
528: }
529: }
530:
531: public static final InputStream bininstream(Value o) {
532: return bininport(o).getInputStream();
533: }
534:
535: public static final SchemeCharacterInputPort charinport(Value o) {
536: if (o instanceof SchemeCharacterInputPort) {
537: return (SchemeCharacterInputPort) o;
538: } else {
539: typeError("character-input-port", o);
540: return null;
541: }
542: }
543:
544: public static final Reader charinreader(Value o) {
545: return charinport(o).getReader();
546: }
547:
548: public static final SymbolicEnvironment env(Value o) {
549: if (o instanceof SymbolicEnvironment) {
550: return (sisc.env.SymbolicEnvironment) o;
551: } else {
552: typeError("environment", o);
553: return null;
554: }
555: }
556:
557: public static final Box box(Value o) {
558: if (o instanceof Box) {
559: return (Box) o;
560: } else {
561: typeError("box", o);
562: return null;
563: }
564: }
565:
566: public static final CallFrame cont(Value o) {
567: if (o instanceof CallFrame) {
568: return (CallFrame) o;
569: } else {
570: typeError("continuation", o);
571: return null;
572: }
573: }
574:
575: public static final Expression expr(Value o) {
576: if (o instanceof ExpressionValue) {
577: return ((ExpressionValue) o).e;
578: } else {
579: typeError("expression", o);
580: return null;
581: }
582: }
583:
584: public static final AnnotatedExpr annotated(Value o) {
585: if (o instanceof AnnotatedExpr) {
586: return (AnnotatedExpr) o;
587: } else {
588: typeError("annotatedexpression", o);
589: return null;
590: }
591: }
592:
593: public static URL makeURL(String url) {
594: URL res = null;
595: if (url == null)
596: return res;
597: try {
598: res = new URL(url);
599: } catch (MalformedURLException e) {
600: try {
601: res = new URL("file", null, url);
602: } catch (MalformedURLException ee) {
603: }
604: }
605: return res;
606: }
607:
608: public static URL url(Value v) {
609: try {
610: return url(string(v));
611: } catch (MalformedURLException e) {
612: typeError("url", v);
613: }
614: return null;
615: }
616:
617: public static URL url(String s) throws MalformedURLException {
618: try {
619: return new URL(s);
620: } catch (MalformedURLException e) {
621: return new URL("file", null, s);
622: }
623: }
624:
625: public static URL url(Value current, Value v) {
626: URL c = url(current);
627: String s = string(v);
628: try {
629: return new URL(c, s);
630: } catch (MalformedURLException e) {
631: try {
632: return new URL(c, "file:" + s);
633: } catch (MalformedURLException ee) {
634: typeError("url", v);
635: }
636: return null;
637: }
638: }
639:
640: public static final NativeLibrary nlib(Value o) {
641: if (o instanceof NativeLibrary) {
642: return (NativeLibrary) o;
643: } else {
644: typeError("nativelibrary", o);
645: return null;
646: }
647: }
648:
649: public static final ImmutablePair immutablePair(Value o) {
650: if (o instanceof ImmutablePair) {
651: return (ImmutablePair) o;
652: } else {
653: typeError("immutable-pair", o);
654: return null;
655: }
656: }
657:
658: public static final ImmutableVector immutableVector(Value o) {
659: if (o instanceof ImmutableVector) {
660: return (ImmutableVector) o;
661: } else {
662: typeError("immutable-vector", o);
663: return null;
664: }
665: }
666:
667: public static final SchemeBoolean truth(boolean b) {
668: return b ? TRUE : FALSE;
669: }
670:
671: public static final boolean truth(Value v) {
672: return v != FALSE;
673: }
674:
675: /* List functions */
676: public static Value assq(Value v, Pair p) {
677: while (p != EMPTYLIST) {
678: Pair assc = pair(p.car());
679: if (assc.car() == v) {
680: return assc;
681: }
682: p = pair(p.cdr());
683: }
684: return FALSE;
685: }
686:
687: public static Pair mapcar(Pair list) {
688: Pair c = EMPTYLIST;
689: while (list != EMPTYLIST) {
690: c = new Pair(truePair(list.car()).car(), c);
691: list = pair(list.cdr());
692: }
693: return reverseInPlace(c);
694: }
695:
696: public static Pair reverse(Pair p) {
697: Pair n = EMPTYLIST;
698: while (p != EMPTYLIST) {
699: n = new Pair(p.car(), n);
700: p = (Pair) p.cdr();
701: }
702: return n;
703: }
704:
705: public static Pair reverseInPlace(Pair s) {
706: if (s == EMPTYLIST) {
707: return EMPTYLIST;
708: }
709: Pair r = EMPTYLIST;
710: Value d;
711: for (;;) {
712: d = s.cdr();
713: s.setCdr(r);
714: r = s;
715: if (d == EMPTYLIST) {
716: break;
717: }
718: s = (Pair) d;
719: }
720: return r;
721: }
722:
723: public static Pair append(Pair p1, Pair p2) {
724: if (p1 == EMPTYLIST)
725: return p2;
726: return new Pair(p1.car(), append((Pair) p1.cdr(), p2));
727: }
728:
729: public static final Pair list(Value o1) {
730: return new Pair(o1, EMPTYLIST);
731: }
732:
733: public static final Pair list(Value o1, Value o2) {
734: return new Pair(o1, list(o2));
735: }
736:
737: public static final Pair list(Value o1, Value o2, Value o3) {
738: return new Pair(o1, list(o2, o3));
739: }
740:
741: public static final Pair list(Value o1, Value o2, Value o3, Value o4) {
742: return new Pair(o1, list(o2, o3, o4));
743: }
744:
745: public static final Pair list(Value o1, Value o2, Value o3,
746: Value o4, Value o5) {
747: return new Pair(o1, list(o2, o3, o4, o5));
748: }
749:
750: public static final Pair valArrayToList(Value[] r, int offset,
751: int len) {
752: Pair p = EMPTYLIST;
753: for (int i = (offset + len) - 1; i >= offset; i--) {
754: p = new Pair(r[i], p);
755: }
756: return p;
757: }
758:
759: public static final Pair valArrayToList(Value[] r) {
760: return (r == null ? EMPTYLIST : valArrayToList(r, 0, r.length));
761: }
762:
763: public static final SchemeVector valArrayToVec(Value[] r) {
764: if (r == null)
765: return EMPTYVEC;
766: //replace nulls with VOID - this mutation is always safe
767: for (int i = 0; i < r.length; i++) {
768: if (r[i] == null)
769: r[i] = VOID;
770: }
771: return new SchemeVector(r);
772: }
773:
774: public static Value memq(Value v, Pair p) {
775: while (p != EMPTYLIST) {
776: if (p.car() == v) {
777: return p;
778: }
779: p = pair(p.cdr());
780: }
781: return FALSE;
782: }
783:
784: /* Localization and Internationalization */
785: public static Symbol SISCB = Symbol.intern("sisc.Messages");
786: public static WeakHashMap bundles = new WeakHashMap();
787: static Locale myLocale = Locale.getDefault();
788: static MessageFormat formatter = new MessageFormat("");
789:
790: static {
791: formatter.setLocale(myLocale);
792: }
793:
794: public static void registerBundle(Symbol bundleName)
795: throws MissingResourceException {
796: ResourceBundle b = ResourceBundle.getBundle(bundleName.symval);
797: bundles.put(bundleName, b);
798: }
799:
800: public static String liMessage(Symbol bundleName, String messageName) {
801: ResourceBundle bundle = (ResourceBundle) bundles
802: .get(bundleName);
803: try {
804: if (bundle == null) {
805: registerBundle(bundleName);
806: bundle = (ResourceBundle) bundles.get(bundleName);
807: }
808: return bundle.getString(messageName);
809: } catch (MissingResourceException mr) {
810: if (!bundleName.equals(SISCB))
811: return liMessage(SISCB, messageName);
812: else
813: return "<localized message not found: " + messageName
814: + ">";
815: }
816: }
817:
818: public static String liMessage(Symbol bundle, String messageName,
819: String arg1) {
820: return MessageFormat.format(liMessage(bundle, messageName),
821: new Object[] { arg1 });
822: }
823:
824: public static String liMessage(Symbol bundle, String messageName,
825: String arg1, String arg2) {
826: return MessageFormat.format(liMessage(bundle, messageName),
827: new Object[] { arg1, arg2 });
828: }
829:
830: public static String liMessage(Symbol bundle, String messageName,
831: String arg1, String arg2, String arg3) {
832: return MessageFormat.format(liMessage(bundle, messageName),
833: new Object[] { arg1, arg2, arg3 });
834: }
835:
836: public static String liMessage(Symbol bundle, String messageName,
837: String arg1, String arg2, String arg3, String arg4) {
838: return MessageFormat.format(liMessage(bundle, messageName),
839: new Object[] { arg1, arg2, arg3, arg4 });
840: }
841:
842: public static String liMessage(Symbol bundle, String messageName,
843: String arg1, int arg2, int arg3) {
844: return MessageFormat.format(liMessage(bundle, messageName),
845: new Object[] { arg1, new Integer(arg2),
846: new Integer(arg3) });
847: }
848:
849: public static String liMessage(Symbol bundle, String messageName,
850: Object[] args) {
851: return MessageFormat.format(liMessage(bundle, messageName),
852: args);
853: }
854:
855: protected static String javaExceptionToString(Exception e) {
856: return "<" + e.getClass().getName() + ">: " + e.getMessage();
857: }
858:
859: public static Pair sourceAnnotations(String file, int line,
860: int column, Pair anns) {
861: return new Pair(new Pair(SOURCE_FILE, new SchemeString(file)),
862: new Pair(new Pair(SOURCE_LINE, Quantity.valueOf(line)),
863: new Pair(new Pair(SOURCE_COLUMN, Quantity
864: .valueOf(column)), anns)));
865: }
866:
867: public static Expression annotatedAppEval(Class clazz, String fn) {
868: Expression e = new AppEval();
869: e.setAnnotation(SOURCE_FILE, new SchemeString(clazz.getName()
870: + "/" + fn));
871: return e;
872: }
873:
874: private static Charset defaultCharset = null;
875:
876: static {
877: try {
878: defaultCharset = Charset.forName("UTF-8");
879: } catch (UnsupportedEncodingException e) {
880: // I think this is a "can't happen" error,
881: // since Java natively supports UTF-8
882: throw new ExceptionInInitializerError(e);
883: } catch (java.nio.charset.UnsupportedCharsetException e) {
884: // this one, too
885: throw new ExceptionInInitializerError(e);
886: }
887: }
888:
889: /**
890: * Return the default character set, which is UTF-8, but could in
891: * principle change.
892: *
893: * @return a static Charset object
894: */
895: public static Charset getDefaultCharacterSet() {
896: return defaultCharset;
897: }
898:
899: /**
900: * Converts a character set name to a Charset. If the input name
901: * is null, then return the default Charset. If the input name
902: * does not correspond to a legal or supported
903: * character set, then return the default Charset and give a warning.
904: *
905: * @param charsetName the name of a putative character set, or null
906: * @return the Charset corresponding to the argument, or the
907: * default character set (see {@link #getDefaultCharacterSet}) if
908: * that is not possible
909: */
910: public static Charset charsetFromString(String charsetName) {
911: Charset c;
912: if (charsetName == null) {
913: c = getDefaultCharacterSet();
914: } else {
915: try {
916: c = Charset.forName(charsetName);
917: } catch (Exception e) {
918: // This is either IllegalCharsetNameException or
919: // UnsupportedCharsetException -- handle both in the same way
920: System.err.println(Util.warn("unsupencoding",
921: charsetName));
922: c = getDefaultCharacterSet();
923: }
924: }
925: //assert c != null;
926: return c;
927: }
928:
929: }
930:
931: /*
932: * The contents of this file are subject to the Mozilla Public
933: * License Version 1.1 (the "License"); you may not use this file
934: * except in compliance with the License. You may obtain a copy of
935: * the License at http://www.mozilla.org/MPL/
936: *
937: * Software distributed under the License is distributed on an "AS
938: * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
939: * implied. See the License for the specific language governing
940: * rights and limitations under the License.
941: *
942: * The Original Code is the Second Interpreter of Scheme Code (SISC).
943: *
944: * The Initial Developer of the Original Code is Scott G. Miller.
945: * Portions created by Scott G. Miller are Copyright (C) 2000-2007
946: * Scott G. Miller. All Rights Reserved.
947: *
948: * Contributor(s):
949: * Matthias Radestock
950: *
951: * Alternatively, the contents of this file may be used under the
952: * terms of the GNU General Public License Version 2 or later (the
953: * "GPL"), in which case the provisions of the GPL are applicable
954: * instead of those above. If you wish to allow use of your
955: * version of this file only under the terms of the GPL and not to
956: * allow others to use your version of this file under the MPL,
957: * indicate your decision by deleting the provisions above and
958: * replace them with the notice and other provisions required by
959: * the GPL. If you do not delete the provisions above, a recipient
960: * may use your version of this file under either the MPL or the
961: * GPL.
962: */
|