unoidl2

Unnamed repository; edit this file to name it for gitweb.
git clone https://logand.com/git/unoidl2.git/
Log | Files | Refs

unoidl2java.c (25082B)


      1 /* unoidl2java -- convert uno idl input to java */
      2 /*
      3    This file is part of unoidl2.
      4 
      5    unoidl2 is free software: you can redistribute it and/or modify
      6    it under the terms of the GNU General Public License as published by
      7    the Free Software Foundation, either version 3 of the License, or
      8    (at your option) any later version.
      9 
     10    unoidl2 is distributed in the hope that it will be useful,
     11    but WITHOUT ANY WARRANTY; without even the implied warranty of
     12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13    GNU General Public License for more details.
     14 
     15    You should have received a copy of the GNU General Public License
     16    along with unoidl2.  If not, see <http://www.gnu.org/licenses/>.
     17 */
     18 
     19 #include "unoidl2.h"
     20 #include "parse.c.h"
     21 
     22 #include <stdio.h>
     23 
     24 extern int yyparse();
     25 
     26 extern const Any NIL;
     27 extern const Any T;
     28 extern const Any ast;
     29 extern const Any root2;
     30 
     31 static Any com_sun_star_uno_XInterface;
     32 static Any com_sun_star_uno_Exception;
     33 static Any com_sun_star_uno_RuntimeException;
     34 
     35 static int template = 0;
     36 static int use_XInterface = 0;
     37 static int seq0 = 0;
     38 
     39 static void pr(char *x) {printf("%s", x);}
     40 static void pl(char *x) {printf("%s\n", x);}
     41 static void pi(int x)   {printf("%d", x);}
     42 
     43 static Any pp(Any x);
     44 
     45 static void pp_list(Any x, char *sep, Fn1 fn) {
     46   for(int i = 0; NIL != x; x = cdr(x), i++) {
     47     if(sep && 0 < i) pr(sep);
     48     fn(car(x));
     49   }
     50 }
     51 
     52 static Any last(Any x) {
     53   if(consp(x)) {
     54     for(; NIL != x; x = cdr(x))
     55       if(NIL == cdr(x)) return car(x);
     56     return NIL;
     57   } else return x;
     58 }
     59 
     60 static void pr_package(Any x) {
     61   Any name = cadr(x);
     62   Any p = sym2p(name);
     63   pr("///--- "); print_sym2_custom(p, "/"); pr(" "); pp(sym2k(name)); pl(".java"); // TODO only toplevel
     64   pl("// Generated by unoidl2java, do not edit!");
     65   pr("// "); print(car(x)); pr(" "); print(name); pl("");
     66   pr("package "); pp(p); pl(";");
     67   /* for(p = sym2p(p); NIL != sym2k(p); p = sym2p(p)) { */
     68   /*   pr("import "); pp(p); pl(".*;"); */
     69   /* } */
     70 }
     71 
     72 static void pr_enum(Any x) { // (enum Name T ONE TWO (THREE 3))
     73   Any name = cadr(x);
     74   Any published = caddr(x);
     75   if(1 || NIL != published) {
     76     Any values = cdddr(x);
     77     Any v0 = car(values);
     78     Any v0k = consp(v0) ? car(v0) : v0;
     79     pr_package(x);
     80     Any k = sym2k(name);
     81     pr("public final class "); pp(k); pl(" extends com.sun.star.uno.Enum {");
     82     pr("   private "); pp(k); pl("(int value) {");
     83     pl("      super(value);");
     84     pl("   }");
     85     pr("   public static "); pp(k); pl(" getDefault() {");
     86     pr("      return "); pp(v0k); pl(";");
     87     pl("   }");
     88     int n = 0;
     89     int explicit = 0;
     90     for(Any y = values; NIL != y; y = cdr(y)) {
     91       Any value = car(y);
     92       int explicit1 = consp(value);
     93       explicit |= explicit1;
     94       Any k2 = sym1(explicit1 ? car(value) : value);
     95       Any v = explicit1 ? cadr(value) : mkinum(n++);
     96       pr("   public static final "); pp(k); pr(" "); pp(k2); pr(" = new ");
     97       pp(k); pr("("); pp(v); pl(");");
     98       pr("   public static final int "); pp(k2); pr("_value = ");
     99       if(!explicit || explicit1) pp(v); // syntax error if not
    100       //else {pr("@@@"); print(v);}
    101       pl(";");
    102     }
    103     pr("   public static "); pp(k); pl(" fromInt(int value) {");
    104     pl("      switch(value) {");
    105     pl("         default: return null;");
    106     n = 0;
    107     for(Any y = values; NIL != y; y = cdr(y)) {
    108       Any value = car(y);
    109       Any k = sym1(consp(value) ? car(value) : value);
    110       Any v = consp(value) ? cadr(value) : mkinum(n++);
    111       pr("         case "); pp(v); pr(": return "); pp(k); pl(";");
    112     }
    113     pl("      }");
    114     //pr("      return "); pp(v0k); pl(";");
    115     pl("   }");
    116     pl("}");}
    117 }
    118 
    119 static void pr_args(Any x) {
    120   for(int i = 0; NIL != x; x = cdr(x), i++) {
    121     Any a = car(x);
    122     if(0 < i) pr(", ");
    123     pp(cadr(a)); pr(" "); pp(car(a));
    124   }
    125 }
    126 
    127 static void pr_args2(Any x) { // for in, out, inout
    128   for(int i = 0; NIL != x; x = cdr(x), i++) {
    129     Any a = car(x);
    130     if(0 < i) pr(", ");
    131     pp(caddr(a)); pr(" "); pp(cadr(a));
    132     switch(kind(car(a))) {
    133     case OUT:
    134     case INOUT: pr("[]");
    135     }
    136   }
    137 }
    138 
    139 static Any resolve_typedef(Any x, int val) {
    140   Any v;
    141   while(TYPEDEF == kind(car(v = get2(x)))) x = cadddr(v);
    142   return val ? v : x;
    143 }
    144 
    145 static Any pr_default_slot(Any slot) { // (sName (string))
    146   Any n = car(slot);
    147   Any t = cadr(slot);
    148   Any v;
    149   if(consp(t)) { // !consp is T in template
    150     switch(kind(car(t))) {
    151     case RELATIVE:
    152     case ABSOLUTE:
    153       t = resolve_typedef(cadr(t), 1);
    154     }
    155     switch(kind(car(t))) {
    156     case STRING: pr("      this."); pp(n); pl(" = \"\";"); break;
    157     case ANY: pr("      this."); pp(n); pl(" = com.sun.star.uno.Any.VOID;"); break;
    158     case TYPE: pr("      this."); pp(n); pl(" = com.sun.star.uno.Type.VOID;"); break;
    159     case SEQUENCE:
    160       pr("      this."); pp(n); pr(" = new ");
    161       seq0++;
    162       pp(t);
    163       seq0--;
    164       pl(";");
    165       break;
    166     case TEMPLATE: //(template (absolute com.sun.star.beans.Optional) ((string)))
    167       pr("      "); pp(n); pr(" = new "); pp(cadr(t)); pl("();"); break;
    168       break;
    169     case ENUM:
    170       v = cadddr(t);
    171       pr("      this."); pp(n); pr(" = "); pp(cadr(t)); pr(".");
    172       pp(consp(v) ? car(v) : v);
    173       pl(";");
    174       break;
    175     case STRUCT:
    176       pr("      this."); pp(n); pr(" = new "); pp(cadr(t)); pl("();");
    177       break;
    178     }
    179   }
    180   return slot;
    181 }
    182 
    183 static void pr_default_slots(Any slots) {mapc(pr_default_slot, slots);}
    184 
    185 static int pr_slots_rec1(Any super) { // (absolute|relative com.sun...)
    186   if(NIL == super) return 0;
    187   Any s = cdddr(resolve_typedef(cadr(super), 1));
    188   if(pr_slots_rec1(car(s))) pr(", ");
    189   pr_args(cdr(s));
    190   return 1;
    191 }
    192 
    193 static int pr_slots_rec2(Any super) {
    194   if(NIL == super) return 0;
    195   Any s = cdddr(resolve_typedef(cadr(super), 1));
    196   int z = pr_slots_rec2(car(s));
    197   for(Any y = cdr(s); NIL != y; y = cdr(y)) {
    198     if(0 < z++) pr(", ");
    199     pp(caar(y));
    200   }
    201   return 1;
    202 }
    203 
    204 static void pr_slots(Any slots, Any name, Any super) {
    205   for(Any y = slots; NIL != y; y = cdr(y)) {
    206     Any slot = car(y);
    207     Any n = car(slot);
    208     Any t = cadr(slot);
    209     pr("   public "); pp(t); pr(" "); pp(n); pl(";");
    210   }
    211   pr("   public "); pp(name); pl("() {");
    212   pr_default_slots(slots);
    213   pl("   }");
    214   pr("   public "); pp(name); pr("(");
    215   if(pr_slots_rec1(super) && NIL != slots) pr(", ");
    216   pr_args(slots);
    217   pl(") {");
    218   if(NIL != super) {
    219     pr("      super(");
    220     pr_slots_rec2(super);
    221     pl(");");
    222   }
    223   for(Any y = slots; NIL != y; y = cdr(y)) {
    224     Any slot = car(y);
    225     Any n = car(slot);
    226     Any t = cadr(slot);
    227     // TODO if Object => super(slot);
    228     pr("      this."); pp(n); pr(" = "); pp(n); pl(";");
    229   }
    230   pl("   }");
    231 }
    232 
    233 static Any method;
    234 static int k;
    235 
    236 typedef enum {_ATTRIBUTE, _METHOD, _MEMBER, _PARAMETER} _Kind;
    237 
    238 static char *__kind[] = {"Attribute", "Method", "Member", "Parameter"};
    239 
    240 static int pr_TypeInfo_signature_test = 0;
    241 
    242 static Any pr_TypeInfo_signature(Any x) {
    243   if(consp(x)) {
    244     switch(kind(car(x))) {
    245     case ABSOLUTE:
    246     case RELATIVE: if(!pr_TypeInfo_signature_test) pp(x); break;
    247     case SEQUENCE:
    248       if(!pr_TypeInfo_signature_test) pr("[]");
    249       return pr_TypeInfo_signature(cadr(x));
    250     case TEMPLATE:
    251       if(!pr_TypeInfo_signature_test) {
    252         pp(cadr(x)); pr("<");
    253         pp_list(caddr(x), ",", pr_TypeInfo_signature);
    254         pr(">");
    255       }
    256       return T;
    257     default:
    258       if(!pr_TypeInfo_signature_test) pp_list(x, " ", print);
    259     }
    260   }
    261   return NIL;
    262 }
    263 
    264 static void pr_TypeInfo2(_Kind _kind, Any name, Any type, int flags, int *i, int j) {
    265   pl(*i < 0 && j < 0 ? "" : ",");
    266   pr("      new com.sun.star.lib.uno.typeinfo."); pr(__kind[_kind]);
    267   pr("TypeInfo(\""); pp(name); pr("\", ");
    268   if(!j) {pr("\""); pp(method); pr("\", ");}
    269   pi(++*i); pr(", ");
    270   pi(flags);
    271   if(!(consp(type))) {pr(", null, "); pi(++k);}
    272   else
    273     switch(_kind) {
    274     case _ATTRIBUTE:
    275     case _MEMBER:
    276     case _METHOD:
    277     case _PARAMETER:
    278       switch(kind(car(type))) {
    279       case SEQUENCE:
    280       case TEMPLATE:
    281         pr_TypeInfo_signature_test = 1;
    282         if(NIL != pr_TypeInfo_signature(type)) {
    283           pr_TypeInfo_signature_test = 0;
    284           pr(", new com.sun.star.uno.Type(\"");
    285           pr_TypeInfo_signature(type);
    286           pr("\", com.sun.star.uno.TypeClass.");
    287           switch(kind(car(type))) {
    288           case SEQUENCE: pr("SEQUENCE"); break;
    289           default: pr("STRUCT");
    290           }
    291           pr(")");
    292           switch(_kind) {
    293           case _MEMBER:
    294             pr(", -1");
    295           }
    296         }
    297       }
    298     }
    299   pr(")");
    300 }
    301 
    302 enum flags { // ridljar/com/sun/star/lib/uno/typeinfo.TypeInfo.java
    303   _IN        = 0x001,
    304   _OUT       = 0x002,
    305   _UNSIGNED  = 0x004,
    306   _READONLY  = 0x008,
    307   _ONEWAY    = 0x010,
    308   _CONST     = 0x020,
    309   _ANY       = 0x040,
    310   _INTERFACE = 0x080,
    311   _BOUND     = 0x100
    312 };
    313 
    314 static int type_flags(Any x) {
    315   if(consp(x)) {
    316     switch(kind(car(x))) {
    317     case UNSIGNED: return _UNSIGNED;
    318     case ANY: return _ANY;
    319     case SEQUENCE: return type_flags(cadr(x));
    320     case RELATIVE:
    321     case ABSOLUTE:
    322       x = resolve_typedef(cadr(x), 0);
    323       return com_sun_star_uno_XInterface == x ? _INTERFACE : type_flags(x);
    324     }
    325   }
    326   return 0;
    327 }
    328 
    329 static int type_template(Any x) {
    330   if(consp(x)) {
    331     switch(kind(car(x))) {
    332     case TEMPLATE: return 1;
    333     case SEQUENCE: return type_template(cadr(x));
    334     case RELATIVE:
    335     case ABSOLUTE:
    336       x = resolve_typedef(cadr(x), 0);
    337       return com_sun_star_uno_XInterface == x ? 0 : type_template(x);
    338     }
    339   }
    340   return 0;
    341 }
    342 
    343 static Any kindeq(Kind k, Any a) {return k == kind(a) ? T : NIL;}
    344 
    345 static Any readonlyp(Any a) {return kindeq(READONLY, a);}
    346 static Any boundp(Any a) {return kindeq(BOUND, a);}
    347 
    348 static Any pr_TypeInfo1(void *env, Any x) {
    349   int f = 0;
    350   Any t = NIL;
    351   switch(kind(car(x))) {
    352   case ATTRIBUTE: // (attribute (string) KeyName (readonly))
    353     t = cadr(x);
    354     f |= type_flags(t);
    355     if(NIL != some(readonlyp, cadddr(x))) f |= _READONLY;
    356     if(NIL != some(boundp, cadddr(x))) f |= _BOUND;
    357     pr_TypeInfo2(_ATTRIBUTE, caddr(x), t, f, env, -1);
    358     break;
    359   case ID: // (NewValue (any))
    360     t = cadr(x);
    361     f |= type_flags(t);
    362     pr_TypeInfo2(_MEMBER, car(x), t, f, env, -1);
    363     break;
    364   case METHOD: // (method queryInterface NIL (any) ((in aType (type))))
    365     method = cadr(x);
    366     t = cadddr(x);
    367     f |= type_flags(t);
    368     if(NIL != caddr(x)) f |= _ONEWAY;
    369     pr_TypeInfo2(_METHOD, method, t, f, env, -1);
    370     int i = -1;
    371     mapcx(&i, pr_TypeInfo1, caddddr(x));
    372     break;
    373   case IN: // (in aType (type))
    374     t = caddr(x);
    375     f |= _IN | type_flags(t);
    376     if((f != _IN && f != (_IN | _ANY)) || type_template(t))
    377       pr_TypeInfo2(_PARAMETER, cadr(x), t, f, env, 0);
    378     else
    379       ++*((int *) env);
    380     break;
    381   case OUT:
    382     t = caddr(x);
    383     f |= _OUT | type_flags(t);
    384     pr_TypeInfo2(_PARAMETER, cadr(x), t, f, env, 0);
    385     break;
    386   case INOUT:
    387     t = caddr(x);
    388     f |= _IN | _OUT | type_flags(t);
    389     pr_TypeInfo2(_PARAMETER, cadr(x), t, f, env, 0);
    390   }
    391   return NIL;
    392 }
    393 
    394 static Any pr_TypeInfo1_attribute(void *env, Any x) {
    395   if(ATTRIBUTE == kind(car(x))) {
    396     pr_TypeInfo1(env, x);
    397     if(NIL == some(readonlyp, cadddr(x)))
    398       ++*((int *) env);
    399   }
    400   return NIL;
    401 }
    402 
    403 static Any pr_TypeInfo1_nonattribute(void *env, Any x) {
    404   if(ATTRIBUTE != kind(car(x)))
    405     pr_TypeInfo1(env, x);
    406   return NIL;
    407 }
    408 
    409 static Any noninterfacep(Any x) {return INTERFACE == kind(car(x)) ? NIL : x;}
    410 
    411 static void pr_TypeInfo(Any body) {
    412   if(NIL != body && NIL != some(noninterfacep, body)) {
    413     pr("   public static final com.sun.star.lib.uno.typeinfo.TypeInfo UNOTYPEINFO[] = {");
    414     int i = -1;
    415     k = -1;
    416     mapcx(&i, pr_TypeInfo1_attribute, body);
    417     mapcx(&i, pr_TypeInfo1_nonattribute, body);
    418     pl("");
    419     pl("   };");
    420   }
    421 }
    422 
    423 static void pr_extends(Any x) {
    424   if(NIL != x) {
    425     pr(" extends ");
    426     use_XInterface = 1;
    427     pp(x);
    428     use_XInterface = 0;
    429   }
    430 }
    431 
    432 static void pr_struct(Any x) {
    433   Any name = cadr(x);
    434   Any published = caddr(x);
    435   if(1 || NIL != published) {
    436     Any super = cadddr(x);
    437     Any slots = cddddr(x);
    438     pr_package(x);
    439     Any k = sym2k(name);
    440     pr("public class "); pp(k);
    441     pr_extends(super);
    442     pl(" {");
    443     pr_slots(slots, k, super);
    444     pr_TypeInfo(slots);
    445     pl("}");
    446   }
    447 }
    448 
    449 static void pr_exception(Any x) {
    450   Any name = cadr(x);
    451   Any published = caddr(x);
    452   if(1 || NIL != published) {
    453     Any super = cadddr(x);
    454     Any body = cddddr(x);
    455     pr_package(x);
    456     Any k = sym2k(name);
    457     pr("public class "); pp(k);
    458     int e = name == com_sun_star_uno_Exception;
    459     int r = name == com_sun_star_uno_RuntimeException;
    460     if(e)
    461       pr(" extends java.lang.Exception");
    462     else if(r)
    463       pr(" extends java.lang.RuntimeException");
    464     else pr_extends(super);
    465     pl(" {");
    466     if(e || r) {
    467       pl("   public java.lang.Object Context;");
    468       pr("   public "); pp(k); pl("() {");
    469       pl("   }");
    470       pr("   public "); pp(k); pl("(java.lang.String m) {");
    471       pl("      super(m);");
    472       pl("   }");
    473       pr("   public "); pp(k); pl("(java.lang.String m, java.lang.Object c) {");
    474       pl("      super(m);");
    475       pl("      this.Context = c;");
    476       pl("   }");
    477       pl("   public static final com.sun.star.lib.uno.typeinfo.TypeInfo UNOTYPEINFO[] = {");
    478       pl("      new com.sun.star.lib.uno.typeinfo.MemberTypeInfo(\"Context\", 0, 128)");
    479       pl("   };");
    480     } else {
    481       for(Any y = body; NIL != y; y = cdr(y)) {
    482         Any slot = car(y);
    483         pr("   public "); pp(cadr(slot)); pr(" "); pp(car(slot)); pl(";");
    484       }
    485       pr("   public "); pp(k); pl("() {");
    486       pr_default_slots(body);
    487       pl("   }");
    488       pr("   public "); pp(k); pl("(java.lang.String m) {");
    489       pl("      super(m);");
    490       pr_default_slots(body);
    491       pl("   }");
    492       /* pr("   public "); pp(k); pl("(java.lang.String m, java.lang.Object c) {"); */
    493       /* pl("      super(m, c);"); */
    494       /* pr_default_slots(body); */
    495       /* pl("   }"); */
    496       if(NIL != body) {
    497         pr("   public "); pp(k);
    498         pr("(java.lang.String Message, java.lang.Object Context,");
    499         pr_args(body); // TODO inherited args!
    500         pl(") {");
    501         pl("      super(Message, Context);"); // TODO inherited args!
    502         for(Any y = body; NIL != y; y = cdr(y)) {
    503           Any slot = car(y);
    504           Any n = car(slot);
    505           pr("      this."); pp(n); pr(" = "); pp(n); pl(";");
    506         }
    507         pl("   }");
    508       } else {
    509         pr("   public "); pp(k); pl("(java.lang.String m, java.lang.Object c) {");
    510         pl("      super(m, c);");
    511         pr_default_slots(body);
    512         pl("   }");
    513       }
    514       pr_TypeInfo(body);
    515     }
    516     pl("}");
    517   }
    518 }
    519 
    520 static Any pr_definterface_attribute(Any x) {
    521   if(ATTRIBUTE == kind(car(x))) pp(x);
    522   return NIL;
    523 }
    524 
    525 static Any pr_definterface_nonattribute(Any x) {
    526   if(ATTRIBUTE != kind(car(x))) pp(x);
    527   return NIL;
    528 }
    529 
    530 static void pr_definterface(Any x) {
    531   Any name = cadr(x);
    532   Any published = caddr(x);
    533   if(1 || NIL != published) {
    534     Any super = cadddr(x);
    535     Any body = cddddr(x);
    536     pr_package(x);
    537     pr("public interface "); pp(sym2k(name));
    538     pr_extends(super);
    539     use_XInterface = 1;
    540     int i = NIL == super ? 0 : 1;
    541     for(Any y = body; NIL != y; y = cdr(y)) {
    542       Any slot = car(y);
    543       if(INTERFACE == kind(car(slot))) {
    544         pr(0 < i++ ? ", " : " extends ");
    545         pp(cadr(slot));
    546       }
    547     }
    548     if(NIL == super && i <= 0 && name != com_sun_star_uno_XInterface)
    549       pr(" extends com.sun.star.uno.XInterface");
    550     use_XInterface = 0;
    551     pl(" {");
    552     if(name != com_sun_star_uno_XInterface) {
    553       mapc(pr_definterface_attribute, body);
    554       mapc(pr_definterface_nonattribute, body);
    555       pr_TypeInfo(body);
    556     }
    557     pl("}");
    558   }
    559 }
    560 
    561 static void pr_method(Any x) {
    562   Any name = cadr(x);
    563   Any published = caddr(x);
    564   Any type = cadddr(x);
    565   Any args = caddddr(x);
    566   Any body = cdddddr(x);
    567   pr("   public abstract "); pp(type); pr(" "); pp(name); pr("("); pr_args2(args); pr(")");
    568   if(NIL != body) {
    569     pr(" throws "); pp_list(body, ", ", pp);
    570   }
    571   pl(";");
    572 }
    573 
    574 static Any pr_attribute_get(Any e) {
    575   if(GET == kind(car(e))) {
    576     pr(" throws ");
    577     pp_list(cadr(e), ", ", pp);
    578   }
    579 }
    580 
    581 static Any pr_attribute_set(Any e) {
    582   if(SET == kind(car(e))) {
    583     pr(" throws ");
    584     pp_list(cadr(e), ", ", pp);
    585   }
    586 }
    587 
    588 static void pr_attribute(Any x) { // (attribute (string) KeyName (readonly))
    589   Any t = cadr(x);
    590   Any n = caddr(x);
    591   Any o = cadddr(x);
    592   Any b = cddddr(x);
    593   // (attribute (string) HyperLinkTarget (bound) (set ((relative com sun star beans UnknownPropertyException))) (get ((relative com sun star beans UnknownPropertyException))))
    594   pr("   public abstract "); pp(t); pr(" get"); pp(n); pr("()");
    595   mapc(pr_attribute_get, b);
    596   pl(";");
    597   if(NIL == some(readonlyp, o)) {
    598     pr("   public abstract void set"); pp(n); pr("("); pp(t); pr(" x)");
    599     mapc(pr_attribute_set, b);
    600     pl(";");
    601   }
    602 }
    603 
    604 static void pr_arg(Any x) {
    605   pp(caddr(x)); pr(" "); pp(cadr(x));
    606 }
    607 
    608 static void pr_service(Any x) {
    609   Any name = cadr(x);
    610   Any published = caddr(x);
    611   if(1 || NIL != published) {
    612     Any super = cadddr(x); // interface service
    613     Any body = caddddr(x); // accumulated service
    614     if(!(NIL != super && NIL == body)) return; // TODO why not?
    615     pr_package(x);
    616     pl("import com.sun.star.uno.XComponentContext;");
    617     pl("import com.sun.star.uno.DeploymentException;");
    618     pl("import com.sun.star.uno.TypeClass;");
    619     pl("import com.sun.star.uno.Type;");
    620     pl("import com.sun.star.uno.UnoRuntime;");
    621     pl("import com.sun.star.lang.XMultiComponentFactory;");
    622     pr("public final class "); pp(last(name));
    623     //if(NIL != super) {pr(" implements "); pp(super);}
    624     pl(" {");
    625     if(NIL != super && NIL == body) { // implicit constructor
    626       Any s = super;
    627       if(RELATIVE == kind(car(s)) && NIL == cddr(s))
    628         s = cons(car(s), reverse(module, cdr(s)));
    629       pr("   private "); pp(last(name)); pl("() {}");
    630       pr("   public static "); pp(super); pl(" create(XComponentContext c) { // interface service");
    631       pr("      "); pp(super); pl(" x = null;");
    632       pl("      try {");
    633       pl("         XMultiComponentFactory f = $getFactory(c);");
    634       pr("         x = ("); pp(s); pr(") $castInstance(f.createInstanceWithContext(\""); pp(name); pl("\", c), c);");
    635       pl("      } catch(Exception e) {");
    636       pr("         throw new DeploymentException(\"component context fails to supply "); pp(name); pr(" of type "); pp(s); pl(": \".concat(e.toString()), c);");
    637       pl("      }");
    638       pl("      return x;");
    639       pl("   }");
    640       pl("   private static XMultiComponentFactory $getFactory(XComponentContext c) {");
    641       pl("      XMultiComponentFactory f = c.getServiceManager();");
    642       pl("      if(f == null)");
    643       pl("         throw new DeploymentException(\"component context fails to supply service manager\", c);");
    644       pl("      return f;");
    645       pl("   }");
    646       pl("   private static Object $castInstance(Object o, XComponentContext c) {");
    647       pr("      java.lang.Object o2 = UnoRuntime.queryInterface(new Type(\""); pp(s); pl("\", TypeClass.INTERFACE), o);");
    648       pl("      if(o2 == null)");
    649       pr("         throw new DeploymentException(\"component context fails to supply service "); pp(name); pr(" of type "); pp(s); pl("\", c);");
    650       pl("      return o2;");
    651       pl("   }");
    652     }
    653     pl("}");
    654   }
    655 }
    656 
    657 static void pr_singleton(Any x) {
    658   /* Any name = cadr(x); */
    659   /* Any published = caddr(x); */
    660   /* Any type = cadddr(x); */
    661   /* int iface = !null(caddddr(x)); */
    662   /* pr_package(name); */
    663   /* pr("public class "); pp(name); */
    664   /* if(iface) {pr(" extends "); pp(type);} */
    665   /* pr(" { // "); pr(iface ? "interface" : "service"); pl(" singleton"); */
    666   /* pr("   private "); pp(name); pl("() {}"); */
    667   /* pl("   private static class Holder {"); */
    668   /* pr("      public static final "); pp(name); pr(" instance = new "); pp(name); pl("();"); */
    669   /* pl("   }"); */
    670   /* pr("   public static "); pp(name); pl(" getInstance() {"); */
    671   /* pl("      return Holder.instance;"); */
    672   /* pl("   }"); */
    673   /* pl("}"); */
    674 }
    675 
    676 static void pr_constants(Any x) {
    677   Any name = cadr(x);
    678   Any published = caddr(x);
    679   if(1 || NIL != published) {
    680     Any body = cdddr(x);
    681     pr_package(x);
    682     pr("public interface "); pp(sym2k(name)); pl(" {");
    683     mapc(pp, body);
    684     pl("}");
    685   }
    686 }
    687 
    688 static void pr_const(Any x) {
    689   Any name = cadr(x);
    690   Any type = caddr(x);
    691   Any exp = cadddr(x);
    692   pr("   public static final ");
    693   type = resolve_typedef(type, 0);
    694   pp(type);
    695   pr(" "); pp(sym2k(name)); pr(" = ");
    696   Kind k = kind(car(type));
    697   if(BYTE == k)
    698     pr(" (byte) ");
    699   pp(exp);
    700   switch(k) {
    701   case HYPER: pr("L"); break;
    702   case FLOAT: pr("f"); break;
    703     //case BYTE: pr("y"); break; // java7
    704   }
    705   pl(";");
    706 }
    707 
    708 static void pr_absolute(Any x) { // (absolute|relative com.sun...)
    709   x = resolve_typedef(cadr(x), 0);
    710   if(!use_XInterface && x == com_sun_star_uno_XInterface)
    711     pr("java.lang.Object");
    712   else
    713     pp(x);
    714 }
    715 
    716 static void pr_property(Any x) {
    717   Any n = cadr(x);
    718   Any t = caddr(x);
    719   Any o = cadddr(x);
    720   pr("   protected "); pp(t); pr(" "); pp(n); pl(";");
    721   pr("   public "); pp(t); pr(" get"); pp(n); pl("();");
    722   if(NIL == some(readonlyp, o)) {
    723     pr("   public void set"); pp(n); pr("("); pp(t); pr(" "); pp(n); pl(");");
    724   }
    725 }
    726 
    727 static void pr_deftemplate(Any x) { // (deftemplate com.sun.star.beans.Optional NIL (T) (IsPresent (boolean)) (Value T))
    728   Any name = cadr(x);
    729   Any published = caddr(x);
    730   if(1 || NIL != published) {
    731     Any args = cadddr(x);
    732     Any slots = cddddr(x);
    733     pr_package(x);
    734     Any k = sym2k(name);
    735     pr("public class "); pp(k);
    736     pr("<"); pp_list(args, ", ", pp); pr(">"); pl(" {");
    737     pr_slots(slots, k, NIL);
    738     pr_TypeInfo(slots);
    739     pl("}");
    740   }
    741 }
    742 
    743 static void pr_primitive(Any x) {
    744   if(template) {
    745     switch(kind(car(x))) {
    746     case BOOLEAN: pr("java.lang.Boolean"); break;
    747     case BYTE: pr("java.lang.Byte"); break;
    748     case SHORT: pr("java.lang.Short"); break;
    749     case FLOAT: pr("java.lang.Float"); break;
    750     case DOUBLE: pr("java.lang.Double"); break;
    751     case CHAR: pr("java.lang.Character"); break;
    752     case LONG: pr("java.lang.Integer"); break;
    753     case HYPER: pr("java.lang.Long"); break;
    754     }
    755   } else {
    756     switch(kind(car(x))) {
    757     case BOOLEAN:
    758     case BYTE:
    759     case SHORT:
    760     case FLOAT:
    761     case DOUBLE:
    762     case CHAR: print(car(x)); break;
    763     case LONG: pr("int"); break;
    764     case HYPER: pr("long"); break;
    765     }
    766   }
    767 }
    768 
    769 static void pr_template(Any x) {
    770   template = 1;
    771   pp(cadr(x)); pr("<"); pp_list(caddr(x), ", ", pp); pr(">");
    772   template = 0;
    773 }
    774 
    775 static Any pp(Any x) {
    776   if(x) {
    777     if(consp(x)) {
    778       Any a = car(x);
    779       switch(kind(a)) {
    780       case MODULE: break;
    781       case ENUM: pr_enum(x); break;
    782       case STRUCT: pr_struct(x); break;
    783       case DEFINTERFACE: pr_definterface(x); break;
    784       case DEFTEMPLATE: pr_deftemplate(x); break;
    785       case METHOD: pr_method(x); break;
    786         //case IN:
    787         //case OUT:
    788         //case INOUT: pr_arg(x); break;
    789       case RELATIVE:
    790       case ABSOLUTE: pr_absolute(x); break;
    791       case CONSTANTS: pr_constants(x); break;
    792       case CONST: pr_const(x); break;
    793       case SEQUENCE:
    794         pp(cadr(x));
    795         pr(0 < seq0 && SEQUENCE != kind(car(cadr(x))) ? "[0]" : "[]");
    796         break;
    797       case ATTRIBUTE: pr_attribute(x); break;
    798       case EXCEPTION: pr_exception(x); break;
    799       case SERVICE: pr_service(x); break;
    800       case PROPERTY: pr_property(x); break;
    801       case SINGLETON: pr_singleton(x); break;
    802       case TYPEDEF: break;
    803       case VOID: print(car(x)); break;
    804       case BOOLEAN:
    805       case BYTE:
    806       case SHORT:
    807       case FLOAT:
    808       case DOUBLE:
    809       case CHAR:
    810       case LONG:
    811       case HYPER: pr_primitive(x); break;
    812       case UNSIGNED: pp(cdr(x)); break;
    813       case STRING: pr("java.lang.String"); break;
    814       case TYPE: pr("com.sun.star.uno.Type"); break;
    815       case ANY: pr("java.lang.Object"); break;
    816       case EXP: pp(cadr(x)); break;
    817       case XOR: pp(cadr(x)); pr("^"); pp(caddr(x)); break;
    818       case AND: pp(cadr(x)); pr("&"); pp(caddr(x)); break;
    819       case OR: pp(cadr(x)); pr("|"); pp(caddr(x)); break;
    820       case LSHIFT:
    821       case RSHIFT:
    822       case MUL:
    823       case DIV:
    824       case MOD: pp(cadr(x)); pp(car(x)); pp(caddr(x)); break;
    825       case PLUS:
    826       case MINUS:
    827         if(NIL == cddr(x)) { // unary
    828           pp(car(x)); pp(cadr(x));
    829         } else { // binary
    830           pp(cadr(x)); pp(car(x)); pp(caddr(x));
    831         }
    832         break;
    833       case NOT: pr("!"); pp(cadr(x)); break;
    834       case TEMPLATE: pr_template(x); break;
    835         //default: pr("###"); print(x);
    836       }
    837     } else
    838       print(x);
    839   } else
    840     printf("NIL");
    841   return x;
    842 }
    843 
    844 int main() {
    845   init();
    846   yyparse();
    847   Any p = intern2abs(list4(mk(ID, "com"), mk(ID, "sun"), mk(ID, "star"), mk(ID, "uno")));
    848   com_sun_star_uno_XInterface = intern2rel(sym1(mk(ID, "XInterface")), p);
    849   com_sun_star_uno_Exception = intern2rel(sym1(mk(ID, "Exception")), p);
    850   com_sun_star_uno_RuntimeException = intern2rel(sym1(mk(ID, "RuntimeException")), p);
    851   //pp_list(ast, NULL, pp);
    852   mapc(build2, ast);
    853   walk2_fn = pp;
    854   walk2(root2);
    855   return 0;
    856 }