1 /* -----------------------------------------------------------------------------
2 * See the LICENSE file for information on copyright, usage and redistribution
3 * of SWIG, and the README file for authors - http://www.swig.org/release.html.
7 * R language module for SWIG.
8 * ----------------------------------------------------------------------------- */
10 char cvsroot_r_cxx[] = "$Id: r.cxx 11454 2009-07-26 21:21:26Z wsfulton $";
14 #define UNUSED(a) (void)a
16 static const double DEFAULT_NUMBER = .0000123456712312312323;
17 static const int MAX_OVERLOAD_ARGS = 5;
19 static String* replaceInitialDash(const String *name)
22 if (!Strncmp(name, "_", 1)) {
24 Insert(retval, 0, "s");
31 static String * getRTypeName(SwigType *t, int *outCount = NULL) {
32 String *b = SwigType_base(t);
33 List *els = SwigType_split(t);
37 if(Strncmp(b, "struct ", 7) == 0)
38 Replace(b, "struct ", "", DOH_REPLACE_FIRST);
40 /* Printf(stderr, "<getRTypeName> %s,base = %s\n", t, b);
41 for(i = 0; i < Len(els); i++)
42 Printf(stderr, "%d) %s, ", i, Getitem(els,i));
43 Printf(stderr, "\n"); */
45 for(i = 0; i < Len(els); i++) {
46 String *el = Getitem(els, i);
47 if(Strcmp(el, "p.") == 0 || Strncmp(el, "a(", 2) == 0) {
55 String *tmp = NewString("");
56 char *retName = Char(SwigType_manglestr(t));
57 Insert(tmp, 0, retName);
65 return(NewString(""));
70 static String * getRType(Node *n) {
71 SwigType *elType = Getattr(n, "type");
72 SwigType *elDecl = Getattr(n, "decl");
73 //XXX How can we tell if this is already done.
74 SwigType_push(elType, elDecl);
77 String *rtype = Swig_typemap_lookup("rtype", n, "", 0);
78 String *i = getRTypeName(elType);
81 SwigType *td = SwigType_typedef_resolve(elType);
83 // Printf(stderr, "Resolving typedef %s -> %s\n", elType, td);
87 // Printf(stderr, "<getRType> i = %s, rtype = %s (for %s)\n",
91 Printf(ans, "%s", rtype);
92 Replaceall(ans, "$R_class", Char(i));
93 // Printf(stderr, "Found r type in typemap for %s (for %s) => %s (%s) => %s\n",
94 // SwigType_str(elType, 0), Getattr(n, "name"), rtype, i, ans);
103 /*********************
104 Tries to get the name of the R class corresponding to the given type
105 e.g. struct A * is ARef, struct A** is ARefRef.
106 Now handles arrays, i.e. struct A[2]
109 static String *getRClassName(String *retType, int /*addRef*/ = 1, int upRef=0) {
110 String *tmp = NewString("");
111 SwigType *resolved = SwigType_typedef_resolve_all(retType);
112 char *retName = Char(SwigType_manglestr(resolved));
114 Printf(tmp, "_p%s", retName);
116 Insert(tmp, 0, retName);
122 List *l = SwigType_split(retType);
125 #ifdef R_SWIG_VERBOSE
127 Printf(stderr, "SwigType_split return an empty list for %s\n",
134 String *el = Getitem(l, n-1);
135 char *ptr = Char(el);
136 if(strncmp(ptr, "struct ", 7) == 0)
139 Printf(tmp, "%s", ptr);
142 for(int i = 0; i < n; i++) {
143 if(Strcmp(Getitem(l, i), "p.") == 0 ||
144 Strncmp(Getitem(l, i), "a(", 2) == 0)
150 char *retName = Char(SwigType_manglestr(retType));
155 while(retName && strlen(retName) > 1 && strncmp(retName, "_p", 2) == 0) {
160 if(retName[0] == '_')
162 Insert(tmp, 0, retName);
169 /*********************
170 Tries to get the name of the R class corresponding to the given type
171 e.g. struct A * is ARef, struct A** is ARefRef.
172 Now handles arrays, i.e. struct A[2]
175 static String * getRClassNameCopyStruct(String *retType, int addRef) {
176 String *tmp = NewString("");
179 List *l = SwigType_split(retType);
182 #ifdef R_SWIG_VERBOSE
183 Printf(stderr, "SwigType_split return an empty list for %s\n", retType);
189 String *el = Getitem(l, n-1);
190 char *ptr = Char(el);
191 if(strncmp(ptr, "struct ", 7) == 0)
194 Printf(tmp, "%s", ptr);
197 for(int i = 0; i < n; i++) {
198 if(Strcmp(Getitem(l, i), "p.") == 0 ||
199 Strncmp(Getitem(l, i), "a(", 2) == 0)
205 char *retName = Char(SwigType_manglestr(retType));
210 while(retName && strlen(retName) > 1 &&
211 strncmp(retName, "_p", 2) == 0) {
217 if(retName[0] == '_')
219 Insert(tmp, 0, retName);
226 /*********************************
227 Write the elements of a list to the File*, one element per line.
228 If quote is true, surround the element with "element".
229 This takes care of inserting a tab in front of each line and also
230 a comma after each element, except the last one.
231 **********************************/
233 static void writeListByLine(List *l, File *out, bool quote = 0) {
235 for(i = 0; i < n; i++)
236 Printf(out, "%s%s%s%s%s\n", tab8,
239 quote ? "\"" :"", i < n-1 ? "," : "");
243 static const char *usage = (char *)"\
244 R Options (available with -r)\n\
245 -copystruct - Emit R code to copy C structs (on by default)\n\
246 -cppcast - Enable C++ casting operators (default) \n\
247 -debug - Output debug\n\
248 -dll <name> - Name of the DLL (without the .dll or .so suffix). Default is the module name.\n\
249 -gc - Aggressive garbage collection\n\
250 -memoryprof - Add memory profile\n\
251 -namespace - Output NAMESPACE file\n\
252 -no-init-code - Turn off the generation of the R_init_<pkgname> code (registration information still generated)\n\
253 -package <name> - Package name for the PACKAGE argument of the R .Call() invocations. Default is the module name.\n\
259 Display the help for this module on the screen/console.
261 static void showUsage() {
262 fputs(usage, stdout);
265 static bool expandTypedef(SwigType *t) {
266 if (SwigType_isenum(t)) return false;
267 String *prefix = SwigType_prefix(t);
268 if (Strncmp(prefix, "f", 1)) return false;
269 if (Strncmp(prefix, "p.f", 3)) return false;
275 Determine whether we should add a .copy argument to the S function
276 that wraps/interfaces to the routine that returns the given type.
278 static int addCopyParameter(SwigType *type) {
280 ok = Strncmp(type, "struct ", 7) == 0 || Strncmp(type, "p.struct ", 9) == 0;
282 ok = Strncmp(type, "p.", 2);
288 static void replaceRClass(String *tm, SwigType *type) {
289 String *tmp = getRClassName(type);
290 String *tmp_base = getRClassName(type, 0);
291 String *tmp_ref = getRClassName(type, 1, 1);
292 Replaceall(tm, "$R_class", tmp);
293 Replaceall(tm, "$*R_class", tmp_base);
294 Replaceall(tm, "$&R_class", tmp_ref);
295 Delete(tmp); Delete(tmp_base); Delete(tmp_ref);
298 static double getNumber(String *value, String *type) {
301 double d = DEFAULT_NUMBER;
303 // Printf(stderr, "getNumber %s %s\n", Char(value), type);
304 if(sscanf(Char(value), "%lf", &d) != 1)
305 return(DEFAULT_NUMBER);
310 class R : public Language {
313 void registerClass(Node *n);
314 void main(int argc, char *argv[]);
317 void dispatchFunction(Node *n);
318 int functionWrapper(Node *n);
319 int variableWrapper(Node *n);
321 int classDeclaration(Node *n);
322 int enumDeclaration(Node *n);
324 int membervariableHandler(Node *n);
326 int typedefHandler(Node *n);
328 int memberfunctionHandler(Node *n) {
330 Printf(stderr, "<memberfunctionHandler> %s %s\n",
333 member_name = Getattr(n, "name");
334 processing_class_member_function = 1;
335 int status = Language::memberfunctionHandler(n);
336 processing_class_member_function = 0;
340 /* Grab the name of the current class being processed so that we can
341 deal with members of that class. */
342 int classHandler(Node *n){
343 if(!ClassMemberTable)
344 ClassMemberTable = NewHash();
346 class_name = Getattr(n, "name");
347 int status = Language::classHandler(n);
354 String *runtimeCode();
357 int addRegistrationRoutine(String *rname, int nargs);
358 int outputRegistrationRoutines(File *out);
360 int outputCommandLineArguments(File *out);
361 int generateCopyRoutines(Node *n);
362 int DumpCode(Node *n);
364 int OutputMemberReferenceMethod(String *className, int isSet, List *el, File *out);
365 int OutputArrayMethod(String *className, List *el, File *out);
366 int OutputClassMemberTable(Hash *tb, File *out);
367 int OutputClassMethodsTable(File *out);
368 int OutputClassAccessInfo(Hash *tb, File *out);
370 int defineArrayAccessors(SwigType *type);
372 void addNamespaceFunction(String *name) {
373 if(!namespaceFunctions)
374 namespaceFunctions = NewList();
375 Append(namespaceFunctions, name);
378 void addNamespaceMethod(String *name) {
379 if(!namespaceMethods)
380 namespaceMethods = NewList();
381 Append(namespaceMethods, name);
384 String* processType(SwigType *t, Node *n, int *nargs = NULL);
385 String *createFunctionPointerHandler(SwigType *t, Node *n, int *nargs);
386 int addFunctionPointerProxy(String *name, Node *n, SwigType *t, String *s_paramTypes) {
387 /*XXX Do we need to put the t in there to get the return type later. */
388 if(!functionPointerProxyTable)
389 functionPointerProxyTable = NewHash();
391 Setattr(functionPointerProxyTable, name, n);
393 Setattr(SClassDefs, name, name);
394 Printv(s_classes, "setClass('",
397 "prototype = list(parameterTypes = c(", s_paramTypes, "),\n",
399 "returnType = '", SwigType_manglestr(t), "'),\n", tab8,
400 "contains = 'CRoutinePointer')\n\n##\n", NIL);
406 void addSMethodInfo(String *name,
407 String *argType, int nargs);
408 // Simple initialization such as constant strings that can be reused.
412 void addAccessor(String *memberName, Wrapper *f,
413 String *name, int isSet = -1);
415 static int getFunctionPointerNumArgs(Node *n, SwigType *tt);
422 // Strings into which we cumulate the generated code that is to be written
433 String *s_init_routine;
436 // State variables that carry information across calls to functionWrapper()
437 // from member accessors and class declarations.
438 String *opaqueClassDeclaration;
439 int processing_variable;
440 int processing_member_access_function;
445 int processing_class_member_function;
446 List *class_member_functions;
447 List *class_member_set_functions;
450 Hash *ClassMemberTable;
451 Hash *ClassMethodsTable;
455 // Information about routines that are generated and to be registered with
456 // R for dynamic lookup.
457 Hash *registrationTable;
458 Hash *functionPointerProxyTable;
460 List *namespaceFunctions;
461 List *namespaceMethods;
462 List *namespaceClasses; // Probably can do this from ClassMemberTable.
465 // Store a copy of the command line.
466 // Need only keep a string that has it formatted.
471 // State variables that we remember from the command line settings
472 // potentially that govern the code we generate.
475 bool noInitializationCode;
476 bool outputNamespaceInfo;
478 String *UnProtectWrapupCode;
481 static bool debugMode;
486 memoryProfile(false),
499 opaqueClassDeclaration(0),
500 processing_variable(0),
501 processing_member_access_function(0),
504 processing_class_member_function(0),
505 class_member_functions(0),
506 class_member_set_functions(0),
508 ClassMethodsTable(0),
511 registrationTable(0),
512 functionPointerProxyTable(0),
513 namespaceFunctions(0),
521 noInitializationCode(false),
522 outputNamespaceInfo(false),
523 UnProtectWrapupCode(0) {
526 bool R::debugMode = false;
528 int R::getFunctionPointerNumArgs(Node *n, SwigType *tt) {
530 n = Getattr(n, "type");
532 Printf(stderr, "type: %s\n", n);
534 SwigType *tmp = SwigType_typedef_resolve(tt);
536 n = SwigType_typedef_resolve(tt);
539 ParmList *parms = Getattr(n, "parms");
541 Printf(stderr, "parms = %p\n", parms);
542 return ParmList_len(parms);
546 void R::addSMethodInfo(String *name, String *argType, int nargs) {
550 SMethodInfo = NewHash();
552 Printf(stderr, "[addMethodInfo] %s\n", name);
554 Hash *tb = Getattr(SMethodInfo, name);
558 Setattr(SMethodInfo, name, tb);
561 String *str = Getattr(tb, "max");
564 max = atoi(Char(str));
567 str = NewStringf("%d", max);
568 Setattr(tb, "max", str);
573 Returns the name of the new routine.
575 String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) {
576 String *funName = SwigType_manglestr(t);
578 /* See if we have already processed this one. */
579 if(functionPointerProxyTable && Getattr(functionPointerProxyTable, funName))
583 Printf(stderr, "<createFunctionPointerHandler> Defining %s\n", t);
585 SwigType *rettype = Copy(Getattr(n, "type"));
586 SwigType *funcparams = SwigType_functionpointer_decompose(rettype);
587 String *rtype = SwigType_str(rettype, 0);
589 // ParmList *parms = Getattr(n, "parms");
591 ParmList *parms = SwigType_function_parms(SwigType_del_pointer(Copy(t)));
595 Printf(stderr, "Type: %s\n", t);
596 Printf(stderr, "Return type: %s\n", SwigType_base(t));
599 bool isVoidType = Strcmp(rettype, "void") == 0;
601 Printf(stderr, "%s is void ? %s (%s)\n", funName, isVoidType ? "yes" : "no", rettype);
603 Wrapper *f = NewWrapper();
605 /* Go through argument list, attach lnames for arguments */
608 for (i = 0; p; p = nextSibling(p), ++i) {
609 String *arg = Getattr(p, "name");
610 String *lname = NewString("");
612 if (!arg && Cmp(Getattr(p, "type"), "void")) {
613 lname = NewStringf("s_arg%d", i+1);
614 Setattr(p, "name", lname);
618 Setattr(p, "lname", lname);
621 Swig_typemap_attach_parms("out", parms, f);
622 Swig_typemap_attach_parms("scoerceout", parms, f);
623 Swig_typemap_attach_parms("scheck", parms, f);
625 Printf(f->def, "%s %s(", rtype, funName);
627 emit_parameter_variables(parms, f);
628 emit_return_variable(n, rettype, f);
629 // emit_attach_parmmaps(parms,f);
631 /* Using weird name and struct to avoid potential conflicts. */
632 Wrapper_add_local(f, "r_swig_cb_data", "RCallbackFunctionData *r_swig_cb_data = R_SWIG_getCallbackFunctionData()");
633 String *lvar = NewString("r_swig_cb_data");
635 Wrapper_add_local(f, "r_tmp", "SEXP r_tmp"); // for use in converting arguments to R objects for call.
636 Wrapper_add_local(f, "r_nprotect", "int r_nprotect = 0"); // for use in converting arguments to R objects for call.
637 Wrapper_add_local(f, "r_vmax", "char * r_vmax= 0"); // for use in converting arguments to R objects for call.
639 // Add local for error code in return value. This is not in emit_return_variable because that assumes an out typemap
640 // whereas the type makes are reverse
641 Wrapper_add_local(f, "ecode", "int ecode = 0");
644 int nargs = ParmList_len(parms);
648 Printf(stderr, "Setting number of parameters to %d\n", *numArgs);
650 String *setExprElements = NewString("");
652 String *s_paramTypes = NewString("");
654 SwigType *tt = Getattr(p, "type");
655 SwigType *name = Getattr(p, "name");
656 // String *lname = Getattr(p,"lname");
657 Printf(f->def, "%s %s", SwigType_str(tt, 0), name);
658 String *tm = Getattr(p, "tmap:out");
660 Replaceall(tm, "$1", name);
661 Replaceall(tm, "$result", "r_tmp");
662 replaceRClass(tm, Getattr(p,"type"));
663 Replaceall(tm,"$owner", "R_SWIG_EXTERNAL");
666 Printf(setExprElements, "%s\n", tm);
667 Printf(setExprElements, "SETCAR(r_swig_cb_data->el, %s);\n", "r_tmp");
668 Printf(setExprElements, "r_swig_cb_data->el = CDR(r_swig_cb_data->el);\n\n");
670 Printf(s_paramTypes, "'%s'", SwigType_manglestr(tt));
675 Printf(f->def, ", ");
676 Printf(s_paramTypes, ", ");
680 Printf(f->def, ") {\n");
682 Printf(f->code, "Rf_protect(%s->expr = Rf_allocVector(LANGSXP, %d));\n", lvar, nargs + 1);
683 Printf(f->code, "r_nprotect++;\n");
684 Printf(f->code, "r_swig_cb_data->el = r_swig_cb_data->expr;\n\n");
686 Printf(f->code, "SETCAR(r_swig_cb_data->el, r_swig_cb_data->fun);\n");
687 Printf(f->code, "r_swig_cb_data->el = CDR(r_swig_cb_data->el);\n\n");
689 Printf(f->code, "%s\n\n", setExprElements);
691 Printv(f->code, "r_swig_cb_data->retValue = R_tryEval(",
692 "r_swig_cb_data->expr,",
694 " &r_swig_cb_data->errorOccurred",
698 Printv(f->code, "\n",
699 "if(r_swig_cb_data->errorOccurred) {\n",
700 "R_SWIG_popCallbackFunctionData(1);\n",
701 "Rf_error(\"error in calling R function as a function pointer (",
710 /* Need to deal with the return type of the function pointer, not the function pointer itself.
711 So build a new node that has the relevant pieces.
712 XXX Have to be a little more clever so that we can deal with struct A * - the * is getting lost.
713 Is this still true? If so, will a SwigType_push() solve things?
715 Node *bbase = NewHash();
717 Setattr(bbase, "type", rettype);
718 Setattr(bbase, "name", NewString("result"));
719 String *returnTM = Swig_typemap_lookup("in", bbase, "result", f);
721 String *tm = returnTM;
722 Replaceall(tm,"$input", "r_swig_cb_data->retValue");
723 Replaceall(tm,"$target", "result");
724 replaceRClass(tm, rettype);
725 Replaceall(tm,"$owner", "R_SWIG_EXTERNAL");
726 Replaceall(tm,"$disown","0");
727 Printf(f->code, "%s\n", tm);
732 Printv(f->code, "R_SWIG_popCallbackFunctionData(1);\n", NIL);
733 Printv(f->code, "\n", UnProtectWrapupCode, NIL);
736 Printv(f->code, "return result;\n", NIL);
738 Printv(f->code, "\n}\n", NIL);
740 /* To coerce correctly in S, we really want to have an extra/intermediate
741 function that handles the scoerceout.
742 We need to check if any of the argument types have an entry in
743 that map. If none do, the ignore and call the function straight.
744 Otherwise, generate the a marshalling function.
745 Need to be able to find it in S. Or use an entirely generic one
746 that evaluates the expressions.
747 Handle errors in the evaluation of the function by restoring
748 the stack, if there is one in use for this function (i.e. no
752 Wrapper_print(f, f_wrapper);
754 addFunctionPointerProxy(funName, n, t, s_paramTypes);
755 Delete(s_paramTypes);
764 UnProtectWrapupCode =
765 NewStringf("%s", "vmaxset(r_vmax);\nif(r_nprotect) Rf_unprotect(r_nprotect);\n\n");
767 SClassDefs = NewHash();
769 sfile = NewString("");
770 f_init = NewString("");
771 s_header = NewString("");
772 f_begin = NewString("");
773 f_runtime = NewString("");
774 f_wrapper = NewString("");
775 s_classes = NewString("");
776 s_init = NewString("");
777 s_init_routine = NewString("");
783 int R::cDeclaration(Node *n) {
784 SwigType *t = Getattr(n, "type");
785 SwigType *name = Getattr(n, "name");
787 Printf(stderr, "cDeclaration (%s): %s\n", name, SwigType_lstr(t, 0));
788 return Language::cDeclaration(n);
794 Method from Language that is called to start the entire
795 processing off, i.e. the generation of the code.
796 It is called after the input has been read and parsed.
797 Here we open the output streams and generate the code.
799 int R::top(Node *n) {
800 String *module = Getattr(n, "name");
802 Rpackage = Copy(module);
804 DllName = Copy(module);
806 if(outputNamespaceInfo) {
807 s_namespace = NewString("");
808 Swig_register_filebyname("snamespace", s_namespace);
809 Printf(s_namespace, "useDynLib(%s)\n", DllName);
812 /* Associate the different streams with names so that they can be used in %insert directives by the
814 Swig_register_filebyname("sinit", s_init);
815 Swig_register_filebyname("sinitroutine", s_init_routine);
817 Swig_register_filebyname("begin", f_begin);
818 Swig_register_filebyname("runtime", f_runtime);
819 Swig_register_filebyname("init", f_init);
820 Swig_register_filebyname("header", s_header);
821 Swig_register_filebyname("wrapper", f_wrapper);
822 Swig_register_filebyname("s", sfile);
823 Swig_register_filebyname("sclasses", s_classes);
825 Swig_banner(f_begin);
827 Printf(f_runtime, "\n");
828 Printf(f_runtime, "#define SWIGR\n");
829 Printf(f_runtime, "\n");
832 Swig_banner_target_lang(s_init, "#");
833 outputCommandLineArguments(s_init);
835 Printf(f_wrapper, "#ifdef __cplusplus\n");
836 Printf(f_wrapper, "extern \"C\" {\n");
837 Printf(f_wrapper, "#endif\n\n");
841 Printf(f_wrapper, "#ifdef __cplusplus\n");
842 Printf(f_wrapper, "}\n");
843 Printf(f_wrapper, "#endif\n");
845 String *type_table = NewString("");
846 SwigType_emit_type_table(f_runtime,f_wrapper);
849 if(ClassMemberTable) {
850 //XXX OutputClassAccessInfo(ClassMemberTable, sfile);
851 Delete(ClassMemberTable);
852 ClassMemberTable = NULL;
855 Printf(f_init,"}\n");
856 if(registrationTable)
857 outputRegistrationRoutines(f_init);
859 /* Now arrange to write the 2 files - .S and .c. */
878 /*****************************************************
879 Write the generated code to the .S and the .c files.
880 ****************************************************/
881 int R::DumpCode(Node *n) {
882 String *output_filename = NewString("");
885 /* The name of the file in which we will generate the S code. */
886 Printf(output_filename, "%s%s.R", SWIG_output_directory(), Rpackage);
888 #ifdef R_SWIG_VERBOSE
889 Printf(stderr, "Writing S code to %s\n", output_filename);
892 File *scode = NewFile(output_filename, "w", SWIG_output_files());
894 FileErrorDisplay(output_filename);
895 SWIG_exit(EXIT_FAILURE);
897 Delete(output_filename);
900 Printf(scode, "%s\n\n", s_init);
901 Printf(scode, "%s\n\n", s_classes);
902 Printf(scode, "%s\n", sfile);
906 String *outfile = Getattr(n,"outfile");
907 File *runtime = NewFile(outfile,"w", SWIG_output_files());
909 FileErrorDisplay(outfile);
910 SWIG_exit(EXIT_FAILURE);
913 Printf(runtime, "%s", f_begin);
914 Printf(runtime, "%s\n", f_runtime);
915 Printf(runtime, "%s\n", s_header);
916 Printf(runtime, "%s\n", f_wrapper);
917 Printf(runtime, "%s\n", f_init);
922 if(outputNamespaceInfo) {
923 output_filename = NewString("");
924 Printf(output_filename, "%sNAMESPACE", SWIG_output_directory());
925 File *ns = NewFile(output_filename, "w", SWIG_output_files());
927 FileErrorDisplay(output_filename);
928 SWIG_exit(EXIT_FAILURE);
930 Delete(output_filename);
932 Printf(ns, "%s\n", s_namespace);
934 Printf(ns, "\nexport(\n");
935 writeListByLine(namespaceFunctions, ns);
937 Printf(ns, "\nexportMethods(\n");
938 writeListByLine(namespaceFunctions, ns, 1);
951 We may need to do more.... so this is left as a
954 int R::OutputClassAccessInfo(Hash *tb, File *out) {
955 int n = OutputClassMemberTable(tb, out);
956 OutputClassMethodsTable(out);
960 /************************************************************************
961 Currently this just writes the information collected about the
962 different methods of the C++ classes that have been processed
964 This will be used later to define S4 generics and methods.
965 **************************************************************************/
966 int R::OutputClassMethodsTable(File *) {
967 Hash *tb = ClassMethodsTable;
972 List *keys = Keys(tb);
974 int i, n = Len(keys);
976 for(i = 0; i < n ; i++ ) {
977 key = Getitem(keys, i);
978 Printf(stderr, "%d) %s\n", i, key);
979 List *els = Getattr(tb, key);
981 Printf(stderr, "\t");
982 for(int j = 0; j < nels; j+=2) {
983 Printf(stderr, "%s%s", Getitem(els, j), j < nels - 1 ? ", " : "");
984 Printf(stderr, "%s\n", Getitem(els, j+1));
986 Printf(stderr, "\n");
995 Iterate over the <class name>_set and <>_get
996 elements and generate the $ and $<- functions
997 that provide constrained access to the member
998 fields in these elements.
1000 tb - a hash table that is built up in functionWrapper
1001 as we process each membervalueHandler.
1002 The entries are indexed by <class name>_set and
1003 <class_name>_get. Each entry is a List *.
1005 out - the stram where the code is to be written. This is the S
1006 code stream as we generate only S code here..
1008 int R::OutputClassMemberTable(Hash *tb, File *out) {
1009 List *keys = Keys(tb), *el;
1012 int i, n = Len(keys);
1013 /* Loop over all the <Class>_set and <Class>_get entries in the table. */
1015 if(n && outputNamespaceInfo) {
1016 Printf(s_namespace, "exportClasses(");
1018 for(i = 0; i < n; i++) {
1019 key = Getitem(keys, i);
1020 el = Getattr(tb, key);
1022 String *className = Getitem(el, 0);
1023 char *ptr = Char(key);
1024 ptr = &ptr[Len(key) - 3];
1025 int isSet = strcmp(ptr, "set") == 0;
1027 // OutputArrayMethod(className, el, out);
1028 OutputMemberReferenceMethod(className, isSet, el, out);
1030 if(outputNamespaceInfo)
1031 Printf(s_namespace, "\"%s\"%s", className, i < n-1 ? "," : "");
1033 if(n && outputNamespaceInfo) {
1034 Printf(s_namespace, ")\n");
1040 /*******************************************************************
1041 Write the methods for $ or $<- for accessing a member field in an
1042 struct or union (or class).
1043 className - the name of the struct or union (e.g. Bar for struct Bar)
1044 isSet - a logical value indicating whether the method is for
1045 modifying ($<-) or accessing ($) the member field.
1046 el - a list of length 2 * # accessible member elements + 1.
1047 The first element is the name of the class.
1048 The other pairs are member name and the name of the R function to access it.
1049 out - the stream where we write the code.
1050 ********************************************************************/
1051 int R::OutputMemberReferenceMethod(String *className, int isSet,
1052 List *el, File *out) {
1053 int numMems = Len(el), j;
1054 int has_getitem = 0, has_setitem = 0, has_str = 0;
1055 int varaccessor = 0;
1059 Wrapper *f = NewWrapper(), *attr = NewWrapper();
1061 Printf(f->def, "function(x, name%s)", isSet ? ", value" : "");
1062 Printf(attr->def, "function(x, i, j, ...%s)", isSet ? ", value" : "");
1064 Printf(f->code, "{\n");
1065 Printf(f->code, "%saccessorFuns = list(", tab8);
1067 Node *itemList = NewHash();
1068 bool has_prev = false;
1069 for(j = 0; j < numMems; j+=3) {
1070 String *item = Getitem(el, j);
1071 if (Getattr(itemList, item))
1073 Setattr(itemList, item, "1");
1074 if (!Strcmp(item, "__getitem__")) has_getitem = 1;
1075 if (!Strcmp(item, "__setitem__")) has_setitem = 1;
1076 if (!Strcmp(item, "__str__")) has_str = 1;
1078 String *dup = Getitem(el, j + 1);
1079 char *ptr = Char(dup);
1080 ptr = &ptr[Len(dup) - 3];
1082 if (!strcmp(ptr, "get"))
1086 if (!Strcmp(item, "operator ()")) {
1087 pitem = NewString("call");
1088 } else if (!Strcmp(item, "operator ->")) {
1089 pitem = NewString("deref");
1090 } else if (!Strcmp(item, "operator +")) {
1091 pitem = NewString("add");
1092 } else if (!Strcmp(item, "operator -")) {
1093 pitem = NewString("sub");
1098 Printf(f->code, ", ");
1099 Printf(f->code, "'%s' = %s", pitem, dup);
1104 Printf(f->code, ")\n");
1106 if (!isSet && varaccessor > 0) {
1107 Printf(f->code, "%svaccessors = c(", tab8);
1109 for(j = 0; j < numMems; j+=3) {
1110 String *item = Getitem(el, j);
1111 String *dup = Getitem(el, j + 1);
1112 char *ptr = Char(dup);
1113 ptr = &ptr[Len(dup) - 3];
1115 if (!strcmp(ptr, "get")) {
1117 Printf(f->code, "'%s'%s", item, vcount < varaccessor ? ", " : "");
1120 Printf(f->code, ")\n");
1124 /* Printv(f->code, tab8,
1125 "idx = pmatch(name, names(accessorFuns))\n",
1127 "if(is.na(idx)) {\n",
1129 "stop(\"No ", (isSet ? "modifiable" : "accessible"), " field named \", name, \" in ", className,
1130 ": fields are \", paste(names(accessorFuns), sep = \", \")",
1131 ")", "\n}\n", NIL); */
1132 Printv(f->code, tab8,
1133 "idx = pmatch(name, names(accessorFuns))\n",
1135 "if(is.na(idx)) \n",
1137 Printf(f->code, "return(callNextMethod(x, name%s))\n",
1138 isSet ? ", value" : "");
1139 Printv(f->code, tab8, "f = accessorFuns[[idx]]\n", NIL);
1141 Printv(f->code, tab8, "f(x, value)\n", NIL);
1142 Printv(f->code, tab8, "x\n", NIL); // make certain to return the S value.
1144 Printv(f->code, tab8, "formals(f)[[1]] = x\n", NIL);
1146 Printv(f->code, tab8,
1147 "if (is.na(match(name, vaccessors))) f else f(x)\n", NIL);
1149 Printv(f->code, tab8, "f\n", NIL);
1152 Printf(f->code, "}\n");
1155 Printf(out, "# Start of accessor method for %s\n", className);
1156 Printf(out, "setMethod('$%s', '_p%s', ",
1158 getRClassName(className));
1159 Wrapper_print(f, out);
1163 Printf(out, "setMethod('[[<-', c('_p%s', 'character'),",
1164 getRClassName(className));
1165 Insert(f->code, 2, "name = i\n");
1166 Printf(attr->code, "%s", f->code);
1167 Wrapper_print(attr, out);
1174 Printf(out, "# end of accessor method for %s\n", className);
1179 /*******************************************************************
1180 Write the methods for [ or [<- for accessing a member field in an
1181 struct or union (or class).
1182 className - the name of the struct or union (e.g. Bar for struct Bar)
1183 el - a list of length 2 * # accessible member elements + 1.
1184 The first element is the name of the class.
1185 The other pairs are member name and the name of the R function to access it.
1186 out - the stream where we write the code.
1187 ********************************************************************/
1188 int R::OutputArrayMethod(String *className, List *el, File *out) {
1189 int numMems = Len(el), j;
1191 if(!el || numMems == 0)
1194 Printf(out, "# start of array methods for %s\n", className);
1195 for(j = 0; j < numMems; j+=3) {
1196 String *item = Getitem(el, j);
1197 String *dup = Getitem(el, j + 1);
1198 if (!Strcmp(item, "__getitem__")) {
1200 "setMethod('[', '_p%s', function(x, i, j, ..., drop =TRUE) ",
1201 getRClassName(className));
1202 Printf(out, " sapply(i, function (n) %s(x, as.integer(n-1))))\n\n", dup);
1204 if (!Strcmp(item, "__setitem__")) {
1205 Printf(out, "setMethod('[<-', '_p%s', function(x, i, j, ..., value)",
1206 getRClassName(className));
1207 Printf(out, " sapply(1:length(i), function(n) %s(x, as.integer(i[n]-1), value[n])))\n\n", dup);
1212 Printf(out, "# end of array methods for %s\n", className);
1218 /************************************************************
1219 Called when a enumeration is to be processed.
1220 We want to call the R function defineEnumeration().
1221 tdname is the typedef of the enumeration, i.e. giving its name.
1222 *************************************************************/
1223 int R::enumDeclaration(Node *n) {
1224 String *name = Getattr(n, "name");
1225 String *tdname = Getattr(n, "tdname");
1227 /* Using name if tdname is empty. */
1229 if(Len(tdname) == 0)
1233 if(!tdname || Strcmp(tdname, "") == 0) {
1234 Language::enumDeclaration(n);
1238 String *mangled_tdname = SwigType_manglestr(tdname);
1239 String *scode = NewString("");
1241 Printv(scode, "defineEnumeration('", mangled_tdname, "'",
1242 ",\n", tab8, tab8, tab4, ".values = c(\n", NIL);
1245 int value = -1; // First number is zero
1246 for (c = firstChild(n); c; c = nextSibling(c)) {
1247 // const char *tag = Char(nodeType(c));
1248 // if (Strcmp(tag,"cdecl") == 0) {
1249 name = Getattr(c, "name");
1250 String *type = Getattr(c, "type");
1251 String *val = Getattr(c, "enumvalue");
1252 if(val && Char(val)) {
1253 int inval = (int) getNumber(val, type);
1254 if(inval == DEFAULT_NUMBER)
1261 Printf(scode, "%s%s%s'%s' = %d%s\n", tab8, tab8, tab8, name, value,
1262 nextSibling(c) ? ", " : "");
1266 Printv(scode, "))", NIL);
1267 Printf(sfile, "%s\n", scode);
1270 Delete(mangled_tdname);
1276 /*************************************************************
1277 **************************************************************/
1278 int R::variableWrapper(Node *n) {
1279 String *name = Getattr(n, "sym:name");
1281 processing_variable = 1;
1282 Language::variableWrapper(n); // Force the emission of the _set and _get function wrappers.
1283 processing_variable = 0;
1286 SwigType *ty = Getattr(n, "type");
1287 int addCopyParam = addCopyParameter(ty);
1292 if(!SwigType_isconst(ty)) {
1293 Wrapper *f = NewWrapper();
1294 Printf(f->def, "%s = \nfunction(value%s)\n{\n",
1295 name, addCopyParam ? ", .copy = FALSE" : "");
1296 Printv(f->code, "if(missing(value)) {\n",
1297 name, "_get(", addCopyParam ? ".copy" : "", ")\n}", NIL);
1298 Printv(f->code, " else {\n",
1299 name, "_set(value)\n}\n}", NIL);
1301 Wrapper_print(f, sfile);
1304 Printf(sfile, "%s = %s_get\n", name, name);
1311 void R::addAccessor(String *memberName, Wrapper *wrapper, String *name,
1315 char *ptr = Char(name);
1316 isSet = Strcmp(NewString(&ptr[n-3]), "set") == 0;
1319 List *l = isSet ? class_member_set_functions : class_member_functions;
1324 class_member_set_functions = l;
1326 class_member_functions = l;
1329 Append(l, memberName);
1332 String *tmp = NewString("");
1333 Wrapper_print(wrapper, tmp);
1335 // if we could put the wrapper in directly: Append(l, Copy(sfun));
1337 Printf(stderr, "Adding accessor: %s (%s) => %s\n", memberName, name, tmp);
1340 #define MAX_OVERLOAD 256
1344 int argc; /* Argument count */
1345 ParmList *parms; /* Parameters used for overload check */
1346 int error; /* Ambiguity error */
1350 static List * Swig_overload_rank(Node *n,
1351 bool script_lang_wrapping) {
1352 Overloaded nodes[MAX_OVERLOAD];
1354 Node *o = Getattr(n,"sym:overloaded");
1361 if (Getattr(c,"error")) {
1362 c = Getattr(c,"sym:nextSibling");
1365 /* if (SmartPointer && Getattr(c,"cplus:staticbase")) {
1366 c = Getattr(c,"sym:nextSibling");
1370 /* Make a list of all the declarations (methods) that are overloaded with
1371 * this one particular method name */
1373 if (Getattr(c,"wrap:name")) {
1374 nodes[nnodes].n = c;
1375 nodes[nnodes].parms = Getattr(c,"wrap:parms");
1376 nodes[nnodes].argc = emit_num_required(nodes[nnodes].parms);
1377 nodes[nnodes].error = 0;
1380 c = Getattr(c,"sym:nextSibling");
1383 /* Sort the declarations by required argument count */
1386 for (i = 0; i < nnodes; i++) {
1387 for (j = i+1; j < nnodes; j++) {
1388 if (nodes[i].argc > nodes[j].argc) {
1389 Overloaded t = nodes[i];
1390 nodes[i] = nodes[j];
1397 /* Sort the declarations by argument types */
1400 for (i = 0; i < nnodes-1; i++) {
1401 if (nodes[i].argc == nodes[i+1].argc) {
1402 for (j = i+1; (j < nnodes) && (nodes[j].argc == nodes[i].argc); j++) {
1403 Parm *p1 = nodes[i].parms;
1404 Parm *p2 = nodes[j].parms;
1406 int num_checked = 0;
1407 while (p1 && p2 && (num_checked < nodes[i].argc)) {
1408 // Printf(stdout,"p1 = '%s', p2 = '%s'\n", Getattr(p1,"type"), Getattr(p2,"type"));
1409 if (checkAttribute(p1,"tmap:in:numinputs","0")) {
1410 p1 = Getattr(p1,"tmap:in:next");
1413 if (checkAttribute(p2,"tmap:in:numinputs","0")) {
1414 p2 = Getattr(p2,"tmap:in:next");
1417 String *t1 = Getattr(p1,"tmap:typecheck:precedence");
1418 String *t2 = Getattr(p2,"tmap:typecheck:precedence");
1419 if ((!t1) && (!nodes[i].error)) {
1420 Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[i].n), Getline(nodes[i].n),
1421 "Overloaded method %s not supported (no type checking rule for '%s').\n",
1422 Swig_name_decl(nodes[i].n), SwigType_str(Getattr(p1, "type"), 0));
1424 } else if ((!t2) && (!nodes[j].error)) {
1425 Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[j].n), Getline(nodes[j].n),
1426 "xx Overloaded method %s not supported (no type checking rule for '%s').\n",
1427 Swig_name_decl(nodes[j].n), SwigType_str(Getattr(p2, "type"), 0));
1432 t1v = atoi(Char(t1));
1433 t2v = atoi(Char(t2));
1436 else if (!t1 && t2) differ = 1;
1437 else if (t1 && !t2) differ = -1;
1438 else if (!t1 && !t2) differ = -1;
1441 Overloaded t = nodes[i];
1442 nodes[i] = nodes[j];
1445 } else if ((differ == 0) && (Strcmp(t1,"0") == 0)) {
1446 t1 = Getattr(p1,"ltype");
1448 t1 = SwigType_ltype(Getattr(p1,"type"));
1449 if (Getattr(p1,"tmap:typecheck:SWIGTYPE")) {
1450 SwigType_add_pointer(t1);
1452 Setattr(p1,"ltype",t1);
1454 t2 = Getattr(p2,"ltype");
1456 t2 = SwigType_ltype(Getattr(p2,"type"));
1457 if (Getattr(p2,"tmap:typecheck:SWIGTYPE")) {
1458 SwigType_add_pointer(t2);
1460 Setattr(p2,"ltype",t2);
1463 /* Need subtype check here. If t2 is a subtype of t1, then we need to change the
1466 if (SwigType_issubtype(t2,t1)) {
1467 Overloaded t = nodes[i];
1468 nodes[i] = nodes[j];
1472 if (Strcmp(t1,t2) != 0) {
1476 } else if (differ) {
1479 if (Getattr(p1,"tmap:in:next")) {
1480 p1 = Getattr(p1,"tmap:in:next");
1482 p1 = nextSibling(p1);
1484 if (Getattr(p2,"tmap:in:next")) {
1485 p2 = Getattr(p2,"tmap:in:next");
1487 p2 = nextSibling(p2);
1491 /* See if declarations differ by const only */
1492 String *d1 = Getattr(nodes[i].n,"decl");
1493 String *d2 = Getattr(nodes[j].n,"decl");
1495 String *dq1 = Copy(d1);
1496 String *dq2 = Copy(d2);
1497 if (SwigType_isconst(d1)) {
1498 Delete(SwigType_pop(dq1));
1500 if (SwigType_isconst(d2)) {
1501 Delete(SwigType_pop(dq2));
1503 if (Strcmp(dq1,dq2) == 0) {
1505 if (SwigType_isconst(d1) && !SwigType_isconst(d2)) {
1506 if (script_lang_wrapping) {
1507 // Swap nodes so that the const method gets ignored (shadowed by the non-const method)
1508 Overloaded t = nodes[i];
1509 nodes[i] = nodes[j];
1513 if (!nodes[j].error) {
1514 if (script_lang_wrapping) {
1515 Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n),
1516 "Overloaded %s(%s) const ignored. Non-const method at %s:%d used.\n",
1517 Getattr(nodes[j].n,"name"), ParmList_errorstr(nodes[j].parms),
1518 Getfile(nodes[i].n), Getline(nodes[i].n));
1520 if (!Getattr(nodes[j].n, "overload:ignore"))
1521 Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
1522 "Overloaded method %s(%s) ignored. Method %s(%s) const at %s:%d used.\n",
1523 Getattr(nodes[j].n,"name"), ParmList_errorstr(nodes[j].parms),
1524 Getattr(nodes[i].n,"name"), ParmList_errorstr(nodes[i].parms),
1525 Getfile(nodes[i].n), Getline(nodes[i].n));
1529 } else if (!SwigType_isconst(d1) && SwigType_isconst(d2)) {
1531 if (!nodes[j].error) {
1532 if (script_lang_wrapping) {
1533 Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n),
1534 "Overloaded %s(%s) const ignored. Non-const method at %s:%d used.\n",
1535 Getattr(nodes[j].n,"name"), ParmList_errorstr(nodes[j].parms),
1536 Getfile(nodes[i].n), Getline(nodes[i].n));
1538 if (!Getattr(nodes[j].n, "overload:ignore"))
1539 Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
1540 "Overloaded method %s(%s) const ignored. Method %s(%s) at %s:%d used.\n",
1541 Getattr(nodes[j].n,"name"), ParmList_errorstr(nodes[j].parms),
1542 Getattr(nodes[i].n,"name"), ParmList_errorstr(nodes[i].parms),
1543 Getfile(nodes[i].n), Getline(nodes[i].n));
1554 if (!nodes[j].error) {
1555 if (script_lang_wrapping) {
1556 Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[j].n), Getline(nodes[j].n),
1557 "Overloaded method %s is shadowed by %s at %s:%d.\n",
1558 Swig_name_decl(nodes[j].n), Swig_name_decl(nodes[i].n),
1559 Getfile(nodes[i].n), Getline(nodes[i].n));
1561 if (!Getattr(nodes[j].n, "overload:ignore"))
1562 Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
1563 "Overloaded method %s ignored. Method %s at %s:%d used.\n",
1564 Swig_name_decl(nodes[j].n), Swig_name_decl(nodes[i].n),
1565 Getfile(nodes[i].n), Getline(nodes[i].n));
1574 List *result = NewList();
1577 for (i = 0; i < nnodes; i++) {
1579 Setattr(nodes[i].n, "overload:ignore", "1");
1580 Append(result,nodes[i].n);
1581 // Printf(stdout,"[ %d ] %s\n", i, ParmList_errorstr(nodes[i].parms));
1582 // Swig_print_node(nodes[i].n);
1588 void R::dispatchFunction(Node *n) {
1589 Wrapper *f = NewWrapper();
1590 String *symname = Getattr(n, "sym:name");
1591 String *nodeType = Getattr(n, "nodeType");
1592 bool constructor = (!Cmp(nodeType, "constructor"));
1594 String *sfname = NewString(symname);
1597 Replace(sfname, "new_", "", DOH_REPLACE_FIRST);
1600 "`%s` <- function(...) {", sfname);
1601 List *dispatch = Swig_overload_rank(n, true);
1602 int nfunc = Len(dispatch);
1604 "argtypes <- mapply(class, list(...))\n",
1605 "argv <- list(...)\n",
1606 "argc <- length(argtypes)\n", NIL );
1608 Printf(f->code, "# dispatch functions %d\n", nfunc);
1610 bool first_compare = true;
1611 for (int i=0; i < nfunc; i++) {
1612 Node *ni = Getitem(dispatch,i);
1613 Parm *pi = Getattr(ni,"wrap:parms");
1614 int num_arguments = emit_num_arguments(pi);
1616 String *overname = Getattr(ni,"sym:overname");
1617 if (cur_args != num_arguments) {
1618 if (cur_args != -1) {
1619 Printv(f->code, "} else ", NIL);
1621 Printf(f->code, "if (argc == %d) {", num_arguments);
1622 cur_args = num_arguments;
1623 first_compare = true;
1627 if (num_arguments > 0) {
1628 if (!first_compare) {
1629 Printv(f->code, " else ", NIL);
1631 first_compare = false;
1633 Printv(f->code, "if (", NIL);
1634 for (p =pi, j = 0 ; j < num_arguments ; j++) {
1635 String *tm = Swig_typemap_lookup("rtype", p, "", 0);
1637 replaceRClass(tm, Getattr(p, "type"));
1639 if (DohStrcmp(tm,"numeric")==0) {
1640 Printf(f->code, "%sis.numeric(argv[[%d]])",
1641 j == 0 ? "" : " && ",
1645 Printf(f->code, "%sextends(argtypes[%d], '%s')",
1646 j == 0 ? "" : " && ",
1650 p = Getattr(p, "tmap:in:next");
1652 Printf(f->code, ") { f <- %s%s }\n", sfname, overname);
1654 Printf(f->code, "f <- %s%s", sfname, overname);
1657 if (cur_args != -1) {
1658 Printv(f->code, "}", NIL);
1660 Printv(f->code, "\nf(...)", NIL);
1661 Printv(f->code, "\n}", NIL);
1662 Wrapper_print(f, sfile);
1663 Printv(sfile, "# Dispatch function\n", NIL);
1667 /******************************************************************
1669 *******************************************************************/
1670 int R::functionWrapper(Node *n) {
1671 String *fname = Getattr(n, "name");
1672 String *iname = Getattr(n, "sym:name");
1673 String *type = Getattr(n, "type");
1677 "<functionWrapper> %s %s %s\n", fname, iname, type);
1679 String *overname = 0;
1680 String *nodeType = Getattr(n, "nodeType");
1681 bool constructor = (!Cmp(nodeType, "constructor"));
1682 bool destructor = (!Cmp(nodeType, "destructor"));
1684 String *sfname = NewString(iname);
1687 Replace(sfname, "new_", "", DOH_REPLACE_FIRST);
1689 if (Getattr(n,"sym:overloaded")) {
1690 overname = Getattr(n,"sym:overname");
1691 Append(sfname, overname);
1696 "<functionWrapper> processing parameters\n");
1699 ParmList *l = Getattr(n, "parms");
1705 SwigType *resultType = Getattr(p, "type");
1706 if (expandTypedef(resultType) &&
1707 SwigType_istypedef(resultType)) {
1708 SwigType *resolved =
1709 SwigType_typedef_resolve_all(resultType);
1710 if (expandTypedef(resolved)) {
1711 Setattr(p, "type", Copy(resolved));
1717 String *unresolved_return_type =
1719 if (expandTypedef(type) &&
1720 SwigType_istypedef(type)) {
1721 SwigType *resolved =
1722 SwigType_typedef_resolve_all(type);
1723 if (expandTypedef(resolved)) {
1724 type = Copy(resolved);
1725 Setattr(n, "type", type);
1729 Printf(stderr, "<functionWrapper> unresolved_return_type %s\n",
1730 unresolved_return_type);
1731 if(processing_member_access_function) {
1733 Printf(stderr, "<functionWrapper memberAccess> '%s' '%s' '%s' '%s'\n",
1734 fname, iname, member_name, class_name);
1736 if(opaqueClassDeclaration)
1740 /* Add the name of this member to a list for this class_name.
1741 We will dump all these at the end. */
1744 char *ptr = Char(iname);
1745 bool isSet(Strcmp(NewString(&ptr[n-3]), "set") == 0);
1748 String *tmp = NewString("");
1749 Printf(tmp, "%s_%s", class_name, isSet ? "set" : "get");
1751 List *memList = Getattr(ClassMemberTable, tmp);
1753 memList = NewList();
1754 Append(memList, class_name);
1755 Setattr(ClassMemberTable, tmp, memList);
1758 Append(memList, member_name);
1759 Append(memList, iname);
1763 int nargs, num_required, varargs;
1766 String *wname = Swig_name_wrapper(iname);
1767 Replace(wname, "_wrap", "R_swig", DOH_REPLACE_FIRST);
1769 Append(wname, overname);
1770 Setattr(n,"wrap:name", wname);
1772 Wrapper *f = NewWrapper();
1773 Wrapper *sfun = NewWrapper();
1775 int isVoidReturnType = (Strcmp(type, "void") == 0);
1776 // Need to use the unresolved return type since
1777 // typedef resolution removes the const which causes a
1778 // mismatch with the function action
1779 emit_return_variable(n, unresolved_return_type, f);
1781 SwigType *rtype = Getattr(n, "type");
1782 int addCopyParam = 0;
1784 if(!isVoidReturnType)
1785 addCopyParam = addCopyParameter(rtype);
1788 // Can we get the nodeType() of the type node! and see if it is a struct.
1789 // int addCopyParam = SwigType_isclass(rtype);
1793 Printf(stderr, "Adding a .copy argument to %s for %s = %s\n",
1794 iname, type, addCopyParam ? "yes" : "no");
1796 Printv(f->def, "SWIGEXPORT SEXP\n", wname, " ( ", NIL);
1798 Printf(sfun->def, "# Start of %s\n", iname);
1799 Printv(sfun->def, "\n`", sfname, "` = function(", NIL);
1801 if(outputNamespaceInfo) //XXX Need to be a little more discriminating
1802 addNamespaceFunction(iname);
1804 Swig_typemap_attach_parms("scoercein", l, f);
1805 Swig_typemap_attach_parms("scoerceout", l, f);
1806 Swig_typemap_attach_parms("scheck", l, f);
1808 emit_parameter_variables(l, f);
1809 emit_attach_parmmaps(l,f);
1810 Setattr(n,"wrap:parms",l);
1812 nargs = emit_num_arguments(l);
1813 num_required = emit_num_required(l);
1814 varargs = emit_isvarargs(l);
1816 Wrapper_add_local(f, "r_nprotect", "unsigned int r_nprotect = 0");
1817 Wrapper_add_localv(f, "r_ans", "SEXP", "r_ans = R_NilValue", NIL);
1818 Wrapper_add_localv(f, "r_vmax", "VMAXTYPE", "r_vmax = vmaxget()", NIL);
1820 String *sargs = NewString("");
1823 String *s_inputTypes = NewString("");
1824 String *s_inputMap = NewString("");
1825 bool inFirstArg = true;
1826 bool inFirstType = true;
1828 for (p =l, i = 0 ; i < nargs ; i++) {
1830 while (checkAttribute(p, "tmap:in:numinputs", "0")) {
1831 p = Getattr(p, "tmap:in:next");
1834 SwigType *tt = Getattr(p, "type");
1836 String *funcptr_name = processType(tt, p, &nargs);
1838 // SwigType *tp = Getattr(p, "type");
1839 String *name = Getattr(p,"name");
1840 String *lname = Getattr(p,"lname");
1842 // R keyword renaming
1843 if (name && Swig_name_warning(p, 0, name, 0))
1846 /* If we have a :: in the parameter name because we are accessing a static member of a class, say, then
1847 we need to remove that prefix. */
1848 while (Strstr(name, "::")) {
1850 name = NewStringf("%s", Strchr(name, ':') + 2);
1852 Printf(stderr, "+++ parameter name with :: in it %s\n", name);
1855 name = NewStringf("s_arg%d", i+1);
1857 name = replaceInitialDash(name);
1859 if (!Strncmp(name, "arg", 3)) {
1861 Insert(name, 0, "s_");
1864 if(processing_variable) {
1866 Insert(name, 0, "s_");
1869 if(!Strcmp(name, fname)) {
1871 Insert(name, 0, "s_");
1874 Printf(sargs, "%s, ", name);
1877 if((tm = Getattr(p, "tmap:scoercein"))) {
1878 Replaceall(tm, "$input", name);
1879 replaceRClass(tm, Getattr(p, "type"));
1882 //XXX need to get this to return non-zero
1884 nargs = getFunctionPointerNumArgs(p, tt);
1886 String *snargs = NewStringf("%d", nargs);
1887 Printv(sfun->code, "if(is.function(", name, ")) {", "\n",
1888 "assert('...' %in% names(formals(", name,
1889 ")) || length(formals(", name, ")) >= ", snargs, ")\n} ", NIL);
1892 Printv(sfun->code, "else {\n",
1893 "if(is.character(", name, ")) {\n",
1894 name, " = getNativeSymbolInfo(", name, ")",
1896 "if(is(", name, ", \"NativeSymbolInfo\")) {\n",
1897 name, " = ", name, "$address", "\n}\n",
1901 Printf(sfun->code, "%s\n", tm);
1905 Printv(sfun->def, inFirstArg ? "" : ", ", name, NIL);
1907 if ((tm = Getattr(p,"tmap:scheck"))) {
1909 Replaceall(tm,"$target", lname);
1910 Replaceall(tm,"$source", name);
1911 Replaceall(tm,"$input", name);
1912 replaceRClass(tm, Getattr(p, "type"));
1913 Printf(sfun->code,"%s\n",tm);
1919 if ((tm = Getattr(p,"tmap:in"))) {
1921 Replaceall(tm,"$target", lname);
1922 Replaceall(tm,"$source", name);
1923 Replaceall(tm,"$input", name);
1925 if (Getattr(p,"wrap:disown") || (Getattr(p,"tmap:in:disown"))) {
1926 Replaceall(tm,"$disown","SWIG_POINTER_DISOWN");
1928 Replaceall(tm,"$disown","0");
1932 /* have us a function pointer */
1933 Printf(f->code, "if(TYPEOF(%s) != CLOSXP) {\n", name);
1934 Replaceall(tm,"$R_class", "");
1936 replaceRClass(tm, Getattr(p, "type"));
1940 Printf(f->code,"%s\n",tm);
1942 Printf(f->code, "} else {\n%s = %s;\nR_SWIG_pushCallbackFunctionData(%s, NULL);\n}\n",
1943 lname, funcptr_name, name);
1944 Printv(f->def, inFirstArg ? "" : ", ", "SEXP ", name, NIL);
1947 p = Getattr(p,"tmap:in:next");
1954 tm = Swig_typemap_lookup("rtype", curP, "", 0);
1956 replaceRClass(tm, Getattr(curP, "type"));
1958 Printf(s_inputTypes, "%s'%s'", inFirstType ? "" : ", ", tm);
1959 Printf(s_inputMap, "%s%s='%s'", inFirstType ? "" : ", ", name, tm);
1960 inFirstType = false;
1963 Delete(funcptr_name);
1964 } /* end of looping over parameters. */
1967 Printf(sfun->def, "%s.copy = FALSE", nargs > 0 ? ", " : "");
1968 Printf(f->def, "%sSEXP s_swig_copy", nargs > 0 ? ", " : "");
1970 Printf(sargs, "as.logical(.copy), ");
1973 Printv(f->def, ")\n{\n", NIL);
1974 Printv(sfun->def, ")\n{\n", NIL);
1977 /* Insert cleanup code */
1978 String *cleanup = NewString("");
1980 if ((tm = Getattr(p, "tmap:freearg"))) {
1981 Replaceall(tm, "$source", Getattr(p, "lname"));
1982 Printv(cleanup, tm, "\n", NIL);
1983 p = Getattr(p, "tmap:freearg:next");
1989 String *outargs = NewString("");
1990 int numOutArgs = isVoidReturnType ? -1 : 0;
1991 for(p = l, i = 0; p; i++) {
1992 if((tm = Getattr(p, "tmap:argout"))) {
1993 // String *lname = Getattr(p, "lname");
1995 String *pos = NewStringf("%d", numOutArgs);
1996 Replaceall(tm,"$source", Getattr(p, "lname"));
1997 Replaceall(tm,"$result", "r_ans");
1998 Replaceall(tm,"$n", pos); // The position into which to store the answer.
1999 Replaceall(tm,"$arg", Getattr(p, "emit:input"));
2000 Replaceall(tm,"$input", Getattr(p, "emit:input"));
2001 Replaceall(tm,"$owner", "R_SWIG_EXTERNAL");
2004 Printf(outargs, "%s\n", tm);
2005 p = Getattr(p,"tmap:argout:next");
2010 String *actioncode = emit_action(n);
2012 /* Deal with the explicit return value. */
2013 if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
2014 SwigType *retType = Getattr(n, "type");
2015 //Printf(stderr, "Return Value for %s, array? %s\n", retType, SwigType_isarray(retType) ? "yes" : "no");
2016 /* if(SwigType_isarray(retType)) {
2017 defineArrayAccessors(retType);
2021 Replaceall(tm,"$1", "result");
2022 Replaceall(tm,"$result", "r_ans");
2023 replaceRClass(tm, retType);
2025 if (GetFlag(n,"feature:new")) {
2026 Replaceall(tm, "$owner", "R_SWIG_OWNER");
2028 Replaceall(tm,"$owner", "R_SWIG_EXTERNAL");
2033 Printf(f->code, "if(LOGICAL(s_swig_copy)[0]) {\n");
2034 Printf(f->code, "/* Deal with returning a reference. */\nr_ans = R_NilValue;\n");
2035 Printf(f->code, "}\n else {\n");
2038 Printf(f->code, "%s\n", tm);
2041 Printf(f->code, "}\n"); /* end of if(s_swig_copy) ... else { ... } */
2045 Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number,
2046 "Unable to use return type %s in function %s.\n", SwigType_str(type, 0), fname);
2051 Wrapper_add_local(f, "R_OutputValues", "SEXP R_OutputValues");
2053 String *tmp = NewString("");
2054 if(!isVoidReturnType)
2055 Printf(tmp, "Rf_protect(r_ans);\n");
2057 Printf(tmp, "Rf_protect(R_OutputValues = Rf_allocVector(VECSXP,%d));\nr_nprotect += %d;\n",
2058 numOutArgs + !isVoidReturnType,
2059 isVoidReturnType ? 1 : 2);
2061 if(!isVoidReturnType)
2062 Printf(tmp, "SET_VECTOR_ELT(R_OutputValues, 0, r_ans);\n");
2063 Printf(tmp, "r_ans = R_OutputValues;\n");
2065 Insert(outargs, 0, tmp);
2070 Printv(f->code, outargs, NIL);
2075 /* Output cleanup code */
2076 Printv(f->code, cleanup, NIL);
2081 Printv(f->code, UnProtectWrapupCode, NIL);
2083 /*If the user gave us something to convert the result in */
2084 if ((tm = Swig_typemap_lookup("scoerceout", n,
2086 Replaceall(tm,"$source","ans");
2087 Replaceall(tm,"$result","ans");
2088 replaceRClass(tm, Getattr(n, "type"));
2093 Printv(sfun->code, (Len(tm) ? "ans = " : ""), ".Call('", wname,
2094 "', ", sargs, "PACKAGE='", Rpackage, "')\n", NIL);
2096 Printf(sfun->code, "%s\n\nans\n", tm);
2098 Printv(f->code, "R_ClearExternalPtr(self);\n", NIL);
2100 Printv(f->code, "return r_ans;\n}\n", NIL);
2101 Printv(sfun->code, "\n}", NIL);
2103 /* Substitute the function name */
2104 Replaceall(f->code,"$symname",iname);
2106 Wrapper_print(f, f_wrapper);
2107 Wrapper_print(sfun, sfile);
2109 Printf(sfun->code, "\n# End of %s\n", iname);
2110 tm = Swig_typemap_lookup("rtype", n, "", 0);
2112 SwigType *retType = Getattr(n, "type");
2113 replaceRClass(tm, retType);
2116 Printv(sfile, "attr(`", sfname, "`, 'returnType') = '",
2117 isVoidReturnType ? "void" : (tm ? tm : ""),
2121 Printv(sfile, "attr(`", sfname, "`, \"inputTypes\") = c(",
2122 s_inputTypes, ")\n", NIL);
2123 Printv(sfile, "class(`", sfname, "`) = c(\"SWIGFunction\", class('",
2124 sfname, "'))\n\n", NIL);
2126 if (memoryProfile) {
2127 Printv(sfile, "memory.profile()\n", NIL);
2130 Printv(sfile, "gc()\n", NIL);
2133 // Printv(sfile, "setMethod('", name, "', '", name, "', ", iname, ")\n\n\n");
2137 /* If we are dealing with a method in an C++ class, then
2138 add the name of the R function and its definition.
2139 XXX need to figure out how to store the Wrapper if possible in the hash/list.
2140 Would like to be able to do this so that we can potentialy insert
2142 if(processing_member_access_function || processing_class_member_function) {
2147 tmp = Getattr(n, "memberfunctionHandler:name");
2148 addAccessor(member_name, sfun, iname);
2151 if (Getattr(n, "sym:overloaded") &&
2152 !Getattr(n, "sym:nextSibling")) {
2153 dispatchFunction(n);
2156 addRegistrationRoutine(wname, addCopyParam ? nargs +1 : nargs);
2166 /*****************************************************
2167 Add the specified routine name to the collection of
2168 generated routines that are called from R functions.
2169 This is used to register the routines with R for
2172 rname - the name of the routine
2173 nargs - the number of arguments it expects.
2174 ******************************************************/
2175 int R::addRegistrationRoutine(String *rname, int nargs) {
2176 if(!registrationTable)
2177 registrationTable = NewHash();
2180 NewStringf("{\"%s\", (DL_FUNC) &%s, %d}", rname, rname, nargs);
2182 Setattr(registrationTable, rname, el);
2187 /*****************************************************
2188 Write the registration information to an array and
2189 create the initialization routine for registering
2191 ******************************************************/
2192 int R::outputRegistrationRoutines(File *out) {
2194 if(!registrationTable)
2197 Printf(out, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n");
2199 Printf(out, "#include <R_ext/Rdynload.h>\n\n");
2201 Printf(out, "#ifdef __cplusplus\n}\n#endif\n\n");
2203 Printf(out, "SWIGINTERN R_CallMethodDef CallEntries[] = {\n");
2205 List *keys = Keys(registrationTable);
2207 for(i = 0; i < n; i++)
2208 Printf(out, " %s,\n", Getattr(registrationTable, Getitem(keys, i)));
2210 Printf(out, " {NULL, NULL, 0}\n};\n\n");
2212 if(!noInitializationCode) {
2214 Printv(out, "extern \"C\" ", NIL);
2215 Printf(out, "SWIGEXPORT void R_init_%s(DllInfo *dll) {\n", Rpackage);
2216 Printf(out, "%sR_registerRoutines(dll, NULL, CallEntries, NULL, NULL);\n", tab4);
2217 if(Len(s_init_routine)) {
2218 Printf(out, "\n%s\n", s_init_routine);
2228 /****************************************************************************
2229 Process a struct, union or class declaration in the source code,
2230 or an anonymous typedef struct
2232 *****************************************************************************/
2233 //XXX What do we need to do here -
2234 // Define an S4 class to refer to this.
2236 void R::registerClass(Node *n) {
2237 String *name = Getattr(n, "name");
2238 String *kind = Getattr(n, "kind");
2242 String *sname = NewStringf("_p%s", SwigType_manglestr(name));
2243 if(!Getattr(SClassDefs, sname)) {
2244 Setattr(SClassDefs, sname, sname);
2247 if(Strcmp(kind, "class") == 0) {
2248 base = NewString("");
2249 List *l = Getattr(n, "bases");
2252 for(int i = 0; i < Len(l); i++) {
2253 registerClass(Getitem(l, i));
2254 Printf(base, "'_p%s'%s",
2255 SwigType_manglestr(Getattr(Getitem(l, i), "name")),
2256 i < Len(l)-1 ? ", " : "");
2260 base = NewString("'C++Reference'");
2263 base = NewString("'ExternalReference'");
2265 Printf(s_classes, "setClass('%s', contains = %s)\n", sname, base);
2271 int R::classDeclaration(Node *n) {
2273 String *name = Getattr(n, "name");
2274 String *kind = Getattr(n, "kind");
2281 /* If we have a typedef union { ... } U, then we never get to see the typedef
2282 via a regular call to typedefHandler. Instead, */
2283 if(Getattr(n, "unnamed") && Strcmp(Getattr(n, "storage"), "typedef") == 0
2284 && Getattr(n, "tdname") && Strcmp(Getattr(n, "tdname"), name) == 0) {
2286 Printf(stderr, "Typedef in the class declaration for %s\n", name);
2287 // typedefHandler(n);
2290 bool opaque = GetFlag(n, "feature:opaque") ? true : false;
2293 opaqueClassDeclaration = name;
2295 int status = Language::classDeclaration(n);
2297 opaqueClassDeclaration = NULL;
2300 // OutputArrayMethod(name, class_member_functions, sfile);
2301 if (class_member_functions)
2302 OutputMemberReferenceMethod(name, 0, class_member_functions, sfile);
2303 if (class_member_set_functions)
2304 OutputMemberReferenceMethod(name, 1, class_member_set_functions, sfile);
2306 if(class_member_functions) {
2307 Delete(class_member_functions);
2308 class_member_functions = NULL;
2310 if(class_member_set_functions) {
2311 Delete(class_member_set_functions);
2312 class_member_set_functions = NULL;
2314 if (Getattr(n, "has_destructor")) {
2315 Printf(sfile, "setMethod('delete', '_p%s', function(obj) {delete%s(obj)})\n",
2316 getRClassName(Getattr(n, "name")),
2317 getRClassName(Getattr(n, "name")));
2320 if(!opaque && !Strcmp(kind, "struct") && copyStruct) {
2323 NewStringf("setClass(\"%s\",\n%srepresentation(\n", name, tab4);
2324 bool firstItem = true;
2326 for(Node *c = firstChild(n); c; ) {
2330 elName = Getattr(c, "name");
2332 String *elKind = Getattr(c, "kind");
2333 if (Strcmp(elKind, "variable") != 0) {
2344 tp = Swig_typemap_lookup("rtype", c, "", 0);
2349 if (Strstr(tp, "R_class")) {
2353 if (Strcmp(tp, "character") &&
2354 Strstr(Getattr(c, "decl"), "p.")) {
2363 //XXX How can we tell if this is already done.
2364 // SwigType_push(elType, elDecl);
2367 // returns "" tp = processType(elType, c, NULL);
2368 // Printf(stderr, "<classDeclaration> elType %p\n", elType);
2369 // tp = getRClassNameCopyStruct(Getattr(c, "type"), 1);
2371 String *elNameT = replaceInitialDash(elName);
2372 Printf(def, "%s%s = \"%s\"", tab8, elNameT, tp);
2378 Printf(def, "),\n%scontains = \"RSWIGStruct\")\n", tab8);
2379 Printf(s_classes, "%s\n\n# End class %s\n\n", def, name);
2381 generateCopyRoutines(n);
2391 /***************************************************************
2392 Create the C routines that copy an S object of the class given
2393 by the given struct definition in Node *n to the C value
2394 and also the routine that goes from the C routine to an object
2396 ****************************************************************/
2398 Clean up the toCRef - make certain the names are correct for the types, etc.
2402 int R::generateCopyRoutines(Node *n) {
2403 Wrapper *copyToR = NewWrapper();
2404 Wrapper *copyToC = NewWrapper();
2406 String *name = Getattr(n, "name");
2407 String *tdname = Getattr(n, "tdname");
2408 String *kind = Getattr(n, "kind");
2412 type = Copy(tdname);
2414 type = NewStringf("%s %s", kind, name);
2417 String *mangledName = SwigType_manglestr(name);
2420 Printf(stderr, "generateCopyRoutines: name = %s, %s\n", name, type);
2422 Printf(copyToR->def, "CopyToR%s = function(value, obj = new(\"%s\"))\n{\n",
2424 Printf(copyToC->def, "CopyToC%s = function(value, obj)\n{\n",
2427 Node *c = firstChild(n);
2429 for(; c; c = nextSibling(c)) {
2430 String *elName = Getattr(c, "name");
2434 String *elKind = Getattr(c, "kind");
2435 if (Strcmp(elKind, "variable") != 0) {
2440 String *tp = Swig_typemap_lookup("rtype", c, "", 0);
2444 if (Strstr(tp, "R_class")) {
2447 if (Strcmp(tp, "character") &&
2448 Strstr(Getattr(c, "decl"), "p.")) {
2453 /* The S functions to get and set the member value. */
2454 String *elNameT = replaceInitialDash(elName);
2455 Printf(copyToR->code, "obj@%s = value$%s\n", elNameT, elNameT);
2456 Printf(copyToC->code, "obj$%s = value@%s\n", elNameT, elNameT);
2459 Printf(copyToR->code, "obj\n}\n\n");
2460 String *rclassName = getRClassNameCopyStruct(type, 0); // without the Ref.
2461 Printf(sfile, "# Start definition of copy functions & methods for %s\n", rclassName);
2463 Wrapper_print(copyToR, sfile);
2464 Printf(copyToC->code, "obj\n}\n\n");
2465 Wrapper_print(copyToC, sfile);
2468 Printf(sfile, "# Start definition of copy methods for %s\n", rclassName);
2469 Printf(sfile, "setMethod('copyToR', '_p_%s', CopyToR%s)\n", rclassName,
2471 Printf(sfile, "setMethod('copyToC', '%s', CopyToC%s)\n\n", rclassName,
2474 Printf(sfile, "# End definition of copy methods for %s\n", rclassName);
2475 Printf(sfile, "# End definition of copy functions & methods for %s\n", rclassName);
2477 String *m = NewStringf("%sCopyToR", name);
2478 addNamespaceMethod(m);
2479 char *tt = Char(m); tt[Len(m)-1] = 'C';
2480 addNamespaceMethod(m);
2483 Delete(mangledName);
2484 DelWrapper(copyToR);
2485 DelWrapper(copyToC);
2493 Called when there is a typedef to be invoked.
2495 XXX Needs to be enhanced or split to handle the case where we have a
2496 typedef within a classDeclaration emission because the struct/union/etc.
2499 int R::typedefHandler(Node *n) {
2500 SwigType *tp = Getattr(n, "type");
2501 String *type = Getattr(n, "type");
2503 Printf(stderr, "<typedefHandler> %s\n", Getattr(n, "name"));
2507 if(Strncmp(type, "struct ", 7) == 0) {
2508 String *name = Getattr(n, "name");
2509 char *trueName = Char(type);
2512 Printf(stderr, "<typedefHandler> Defining S class %s\n", trueName);
2513 Printf(s_classes, "setClass('_p%s', contains = 'ExternalReference')\n",
2514 SwigType_manglestr(name));
2517 return Language::typedefHandler(n);
2522 /*********************
2523 Called when processing a field in a "class", i.e. struct, union or
2524 actual class. We set a state variable so that we can correctly
2525 interpret the resulting functionWrapper() call and understand that
2526 it is for a field element.
2527 **********************/
2528 int R::membervariableHandler(Node *n) {
2529 SwigType *t = Getattr(n, "type");
2530 processType(t, n, NULL);
2531 processing_member_access_function = 1;
2532 member_name = Getattr(n,"sym:name");
2534 Printf(stderr, "<membervariableHandler> name = %s, sym:name = %s\n",
2535 Getattr(n, "name"), member_name);
2537 int status(Language::membervariableHandler(n));
2539 if(opaqueClassDeclaration == NULL && debugMode)
2540 Printf(stderr, "<membervariableHandler> %s %s\n", Getattr(n, "name"), Getattr(n, "type"));
2542 processing_member_access_function = 0;
2550 This doesn't seem to get used so leave it out for the moment.
2552 String * R::runtimeCode() {
2553 String *s = Swig_include_sys("rrun.swg");
2555 Printf(stderr, "*** Unable to open 'rrun.swg'\n");
2563 Called when SWIG wants to initialize this
2564 We initialize anythin we want here.
2565 Most importantly, tell SWIG where to find the files (e.g. r.swg) for this module.
2566 Use Swig_mark_arg() to tell SWIG that it is understood and not to throw an error.
2568 void R::main(int argc, char *argv[]) {
2569 bool cppcast = true;
2571 Preprocessor_define("SWIGR 1", 0);
2572 SWIG_library_directory("r");
2573 SWIG_config_file("r.swg");
2576 memoryProfile = false;
2577 aggressiveGc = false;
2578 inCPlusMode = false;
2579 outputNamespaceInfo = false;
2580 noInitializationCode = false;
2585 allow_overloading();// can we support this?
2587 for(int i = 0; i < argc; i++) {
2588 if(strcmp(argv[i], "-package") == 0) {
2593 } else if(strcmp(argv[i], "-dll") == 0) {
2598 } else if(strcmp(argv[i], "-help") == 0) {
2600 } else if(strcmp(argv[i], "-namespace") == 0) {
2601 outputNamespaceInfo = true;
2603 } else if(!strcmp(argv[i], "-no-init-code")) {
2604 noInitializationCode = true;
2606 } else if(!strcmp(argv[i], "-c++")) {
2609 Printf(s_classes, "setClass('C++Reference', contains = 'ExternalReference')\n");
2610 } else if(!strcmp(argv[i], "-debug")) {
2613 } else if (!strcmp(argv[i],"-cppcast")) {
2616 } else if (!strcmp(argv[i],"-nocppcast")) {
2619 } else if (!strcmp(argv[i],"-copystruct")) {
2622 } else if (!strcmp(argv[i], "-nocopystruct")) {
2625 } else if (!strcmp(argv[i], "-memoryprof")) {
2626 memoryProfile = true;
2628 } else if (!strcmp(argv[i], "-nomemoryprof")) {
2629 memoryProfile = false;
2631 } else if (!strcmp(argv[i], "-aggressivegc")) {
2632 aggressiveGc = true;
2634 } else if (!strcmp(argv[i], "-noaggressivegc")) {
2635 aggressiveGc = false;
2640 Preprocessor_define((DOH *) "SWIG_CPLUSPLUS_CAST", 0);
2642 /// copyToR copyToC functions.
2648 Could make this work for String or File and then just store the resulting string
2649 rather than the collection of arguments and argc.
2651 int R::outputCommandLineArguments(File *out)
2653 if(Argc < 1 || !Argv || !Argv[0])
2656 Printf(out, "\n## Generated via the command line invocation:\n##\t");
2657 for(int i = 0; i < Argc ; i++) {
2658 Printf(out, " %s", Argv[i]);
2660 Printf(out, "\n\n\n");
2667 /* How SWIG instantiates an object from this module.
2670 Language *swig_r(void) {
2676 /*************************************************************************************/
2679 Needs to be reworked.
2681 String * R::processType(SwigType *t, Node *n, int *nargs) {
2682 //XXX Need to handle typedefs, e.g.
2683 // a type which is a typedef to a function pointer.
2685 SwigType *tmp = Getattr(n, "tdname");
2687 Printf(stderr, "processType %s (tdname = %s)\n", Getattr(n, "name"), tmp);
2690 if (expandTypedef(t) &&
2691 SwigType_istypedef(t)) {
2692 SwigType *resolved =
2693 SwigType_typedef_resolve_all(t);
2694 if (expandTypedef(resolved)) {
2695 td = Copy(resolved);
2701 String *b = getRTypeName(t, &count);
2702 if(count && b && !Getattr(SClassDefs, b)) {
2704 Printf(stderr, "<processType> Defining class %s\n", b);
2706 Printf(s_classes, "setClass('%s', contains = 'ExternalReference')\n", b);
2707 Setattr(SClassDefs, b, b);
2716 if(SwigType_isfunctionpointer(t)) {
2719 "<processType> Defining pointer handler %s\n", t);
2721 String *tmp = createFunctionPointerHandler(t, n, nargs);
2726 SwigType_isfunction(t) && SwigType_ispointer(t)
2740 /*************************************************************************************/