| #include "swigmod.h" |
| #include <ctype.h> |
| |
| class OBJECTIVEC:public Language { |
| private: |
| /* Files and file sections containing generated code. */ |
| File *f_wrap_h; // Wrapper header file |
| File *f_wrap_mm; // Wrapper source file |
| File *f_proxy_h; // Proxy header file |
| File *f_proxy_mm; // Proxy source file |
| File *f_runtime; |
| File *f_header; /* General DOH objects used for holding the sections of wrapper source */ |
| File *f_wrappers; |
| File *f_init; |
| |
| /* Strings temporarily holding the generated C++ code. */ |
| String *wrap_h_code; // Code to be written in wrap_h. |
| String *wrap_mm_code; // Code to be written in wrap_mm. |
| String *proxy_h_code; // Code to be written in proxy_h. |
| String *proxy_mm_code; // Code to be written in proxy_mm. |
| String *swigtypes_h_code; // Code for Objective-C typewrapper classes header. |
| String *swigtypes_mm_code; // Code for Objective-C typewrapper classes implementation. |
| |
| |
| /* Various flags controlling the code generation. */ |
| bool proxy_flag; // flag: determine should the proxy files be generated or not |
| |
| /* State variables which indicate what is being wrapped at the moment. */ |
| bool member_variable_flag; // flag: wrapping member variables |
| bool static_member_variable_flag; // flag: wrapping static member variables |
| bool global_variable_flag; // flag: wrapping global variables |
| bool global_func_flag; // flag: wrapping global functions |
| bool static_member_func_flag; // flag: wrapping static member functions |
| bool member_func_flag; // flag: wrapping member functions |
| bool member_constant_flag; // flag: wrapping member constants |
| |
| /* Helper strings used in the code */ |
| String *current_class_name; // String representing name of the current class. |
| String *current_class_type; // Current class when used as a type. This represents the complete name of the class including the scope prefix |
| String *variable_name; // String representing the current variable name. |
| String *proxyfuncname; // String representing the current memberfunction name. |
| |
| /* ObjectiveC data for the current proxy class: |
| * These strings are mainly used to temporarily accumulate code from the |
| * various member handling functions while a single class is processed and are |
| * no longer relevant once that class has been finished, i.e. after |
| * classHandler() has returned. */ |
| String *proxy_class_name; // The unqualified name of the current proxy class. |
| String *proxy_class_qname; // The name of the current proxy class, qualified with the name of the namespace it is in, if any. |
| // TODO: Add this when nspaces are handled. Not now! |
| |
| String *proxy_class_decl_code; // The proxy class declaration code.This goes in the proxy_h file if proxy_flag is true. |
| String *proxy_class_defn_code; // The proxy class definition code.This goes in the proxy_mm file if proxy_flag is true. |
| String *proxy_class_imports; // The import directives for the current proxy class. This goes in the proxy_h file if proxy_flag is true. |
| |
| String *proxy_class_enums_code; // Code for enumerations nested in the current proxy class. Is emitted globally and earlier |
| // than the rest of the body to work around forward referencing-issues. |
| |
| String *proxy_class_function_decls; // Code for the proxy class member functions declaration. |
| String *proxy_class_function_defns; // Code for the proxy class member functions definition. |
| String *proxy_global_function_decls; // Code for the proxy class member functions declaration. |
| String *proxy_global_function_defns; // Code for the proxy class member functions definition. |
| String *destrcutor_call; // Contains an ObjectiveC call to the function wrapping the C++ destructor of the |
| // current class (if there is a public C++ destructor). |
| |
| |
| /* SWIG types data: Collects information about encountered types SWIG does not know about (e.g. |
| * incomplete types). This is used later to generate type wrapper proxy. |
| * classes for the unknown types. */ |
| Hash *unknown_types; |
| |
| /* Strings used at different places in the code. */ |
| static const char *const usage; // Usage message |
| const String *empty_string; // Empty string used at different places in the code |
| |
| |
| public: |
| OBJECTIVEC():f_wrap_h(NULL), |
| f_wrap_mm(NULL), |
| f_proxy_h(NULL), |
| f_proxy_mm(NULL), |
| f_runtime(NULL), |
| f_header(NULL), |
| f_wrappers(NULL), |
| f_init(NULL), |
| wrap_h_code(NULL), |
| wrap_mm_code(NULL), |
| proxy_h_code(NULL), |
| proxy_mm_code(NULL), |
| swigtypes_h_code(NULL), |
| swigtypes_mm_code(NULL), |
| proxy_flag(true), |
| member_variable_flag(false), |
| static_member_variable_flag(false), |
| global_variable_flag(false), |
| global_func_flag(false), |
| static_member_func_flag(false), |
| member_func_flag(false), |
| member_constant_flag(false), |
| current_class_name(NULL), |
| current_class_type(NULL), |
| variable_name(NULL), |
| proxyfuncname(NULL), |
| proxy_class_name(NULL), |
| proxy_class_qname(NULL), |
| proxy_class_decl_code(NULL), |
| proxy_class_defn_code(NULL), |
| proxy_class_imports(NULL), |
| proxy_class_enums_code(NULL), |
| proxy_class_function_decls(NULL), |
| proxy_class_function_defns(NULL), |
| proxy_global_function_decls(NULL), proxy_global_function_defns(NULL), destrcutor_call(NULL), unknown_types(NULL), empty_string(NewString("")) { |
| } virtual void main(int argc, char *argv[]); |
| virtual int top(Node *n); |
| |
| /* Function handlers */ |
| virtual int functionHandler(Node *n); |
| virtual int globalfunctionHandler(Node *n); |
| virtual int memberfunctionHandler(Node *n); |
| virtual int staticmemberfunctionHandler(Node *n); |
| virtual int callbackfunctionHandler(Node *n); |
| |
| /* Variable handlers */ |
| virtual int variableHandler(Node *n); |
| virtual int globalvariableHandler(Node *n); |
| virtual int membervariableHandler(Node *n); |
| virtual int staticmembervariableHandler(Node *n); |
| |
| /* C++ handlers */ |
| virtual int memberconstantHandler(Node *n); |
| virtual int constructorHandler(Node *n); |
| virtual int copyconstructorHandler(Node *n); |
| virtual int destructorHandler(Node *n); |
| virtual int classHandler(Node *n); |
| |
| /* C/C++ Parsing */ |
| virtual int enumDeclaration(Node *n); |
| virtual int enumvalueDeclaration(Node *n); |
| |
| /* Low-level code generation */ |
| virtual int constantWrapper(Node *n); |
| virtual int variableWrapper(Node *n); |
| virtual int functionWrapper(Node *n); |
| virtual int nativeWrapper(Node *n); |
| |
| /* Proxy class code generators */ |
| void emitProxyGlobalFunctions(Node *n); |
| void emitProxyClassFunction(Node *n); |
| void emitProxyClassConstructor(Node *n); |
| void emitProxyClass(Node *n); |
| void emitTypeWrapperClass(String *classname, SwigType *type); |
| |
| /* Helper functions */ |
| bool substituteClassname(String *tm, SwigType *pt); |
| void substituteClassnameVariable(String *tm, const char *classnamevariable, SwigType *type); |
| Parm *skipIgnoredArgs(Parm *p); |
| void marshalInputArgs(ParmList *parmlist, Wrapper *wrapper); |
| void makeParameterList(ParmList *parmlist, Wrapper *wrapper); |
| String *makeParameterName(Node *n, Parm *p, int arg_num, bool setter) const; |
| void marshalOutput(Node *n, String *actioncode, Wrapper *wrapper); |
| String *createProxyName(SwigType *t); |
| const String *typemapLookup(Node *n, const_String_or_char_ptr tmap_method, SwigType *type, int warning, Node *typemap_attributes = 0); |
| }; |
| |
| /* --------------------------------------------------------------------- |
| * main() |
| * |
| * Entry point for the Objective-C module. |
| * --------------------------------------------------------------------- */ |
| |
| void OBJECTIVEC::main(int argc, char *argv[]) { |
| // Set language-specific subdirectory in SWIG library |
| SWIG_library_directory("objc"); |
| |
| // Process command line options |
| for (int i = 1; i < argc; i++) { |
| if (argv[i]) { |
| if (strcmp(argv[i], "-noproxy") == 0) { |
| Swig_mark_arg(i); |
| proxy_flag = false; |
| } else if (strcmp(argv[i], "-help") == 0) { |
| Printf(stdout, "%s\n", usage); |
| } |
| } |
| } |
| |
| // Set language-specific preprocessing symbol |
| Preprocessor_define("SWIGOBJECTIVEC 1", 0); |
| |
| // Set language-specific configuration file |
| SWIG_config_file("objc.swg"); |
| |
| // Set typemap language (historical) |
| SWIG_typemap_lang("objc"); |
| } |
| |
| /* --------------------------------------------------------------------- |
| * top() |
| * |
| * Function handler for processing top node of the parse tree |
| * Wrapper code generation starts from here. |
| * --------------------------------------------------------------------- */ |
| |
| int OBJECTIVEC::top(Node *n) { |
| /* Get the module name */ |
| String *module = Getattr(n, "name"); |
| |
| /* Initialize I/O */ |
| |
| // Create the _wrap files |
| String *wrapfile_h = NewStringf("%s_wrap.h", module); |
| f_wrap_h = NewFile(wrapfile_h, "w", SWIG_output_files()); |
| if (!f_wrap_h) { |
| FileErrorDisplay(wrapfile_h); |
| SWIG_exit(EXIT_FAILURE); |
| } |
| String *wrapfile_mm = NewStringf("%s_wrap.mm", module); |
| f_wrap_mm = NewFile(wrapfile_mm, "w", SWIG_output_files()); |
| if (!f_wrap_mm) { |
| FileErrorDisplay(wrapfile_mm); |
| SWIG_exit(EXIT_FAILURE); |
| } |
| Delete(wrapfile_h); |
| Delete(wrapfile_mm); |
| |
| // Create the _proxy files if proxy flag is true |
| if (proxy_flag) { |
| String *proxyfile_h = NewStringf("%s_proxy.h", module); |
| f_proxy_h = NewFile(proxyfile_h, "w", SWIG_output_files()); |
| if (!f_proxy_h) { |
| FileErrorDisplay(proxyfile_h); |
| SWIG_exit(EXIT_FAILURE); |
| } |
| String *proxyfile_mm = NewStringf("%s_proxy.mm", module); |
| f_proxy_mm = NewFile(proxyfile_mm, "w", SWIG_output_files()); |
| if (!f_proxy_mm) { |
| FileErrorDisplay(proxyfile_mm); |
| SWIG_exit(EXIT_FAILURE); |
| } |
| Delete(proxyfile_h); |
| Delete(proxyfile_mm); |
| } |
| |
| f_runtime = NewString(""); |
| f_init = NewString(""); |
| f_header = NewString(""); |
| f_wrappers = NewString(""); |
| |
| |
| // Register file targets with the SWIG file handler |
| Swig_register_filebyname("begin", f_wrap_mm); |
| Swig_register_filebyname("header", f_header); |
| Swig_register_filebyname("wrapper", f_wrappers); |
| Swig_register_filebyname("runtime", f_runtime); |
| Swig_register_filebyname("init", f_init); |
| |
| // Output module initialization code |
| Swig_banner(f_wrap_h); |
| Printf(f_wrap_h, "\n"); |
| Printf(f_wrap_h, "#ifndef %(upper)s_WRAP_H\n", module); |
| Printf(f_wrap_h, "#define %(upper)s_WRAP_H\n\n", module); |
| Printf(f_wrap_h, "\n#ifdef __cplusplus\n"); |
| Printf(f_wrap_h, "extern \"C\" {\n"); |
| Printf(f_wrap_h, "#endif\n\n"); |
| |
| Swig_banner(f_wrap_mm); |
| Printf(f_header, "#include \"%s_wrap.h\"\n", module); |
| |
| if (proxy_flag) { |
| Swig_banner(f_proxy_h); |
| Printf(f_proxy_h, "\n#import <Foundation/Foundation.h>\n\n"); |
| |
| // ObjectiveC will understand the C code. |
| Printf(f_proxy_h, "\n#ifdef __cplusplus\n"); |
| Printf(f_proxy_h, "extern \"C\" {\n"); |
| Printf(f_proxy_h, "#endif\n\n"); |
| |
| Swig_banner(f_proxy_mm); |
| Printf(f_proxy_mm, "#include \"%s_proxy.h\"\n", module); |
| Printf(f_proxy_mm, "#include \"%s_wrap.h\"\n\n", module); |
| } |
| // Create strings for holding the generated code. These will be dumped |
| // to the generated files at the end of the top function. |
| wrap_h_code = NewString(""); |
| wrap_mm_code = NewString(""); |
| if (proxy_flag) { |
| proxy_h_code = NewString(""); |
| proxy_mm_code = NewString(""); |
| swigtypes_h_code = NewString(""); |
| swigtypes_mm_code = NewString(""); |
| |
| proxy_class_decl_code = NewString(""); |
| proxy_class_defn_code = NewString(""); |
| proxy_class_enums_code = NewString(""); |
| proxy_class_function_decls = NewString(""); |
| proxy_class_function_defns = NewString(""); |
| proxy_global_function_decls = NewString(""); |
| proxy_global_function_defns = NewString(""); |
| proxy_class_imports = NewString(""); |
| |
| destrcutor_call = NewString(""); |
| unknown_types = NewHash(); |
| } |
| |
| /* Emit code for children */ |
| Language::top(n); |
| |
| // Write to the wrap_h |
| Dump(wrap_h_code, f_wrap_h); |
| Printf(f_wrap_h, "\n#ifdef __cplusplus\n"); |
| Printf(f_wrap_h, "}\n"); |
| Printf(f_wrap_h, "#endif\n"); |
| Printf(f_wrap_h, "\n#endif\n\n"); |
| |
| // Write to the wrap_mm |
| Dump(f_runtime, f_wrap_mm); |
| Dump(f_header, f_wrap_mm); |
| Printf(f_wrap_mm, "\n#ifdef __cplusplus\n"); |
| Printf(f_wrap_mm, "extern \"C\" {\n"); |
| Printf(f_wrap_mm, "#endif\n\n"); |
| Dump(f_wrappers, f_wrap_mm); |
| Dump(wrap_mm_code, f_wrap_mm); |
| Wrapper_pretty_print(f_init, f_wrap_mm); |
| Printf(f_wrap_mm, "\n#ifdef __cplusplus\n"); |
| Printf(f_wrap_mm, "}\n"); |
| Printf(f_wrap_mm, "#endif\n"); |
| |
| // Write to the proxy.h, if required |
| if (proxy_flag) { |
| |
| for (Iterator swig_type = First(unknown_types); swig_type.key; swig_type = Next(swig_type)) { |
| emitTypeWrapperClass(swig_type.key, swig_type.item); |
| } |
| |
| Dump(swigtypes_h_code, f_proxy_h); |
| Dump(proxy_h_code, f_proxy_h); |
| Printf(f_proxy_h, "\n#ifdef __cplusplus\n"); |
| Printf(f_proxy_h, "}\n"); |
| Printf(f_proxy_h, "#endif\n\n"); |
| } |
| // Write to proxy.mm, if required |
| if (proxy_flag) { |
| // Printf(f_proxy_mm, "\n#ifdef __cplusplus\n"); |
| // Printf(f_proxy_mm, "extern \"C\" {\n"); |
| // Printf(f_proxy_mm, "#endif\n\n"); |
| Dump(swigtypes_mm_code, f_proxy_mm); |
| Dump(proxy_mm_code, f_proxy_mm); |
| // Printf(f_proxy_mm, "\n#ifdef __cplusplus\n"); |
| // Printf(f_proxy_mm, "}\n"); |
| // Printf(f_proxy_mm, "#endif\n"); |
| } |
| // Cleanup |
| Delete(wrap_h_code); |
| Delete(wrap_mm_code); |
| Close(f_wrap_h); |
| Close(f_wrap_mm); |
| Delete(f_runtime); |
| Delete(f_init); |
| Delete(f_header); |
| Delete(f_wrappers); |
| Delete(f_wrap_h); |
| Delete(f_wrap_mm); |
| |
| if (proxy_flag) { |
| Delete(proxy_class_decl_code); |
| Delete(proxy_class_defn_code); |
| Delete(proxy_class_enums_code); |
| Delete(proxy_class_function_decls); |
| Delete(proxy_class_function_defns); |
| Delete(proxy_global_function_decls); |
| Delete(proxy_global_function_defns); |
| Delete(proxy_class_imports); |
| Delete(destrcutor_call); |
| Delete(unknown_types); |
| |
| Delete(swigtypes_h_code); |
| Delete(swigtypes_mm_code); |
| Delete(proxy_h_code); |
| Delete(proxy_mm_code); |
| Close(f_proxy_h); |
| Close(f_proxy_mm); |
| Delete(f_proxy_h); |
| Delete(f_proxy_mm); |
| } |
| |
| return SWIG_OK; |
| } |
| |
| /* --------------------------------------------------------------------- |
| * functionHandler() |
| * |
| * Function handler for generating wrappers for functions |
| * --------------------------------------------------------------------- */ |
| |
| int OBJECTIVEC::functionHandler(Node *n) { |
| Language::functionHandler(n); |
| return SWIG_OK; |
| } |
| |
| /* --------------------------------------------------------------------- |
| * globalfunctionHandler() |
| * |
| * Function handler for generating wrappers for functions |
| * --------------------------------------------------------------------- */ |
| |
| int OBJECTIVEC::globalfunctionHandler(Node *n) { |
| global_func_flag = true; |
| Language::globalfunctionHandler(n); |
| global_func_flag = false; |
| |
| return SWIG_OK; |
| } |
| |
| /* --------------------------------------------------------------------- |
| * memberfunctionHandler() |
| * |
| * Function handler for generating wrappers for functions |
| * --------------------------------------------------------------------- */ |
| |
| int OBJECTIVEC::memberfunctionHandler(Node *n) { |
| String *symname = Getattr(n, "sym:name"); |
| proxyfuncname = symname; |
| member_func_flag = true; |
| Language::memberfunctionHandler(n); |
| member_func_flag = false; |
| |
| return SWIG_OK; |
| } |
| |
| /* --------------------------------------------------------------------- |
| * staticmemberfunctionHandler() |
| * |
| * Function handler for generating wrappers for functions |
| * --------------------------------------------------------------------- */ |
| |
| int OBJECTIVEC::staticmemberfunctionHandler(Node *n) { |
| String *symname = Getattr(n, "sym:name"); |
| proxyfuncname = symname; |
| static_member_func_flag = true; |
| Language::staticmemberfunctionHandler(n); |
| static_member_func_flag = false; |
| |
| return SWIG_OK; |
| } |
| |
| /* --------------------------------------------------------------------- |
| * callbackfunctionHandler() |
| * |
| * Function handler for generating wrappers for functions |
| * --------------------------------------------------------------------- */ |
| |
| int OBJECTIVEC::callbackfunctionHandler(Node *n) { |
| Language::callbackfunctionHandler(n); |
| return SWIG_OK; |
| } |
| |
| /* --------------------------------------------------------------------- |
| * variableHandler() |
| * |
| * Function handler for generating wrappers for functions |
| * --------------------------------------------------------------------- */ |
| |
| int OBJECTIVEC::variableHandler(Node *n) { |
| Language::variableHandler(n); |
| return SWIG_OK; |
| } |
| |
| /* --------------------------------------------------------------------- |
| * globalvariableHandler() |
| * |
| * Function handler for generating wrappers for functions |
| * --------------------------------------------------------------------- */ |
| |
| int OBJECTIVEC::globalvariableHandler(Node *n) { |
| String *symname = Getattr(n, "sym:name"); |
| variable_name = symname; |
| global_variable_flag = true; |
| |
| Language::globalvariableHandler(n); |
| |
| global_variable_flag = false; |
| return SWIG_OK; |
| } |
| |
| /* --------------------------------------------------------------------- |
| * membervariableHandler() |
| * |
| * Function handler for generating wrappers for functions |
| * --------------------------------------------------------------------- */ |
| |
| int OBJECTIVEC::membervariableHandler(Node *n) { |
| String *symname = Getattr(n, "sym:name"); |
| variable_name = symname; |
| member_variable_flag = true; |
| |
| Language::membervariableHandler(n); |
| |
| member_variable_flag = false; |
| return SWIG_OK; |
| } |
| |
| /* --------------------------------------------------------------------- |
| * staticmembervariableHandler() |
| * |
| * Function handler for generating wrappers for functions |
| * --------------------------------------------------------------------- */ |
| |
| int OBJECTIVEC::staticmembervariableHandler(Node *n) { |
| String *symname = Getattr(n, "sym:name"); |
| variable_name = symname; |
| static_member_variable_flag = true; |
| |
| Language::staticmembervariableHandler(n); |
| |
| static_member_variable_flag = false; |
| return SWIG_OK; |
| } |
| |
| /* --------------------------------------------------------------------- |
| * memberconstantHandler() |
| * |
| * Function handler for generating wrappers for functions |
| * --------------------------------------------------------------------- */ |
| |
| int OBJECTIVEC::memberconstantHandler(Node *n) { |
| String *symname = Getattr(n, "sym:name"); |
| variable_name = symname; |
| member_constant_flag = true; |
| |
| Language::memberconstantHandler(n); |
| |
| member_constant_flag = false; |
| return SWIG_OK; |
| } |
| |
| /* --------------------------------------------------------------------- |
| * constructorHandler() |
| * |
| * Function handler for generating wrappers for functions |
| * --------------------------------------------------------------------- */ |
| |
| int OBJECTIVEC::constructorHandler(Node *n) { |
| Language::constructorHandler(n); |
| return SWIG_OK; |
| } |
| |
| /* --------------------------------------------------------------------- |
| * copyconstructorHandler() |
| * |
| * Function handler for generating wrappers for functions |
| * --------------------------------------------------------------------- */ |
| |
| int OBJECTIVEC::copyconstructorHandler(Node *n) { |
| Language::copyconstructorHandler(n); |
| return SWIG_OK; |
| } |
| |
| /* --------------------------------------------------------------------- |
| * destructorHandler() |
| * |
| * Function handler for generating wrappers for functions |
| * --------------------------------------------------------------------- */ |
| |
| int OBJECTIVEC::destructorHandler(Node *n) { |
| Language::destructorHandler(n); |
| String *symname = Getattr(n, "sym:name"); |
| Printv(destrcutor_call, Swig_name_wrapper(Swig_name_destroy(getNSpace(), symname)), "((void*)swigCPtr)", NIL); |
| return SWIG_OK; |
| } |
| |
| /* --------------------------------------------------------------------- |
| * classHandler() |
| * |
| * Function handler for generating wrappers for functions |
| * --------------------------------------------------------------------- */ |
| |
| int OBJECTIVEC::classHandler(Node *n) { |
| if (proxy_flag) { |
| proxy_class_name = Copy(Getattr(n, "sym:name")); |
| |
| if (!addSymbol(proxy_class_name, n)) |
| return SWIG_ERROR; |
| |
| Clear(proxy_class_imports); |
| Clear(proxy_class_function_decls); |
| Clear(proxy_class_function_defns); |
| Clear(proxy_global_function_decls); |
| Clear(proxy_global_function_defns); |
| Clear(proxy_class_enums_code); |
| Clear(proxy_class_decl_code); |
| Clear(proxy_class_defn_code); |
| Clear(destrcutor_call); |
| } |
| |
| Language::classHandler(n); |
| |
| if (proxy_flag) { |
| // Write the code for proxy class |
| emitProxyClass(n); |
| |
| // Apply the necessary substitutions |
| Replaceall(proxy_class_decl_code, "$objcclassname", proxy_class_name); |
| Replaceall(proxy_class_defn_code, "$objcclassname", proxy_class_name); |
| |
| // And, dump everything to the proxy files |
| Printv(proxy_h_code, proxy_class_decl_code, NIL); |
| Printv(proxy_mm_code, proxy_class_defn_code, NIL); |
| Printv(proxy_h_code,proxy_global_function_decls,NIL); |
| Printv(proxy_mm_code,proxy_global_function_defns,NIL); |
| // Tidy up |
| Delete(proxy_class_qname); |
| proxy_class_qname = NULL; |
| Delete(proxy_class_name); |
| proxy_class_name = NULL; |
| } |
| |
| return SWIG_OK; |
| } |
| |
| /* ---------------------------------------------------------------------- |
| * enumDeclaration() |
| * |
| * Wraps C/C++ enums as Objective C enums |
| * ---------------------------------------------------------------------- */ |
| |
| int OBJECTIVEC::enumDeclaration(Node *n) { |
| if (ImportMode) |
| return SWIG_OK; |
| |
| if (getCurrentClass() && (cplus_mode != PUBLIC)) |
| return SWIG_NOWRAP; |
| |
| String *typemap_lookup_type = Getattr(n, "name"); |
| String *symname = Getattr(n, "sym:name"); |
| String *enumname; |
| |
| Node *p = parentNode(n); |
| if (p && !Strcmp(nodeType(p), "class")) { // This is a nested enum, prefix the class name |
| String *parentname = Getattr(p, "sym:name"); |
| enumname = NewStringf("%s_%s", parentname, symname); |
| } else { |
| enumname = Copy(symname); |
| } |
| |
| if (proxy_flag) { |
| if (typemap_lookup_type) { |
| // Copy-paste the C/C++ enum as an Objective-C enum |
| Printv(proxy_h_code, "enum ", enumname, " {\n", NIL); |
| } else { |
| // Handle anonymous enums. |
| Printv(proxy_h_code, "\nenum {\n", NIL); |
| } |
| } |
| // Emit each enum item |
| Language::enumDeclaration(n); |
| |
| if (!GetFlag(n, "nonempty")) { |
| // Do not wrap empty enums; |
| return SWIG_NOWRAP; |
| } |
| |
| if (proxy_flag) { |
| if (typemap_lookup_type) { |
| // Finish the enum declaration |
| Printv(proxy_h_code, "\n};\n\n", NIL); |
| } else { |
| // Handle anonymous enums. |
| Printv(proxy_h_code, "\n};\n\n", NIL); |
| } |
| } |
| |
| Delete(enumname); |
| return SWIG_OK; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| * enumvalueDeclaration() |
| * |
| * Genrerates the enum item for the Objective C enums |
| * --------------------------------------------------------------------------- */ |
| int OBJECTIVEC::enumvalueDeclaration(Node *n) { |
| if (getCurrentClass() && (cplus_mode != PUBLIC)) |
| return SWIG_NOWRAP; |
| |
| Swig_require("enumvalueDeclaration", n, "*name", "?value", NIL); |
| String *symname = Getattr(n, "sym:name"); |
| String *value = Getattr(n, "enumvalue"); |
| Node *parent = parentNode(n); |
| Node *pparent = parentNode(parent); |
| String *enumname; |
| if (pparent && !Strcmp(nodeType(pparent), "class")) { // This is a nested enum, prefix the class name |
| String *classname = Getattr(pparent, "sym:name"); |
| enumname = NewStringf("%s_%s", classname, symname); |
| } else { |
| enumname = Copy(symname); |
| } |
| if (proxy_flag) { // Emit the enum item |
| if (!GetFlag(n, "firstenumitem")) |
| Printf(proxy_h_code, ",\n"); |
| Printf(proxy_h_code, " %s", enumname); |
| if (value) { |
| value = Getattr(n, "enumvalue") ? Copy(Getattr(n, "enumvalue")) : Copy(Getattr(n, "enumvalueex")); |
| Printf(proxy_h_code, " = %s", value); |
| } |
| } |
| // Keep track that the currently processed enum has at least one value |
| SetFlag(parent, "nonempty"); |
| |
| Swig_restore(n); |
| Delete(enumname); |
| return SWIG_OK; |
| } |
| |
| /* --------------------------------------------------------------------- |
| * constantWrapper() |
| * |
| * Low level code generator for constants |
| * --------------------------------------------------------------------- */ |
| |
| int OBJECTIVEC::constantWrapper(Node *n) { |
| SwigType *type = Getattr(n, "type"); |
| String *symname = Getattr(n, "sym:name"); |
| String *value = Getattr(n, "value"); |
| String *typestring = SwigType_str(type, 0); |
| String *tm; |
| |
| String *crettype = NewString(""); |
| String *constants_h_code = NewString(""); |
| String *constants_mm_code = NewString(""); |
| bool is_func_ptr = SwigType_isfunctionpointer(type); |
| |
| if (!addSymbol(symname, n)) |
| return SWIG_ERROR; |
| |
| // Get the corresponding ObjectiveC type or the intermediate type. "imtype" if no proxy and "objctype" if proxy_flag is true. |
| if (!is_func_ptr) { |
| if (proxy_flag) { |
| if ((tm = Swig_typemap_lookup("objctype", n, "", 0))) { |
| substituteClassname(tm, type); |
| Printf(crettype, "%s", tm); |
| } else { |
| Swig_warning(WARN_OBJC_TYPEMAP_OBJCTYPE_UNDEF, input_file, line_number, "No objctype typemap defined for %s\n", typestring); |
| } |
| } else { |
| if ((tm = Swig_typemap_lookup("imtype", n, "", 0))) { |
| Printf(crettype, "%s", tm); |
| } else { |
| Swig_warning(WARN_OBJC_TYPEMAP_IMTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", typestring); |
| } |
| } |
| } else { |
| if (proxy_flag) { |
| if ((tm = Swig_typemap_lookup("objctype", n, "", 0))) { |
| substituteClassname(tm, type); |
| Printf(crettype, "%s", tm); |
| } else { |
| Swig_warning(WARN_OBJC_TYPEMAP_OBJCTYPE_UNDEF, input_file, line_number, "No objctype typemap defined for %s\n", typestring); |
| } |
| } else { |
| Printf(crettype, "%s", SwigType_str(type, symname)); |
| } |
| } |
| |
| if (is_func_ptr) { |
| variableWrapper(n); |
| Printf(constants_h_code, "extern %s %s;\n", crettype, symname); |
| //Printf(constants_mm_code, "%s %s = (%s)%s();\n", crettype, symname, typestring, Swig_name_wrapper(Swig_name_get(getNSpace(), symname))); |
| // Transform return type used in low level accessor to the type used in Objective-C constant definition |
| String *imcall = NewStringf("%s()", Swig_name_wrapper(Swig_name_get(getNSpace(), symname))); |
| if ((tm = Swig_typemap_lookup("objcvarout", n, "", 0))) { |
| substituteClassname(tm, type); |
| Replaceall(tm, "$objcvarname", symname); |
| Replaceall(tm, "$imcall", imcall); |
| } else { |
| Swig_warning(WARN_OBJC_TYPEMAP_OBJCOUT_UNDEF, input_file, line_number, "No objcout typemap defined for %s\n", crettype); |
| } |
| Printf(constants_mm_code, "%s\n", tm); |
| Delete(imcall); |
| }else if (Getattr(n, "wrappedasconstant")) { |
| if (SwigType_type(type) == T_CHAR){ |
| Printf(constants_mm_code, "%s %s= \'%s\';\n", crettype, symname, Getattr(n, "staticmembervariableHandler:value")); |
| } |
| else if (SwigType_type(type) == T_STRING){ |
| Printf(constants_mm_code, "%s const %s= @\"%s\";\n", crettype, symname, Getattr(n, "staticmembervariableHandler:value")); |
| } else { |
| Printf(constants_mm_code, "%s %s= %s;\n", crettype, symname, Getattr(n, "staticmembervariableHandler:value")); |
| } |
| } else { |
| if (SwigType_type(type) == T_STRING) { |
| // http://stackoverflow.com/questions/538996/constants-in-objective-c/539191#539191 |
| Printf(constants_h_code, "extern %s const %s;\n", crettype, symname); |
| Printf(constants_mm_code, "%s const %s= @\"%s\";\n", crettype, symname, value); |
| } else if (SwigType_type(type) == T_CHAR) { |
| Printf(constants_h_code, "extern %s %s;\n", crettype, symname); |
| Printf(constants_mm_code, "%s %s= \'%s\';\n", crettype, symname, value); |
| } else { |
| Printf(constants_h_code, "extern %s %s;\n", crettype, symname); |
| Printf(constants_mm_code, "%s %s= %s;\n", crettype, symname, value); |
| } |
| } |
| |
| // Dump to generated files |
| if (proxy_flag) { // write to the proxy files |
| Printv(proxy_h_code, constants_h_code, NIL); |
| Printv(proxy_mm_code, constants_mm_code, NIL); |
| } else { // write to the wrap files |
| Printv(wrap_h_code, constants_h_code, NIL); |
| Printv(wrap_mm_code, constants_mm_code, NIL); |
| } |
| |
| // Cleanup |
| Delete(crettype); |
| Delete(constants_h_code); |
| Delete(constants_mm_code); |
| return SWIG_OK; |
| } |
| |
| /* --------------------------------------------------------------------- |
| * variableWrapper() |
| * |
| * Low level code generator for variables |
| * --------------------------------------------------------------------- */ |
| |
| int OBJECTIVEC::variableWrapper(Node *n) { |
| Language::variableWrapper(n); |
| return SWIG_OK; |
| } |
| |
| /* --------------------------------------------------------------------- |
| * functionWrapper() |
| * |
| * |
| * Generates the C wrapper code for a function and the corresponding |
| * declaration in the wrap files |
| * --------------------------------------------------------------------- */ |
| |
| int OBJECTIVEC::functionWrapper(Node *n) { |
| // Get some useful attributes of this function |
| String *symname = Getattr(n, "sym:name"); |
| SwigType *type = Getattr(n, "type"); |
| ParmList *parmlist = Getattr(n, "parms"); |
| String *crettype = SwigType_str(type, 0); |
| String *imrettype = NewString(""); |
| String *tm; |
| bool is_void_return = (Cmp(crettype, "void") == 0); |
| bool is_constructor = (Cmp(nodeType(n), "constructor") == 0); |
| bool is_destructor = (Cmp(nodeType(n), "destructor") == 0); |
| bool is_constant = (Cmp(nodeType(n), "constant") == 0); |
| |
| if (!Getattr(n, "sym:overloaded")) { |
| if (!addSymbol(Getattr(n, "sym:name"), n)) |
| return SWIG_ERROR; |
| } |
| // Create the function's wrappered name |
| String *wname = Swig_name_wrapper(symname); |
| |
| // Create the wrapper function object |
| Wrapper *wrapper = NewWrapper(); |
| |
| // Retrieve the intermediate return type for this function |
| if ((tm = Swig_typemap_lookup("imtype", n, "", 0))) { |
| Printf(imrettype, "%s", tm); |
| } else { |
| Swig_warning(WARN_OBJC_TYPEMAP_IMTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", crettype); |
| } |
| |
| // Deal with overloading |
| |
| /* Write the wrapper function declaration and definition */ |
| |
| // Begin the first line of the function definition |
| Printv(wrapper->def, imrettype, " ", wname, "(", NIL); |
| |
| // Make the param list with the intermediate parameter types |
| makeParameterList(parmlist, wrapper); |
| |
| // End the first line of the function definition |
| Printv(wrapper->def, ")", NIL); |
| |
| // Write the function declaration to the wrap_h |
| Printv(wrap_h_code, wrapper->def, ";\n", NIL); |
| |
| // Now write the function definition to the wrap_cpp |
| Printv(wrapper->def, "\n{", NIL); |
| |
| // Emit all of the local variables for holding arguments |
| emit_parameter_variables(parmlist, wrapper); |
| |
| // If any additional local variable needed, add them now |
| if (!is_void_return) |
| Wrapper_add_localv(wrapper, "imresult", imrettype, "imresult = 0", NIL); |
| |
| // Attach the standard typemaps to the parameter list |
| emit_attach_parmmaps(parmlist, wrapper); |
| Setattr(n, "wrap:parms", parmlist); |
| |
| // Now walk the function parameter list and generate code to get arguments. |
| marshalInputArgs(parmlist, wrapper); |
| |
| // Emit the function call |
| if (is_constant) { // Wrapping a constant hack. |
| Swig_save("functionWrapper", n, "wrap:action", NIL); |
| |
| // below based on Swig_VargetToFunction() |
| SwigType *ty = Swig_wrapped_var_type(Getattr(n, "type"), use_naturalvar_mode(n)); |
| Setattr(n, "wrap:action", NewStringf("%s = (%s) %s;", Swig_cresult_name(), SwigType_lstr(ty, 0), Getattr(n, "value"))); |
| } |
| |
| Setattr(n, "wrap:name", wname); |
| String *actioncode = emit_action(n); |
| |
| if (Cmp(nodeType(n), "constant") == 0) |
| Swig_restore(n); |
| |
| // Write typemaps(out) and return value if necessary. |
| marshalOutput(n, actioncode, wrapper); |
| |
| // Close the function |
| if (!is_void_return) |
| Printv(wrapper->code, "return imresult;\n", NIL); |
| Printv(wrapper->code, "}", NIL); |
| |
| // Final substititions if applicable. |
| |
| /* Contract macro modification */ |
| Replaceall(wrapper->code, "SWIG_contract_assert(", "SWIG_contract_assert($null, "); |
| |
| if (!is_void_return) |
| Replaceall(wrapper->code, "$null", "0"); |
| else |
| Replaceall(wrapper->code, "$null", ""); |
| |
| // Dump the function out. |
| Wrapper_print(wrapper, wrap_mm_code); |
| |
| /* Create the proxy functions if proxy_flag is true. */ |
| if (proxy_flag && is_constructor) { // Handle constructor |
| Setattr(n, "imfunctionname", wname); |
| emitProxyClassConstructor(n); |
| } else if (proxy_flag && is_destructor) { // Handle destructor |
| // TODO: Do it here instead in emitProxyClass function |
| } |
| // globalFunctionHandler is called for static member functions as well hence setting global_func_flag to true. |
| // To route the call to the appropriate proxy generator, we check for !static_member_func_flag here. |
| if (proxy_flag && (global_variable_flag || global_func_flag) && !static_member_func_flag) { // Handle globals |
| Setattr(n, "imfunctionname", wname); |
| emitProxyGlobalFunctions(n); |
| } else if (proxy_flag && (member_variable_flag || static_member_variable_flag || member_constant_flag || member_func_flag || static_member_func_flag)) { // Handle members |
| Setattr(n, "imfunctionname", wname); |
| emitProxyClassFunction(n); |
| } |
| // Tidy up |
| Delete(imrettype); |
| Delete(wname); |
| DelWrapper(wrapper); |
| return SWIG_OK; |
| } |
| |
| /* --------------------------------------------------------------------- |
| * nativeWrapper() |
| * |
| * |
| * --------------------------------------------------------------------- */ |
| |
| int OBJECTIVEC::nativeWrapper(Node *n) { |
| Language::nativeWrapper(n); |
| return SWIG_OK; |
| } |
| |
| /* ----------------------------------------------------------------------------- |
| * emitProxyGlobalFunctions() |
| * |
| * C/C++ global functions and global variables are mapped to ObjectiveC global functions. |
| * C/C++ types will be replaced with their equivalent ObjectiveC types (eg: char* --> NSString*) |
| * A prefix 'Objc' will be added to counter linker redifiniton complains. |
| * |
| * ----------------------------------------------------------------------------- */ |
| |
| void OBJECTIVEC::emitProxyGlobalFunctions(Node *n) { |
| if (!proxy_flag) |
| return; |
| |
| // Get some useful attributes of this function |
| String *symname = Getattr(n, "sym:name"); |
| SwigType *type = Getattr(n, "type"); |
| ParmList *parmlist = Getattr(n, "parms"); |
| String *crettype = SwigType_str(type, 0); |
| String *storage = Getattr(n, "storage"); |
| String *objcrettype = NewString(""); |
| String *imcall = NewString(""); |
| String *function_defn = NewString(""); |
| String *function_decl = NewString(""); |
| String *tm; |
| String *imfunctionname = Getattr(n, "imfunctionname"); |
| String *proxyfunctionname; |
| bool setter_flag = false; |
| |
| // Retrieve the ObjectiveC return type for this function |
| if ((tm = Swig_typemap_lookup("objctype", n, "", 0))) { |
| substituteClassname(tm, type); |
| Printf(objcrettype, "%s", tm); |
| } else { |
| Swig_warning(WARN_OBJC_TYPEMAP_OBJCTYPE_UNDEF, input_file, line_number, "No objctype typemap defined for %s\n", crettype); |
| } |
| |
| // Deal with overloading |
| |
| // Change the function name for global variables |
| if (proxy_flag && global_variable_flag) { |
| proxyfunctionname = NewString(""); |
| setter_flag = (Cmp(symname, Swig_name_set(getNSpace(), variable_name)) == 0); |
| if (setter_flag) |
| Printf(proxyfunctionname, "set"); |
| else |
| Printf(proxyfunctionname, "get"); |
| |
| // Capitalize the first letter in the variable to create an ObjectiveC proxy function name |
| Putc(toupper((int) *Char(variable_name)), proxyfunctionname); |
| Printf(proxyfunctionname, "%s", Char(variable_name) + 1); |
| } else { |
| proxyfunctionname = NewString("Objc"); |
| // Capitalize the first letter |
| Putc(toupper((int) *Char(symname)), proxyfunctionname); |
| Printf(proxyfunctionname, "%s", Char(symname) + 1); |
| } |
| |
| /* Write the proxy global function declaration and definition */ |
| |
| // Begin the first line of the function |
| Printv(function_decl, objcrettype, " ", proxyfunctionname, "(", NIL); |
| |
| // Prepare the call to intermediate function |
| Printf(imcall, "%s(", imfunctionname); |
| |
| // Attach the non-standard typemaps to the parameter list |
| Swig_typemap_attach_parms("in", parmlist, NULL); |
| Swig_typemap_attach_parms("objctype", parmlist, NULL); |
| Swig_typemap_attach_parms("objcin", parmlist, NULL); |
| |
| Parm *p; |
| int i = 0; |
| int gencomma = 0; |
| |
| for (p = parmlist; p; p = nextSibling(p), i++) { |
| p = skipIgnoredArgs(p); |
| SwigType *pt = Getattr(p, "type"); |
| |
| String *objcparmtype = NewString(""); |
| |
| // Get the ObjectiveC parameter type for this parameter |
| if ((tm = Getattr(p, "tmap:objctype"))) { |
| substituteClassname(tm, pt); |
| Printf(objcparmtype, "%s", tm); |
| } else { |
| Swig_warning(WARN_OBJC_TYPEMAP_OBJCTYPE_UNDEF, input_file, line_number, "No objctype typemap defined for %s\n", SwigType_str(pt, 0)); |
| } |
| |
| if (gencomma) |
| Printf(imcall, ", "); |
| |
| String *arg = makeParameterName(n, p, i, setter_flag); |
| |
| // Use typemaps to transform the type used in Objective-C proxy function to the one used in intermediate code. |
| if ((tm = Getattr(p, "tmap:objcin"))) { |
| substituteClassname(tm, pt); |
| Replaceall(tm, "$objcinput", arg); |
| Printv(imcall, tm, NIL); |
| } else { |
| Swig_warning(WARN_OBJC_TYPEMAP_OBJCIN_UNDEF, input_file, line_number, "No objcin typemap defined for %s\n", SwigType_str(pt, 0)); |
| } |
| |
| // Add parameter to proxy function |
| if (gencomma >= 2) |
| Printf(function_decl, ", "); |
| gencomma = 2; |
| Printf(function_decl, "%s %s", objcparmtype, arg); |
| |
| Delete(arg); |
| Delete(objcparmtype); |
| } |
| |
| // End the first line of the function |
| Printv(function_decl, ")", NIL); // or |
| //Printv(function_decl, paramstring, ")", NIL); |
| |
| Printv(function_defn, function_decl, "\n{\n", NIL); |
| Printf(function_decl, ";"); |
| |
| // End the call to the intermediate function |
| Printv(imcall, ")", NIL); |
| |
| // Transform return type used in low level accessor to type used in Objective-C proxy function |
| if ((tm = Swig_typemap_lookup("objcout", n, "", 0))) { |
| substituteClassname(tm, type); |
| Replaceall(tm, "$imcall", imcall); |
| } else { |
| Swig_warning(WARN_OBJC_TYPEMAP_OBJCOUT_UNDEF, input_file, line_number, "No objcout typemap defined for %s\n", crettype); |
| } |
| |
| Printf(function_defn, " %s\n}\n", tm ? (const String *) tm : empty_string); |
| |
| /* Write the function declaration to the proxy_h_code |
| and function definition to the proxy_mm_code */ |
| if ((member_func_flag || member_constant_flag || Strcmp(storage, "friend") == 0 || Strcmp(storage, "typedef") == 0)) |
| { |
| Printv(proxy_global_function_decls, function_decl, "\n", NIL); |
| Printv(proxy_global_function_defns, function_defn, "\n", NIL); |
| }else { |
| Printv(proxy_h_code, function_decl, "\n", NIL); |
| Printv(proxy_mm_code, function_defn, "\n", NIL); |
| } |
| //Delete(paramstring); |
| Delete(proxyfunctionname); |
| Delete(objcrettype); |
| Delete(imcall); |
| Delete(function_decl); |
| Delete(function_defn); |
| } |
| |
| |
| /* ----------------------------------------------------------------------------- |
| * emitProxyClassFunction() |
| * |
| * Function called for writing an Objective-C proxy function for static and non-static |
| * C++ class functions, static and non-static member variables, member constants/enums. |
| * |
| * C++ class static functions map to Objective-C "+" functions. |
| * C++ class non-static functions map to Objective-C "-" functions. |
| * ----------------------------------------------------------------------------- */ |
| |
| void OBJECTIVEC::emitProxyClassFunction(Node *n) { |
| if (!proxy_flag) |
| return; |
| |
| // Get some useful attributes of this function |
| String *symname = Getattr(n, "sym:name"); |
| String *name = Getattr(n, "name"); |
| SwigType *type = Getattr(n, "type"); |
| ParmList *parmlist = Getattr(n, "parms"); |
| String *crettype = SwigType_str(type, 0); |
| String *objcrettype = NewString(""); |
| String *imcall = NewString(""); |
| String *function_defn = NewString(""); |
| String *function_decl = NewString(""); |
| String *tm; |
| |
| String *imfunctionname = Getattr(n, "imfunctionname"); |
| String *proxyfunctionname; |
| |
| bool setter_flag = false; |
| bool static_flag = (static_member_func_flag || static_member_variable_flag); |
| |
| // Retrieve the ObjectiveC return type for this function |
| if ((tm = Swig_typemap_lookup("objctype", n, "", 0))) { |
| substituteClassname(tm, type); |
| Printf(objcrettype, "%s", tm); |
| } else { |
| Swig_warning(WARN_OBJC_TYPEMAP_OBJCTYPE_UNDEF, input_file, line_number, "No objctype typemap defined for %s\n", crettype); |
| } |
| |
| if (member_variable_flag || static_member_variable_flag || member_constant_flag) { |
| proxyfunctionname = NewString(""); |
| setter_flag = Cmp(symname, Swig_name_set(getNSpace(), Swig_name_member(0, proxy_class_name, variable_name))) == 0; |
| if (setter_flag) |
| Printf(proxyfunctionname, "set"); |
| else |
| Printf(proxyfunctionname, "get"); |
| // Capitalize the first letter in the variable to create an ObjectiveC proxy function name |
| Putc(toupper((int) *Char(variable_name)), proxyfunctionname); |
| Printf(proxyfunctionname, "%s", Char(variable_name) + 1); |
| |
| } else if (member_func_flag) { |
| proxyfunctionname = Copy(proxyfuncname); |
| } else { |
| proxyfunctionname = Copy(proxyfuncname); |
| } |
| |
| // Deal with overloading |
| |
| /* Write the proxy function declaration and definition */ |
| |
| // Begin the first line of the function declaration |
| if (static_flag) |
| Printv(function_decl, "+(", objcrettype, ")", proxyfunctionname, NIL); |
| else |
| Printv(function_decl, "-(", objcrettype, ")", proxyfunctionname, NIL); |
| |
| // Prepare the call to intermediate function |
| Printv(imcall, imfunctionname, "(", NIL); |
| |
| // Attach the non-standard typemaps to the parameter list |
| Swig_typemap_attach_parms("in", parmlist, NULL); |
| Swig_typemap_attach_parms("objctype", parmlist, NULL); |
| Swig_typemap_attach_parms("objcin", parmlist, NULL); |
| |
| Parm *p; |
| int i = 0; |
| int gencomma = 0; |
| |
| for (p = parmlist; p; p = nextSibling(p), i++) { |
| p = skipIgnoredArgs(p); |
| SwigType *pt = Getattr(p, "type"); |
| String *objcparmtype = NewString(""); |
| |
| // Get the ObjectiveC parameter type for this parameter |
| if ((tm = Getattr(p, "tmap:objctype"))) { |
| substituteClassname(tm, pt); |
| Printf(objcparmtype, "%s", tm); |
| } else { |
| Swig_warning(WARN_OBJC_TYPEMAP_OBJCTYPE_UNDEF, input_file, line_number, "No objctype typemap defined for %s\n", SwigType_str(pt, 0)); |
| } |
| |
| if (gencomma) |
| Printf(imcall, ", "); |
| |
| String *arg = makeParameterName(n, p, i, setter_flag); |
| |
| // Use typemaps to transform type used in Objective-C proxy function to the one used in intermediate code. |
| if ((tm = Getattr(p, "tmap:objcin"))) { |
| substituteClassname(tm, pt); |
| Replaceall(tm, "$objcinput", arg); |
| Printv(imcall, tm, NIL); |
| } else { |
| Swig_warning(WARN_OBJC_TYPEMAP_OBJCIN_UNDEF, input_file, line_number, "No objcin typemap defined for %s\n", SwigType_str(pt, 0)); |
| } |
| |
| // Add parameter to proxy function |
| if (static_flag) { |
| if (gencomma == 0) |
| Printf(function_decl, ": (%s)%s", objcparmtype, arg); |
| else if (gencomma >= 1) |
| Printf(function_decl, " %s: (%s)%s", arg, objcparmtype, arg); |
| } else { |
| if (gencomma == 1) |
| Printf(function_decl, ": (%s)%s", objcparmtype, arg); |
| else if (gencomma >= 2) |
| Printf(function_decl, " %s: (%s)%s", arg, objcparmtype, arg); |
| } |
| gencomma++; |
| |
| Delete(arg); |
| Delete(objcparmtype); |
| } |
| |
| // First line of function definition |
| Printv(function_defn, function_decl, "\n{\n", NIL); |
| Printf(function_decl, ";"); |
| |
| // End the call to the intermediate function |
| Printv(imcall, ")", NIL); |
| |
| // Transform return type used in low level accessor to type used in Objective-C proxy function |
| if ((tm = Swig_typemap_lookup("objcout", n, "", 0))) { |
| substituteClassname(tm, type); |
| Replaceall(tm, "$imcall", imcall); |
| } else { |
| Swig_warning(WARN_OBJC_TYPEMAP_OBJCOUT_UNDEF, input_file, line_number, "No objcout typemap defined for %s\n", crettype); |
| } |
| |
| Printf(function_defn, " %s\n}\n", tm ? (const String *) tm : empty_string); |
| |
| |
| /* Write the function declaration to the proxy_class_function_decls |
| and function definition to the proxy_class_function_defns */ |
| Printv(proxy_class_function_decls, function_decl, "\n", NIL); |
| Printv(proxy_class_function_defns, function_defn, "\n", NIL); |
| |
| //Delete(paramstring); |
| Delete(proxyfunctionname); |
| Delete(objcrettype); |
| Delete(imcall); |
| Delete(function_decl); |
| Delete(function_defn); |
| } |
| |
| /* ----------------------------------------------------------------------------- |
| * emitProxyClassConstructor() |
| * |
| * Function called for writing an Objective-C proxy class constructor a.k.a |
| * init function(s). |
| * |
| * ----------------------------------------------------------------------------- */ |
| |
| void OBJECTIVEC::emitProxyClassConstructor(Node *n) { |
| if (!proxy_flag) |
| return; |
| |
| // Get some useful attributes of the constructor |
| String *name = Getattr(n, "name"); |
| ParmList *parmlist = Getattr(n, "parms"); |
| String *imcall = NewString(""); |
| String *constructor_defn = NewString(""); |
| String *constructor_decl = NewString(""); |
| String *tm; |
| String *objcrettype = NewString("id"); |
| |
| String *imfunctionname = Getattr(n, "imfunctionname"); |
| String *proxyfunctionname = NewString("init"); |
| |
| // Deal with overloading |
| |
| /* Write the proxy class constructor declaration and definition */ |
| |
| // Begin the first line of the constructor |
| Printv(constructor_decl, "-(", objcrettype, ")", proxyfunctionname, NIL); |
| |
| // Prepare the call to intermediate function |
| Printv(imcall, imfunctionname, "(", NIL); |
| |
| // Attach the non-standard typemaps to the parameter list |
| Swig_typemap_attach_parms("in", parmlist, NULL); |
| Swig_typemap_attach_parms("objctype", parmlist, NULL); |
| Swig_typemap_attach_parms("objcin", parmlist, NULL); |
| |
| Parm *p; |
| int i = 0; |
| int gencomma = 0; |
| |
| for (p = parmlist; p; p = nextSibling(p), i++) { |
| p = skipIgnoredArgs(p); |
| SwigType *pt = Getattr(p, "type"); |
| String *objcparmtype = NewString(""); |
| |
| // Get the ObjectiveC parameter type for this parameter |
| if ((tm = Getattr(p, "tmap:objctype"))) { |
| substituteClassname(tm, pt); |
| Printf(objcparmtype, "%s", tm); |
| } else { |
| Swig_warning(WARN_OBJC_TYPEMAP_OBJCTYPE_UNDEF, input_file, line_number, "No objctype typemap defined for %s\n", SwigType_str(pt, 0)); |
| } |
| |
| if (gencomma) |
| Printf(imcall, ", "); |
| |
| String *arg = makeParameterName(n, p, i, false); |
| |
| // Use typemaps to transform type used in Objective-C proxy function to the one used in intermediate code. |
| if ((tm = Getattr(p, "tmap:objcin"))) { |
| substituteClassname(tm, pt); |
| Replaceall(tm, "$objcinput", arg); |
| Printv(imcall, tm, NIL); |
| } else { |
| Swig_warning(WARN_OBJC_TYPEMAP_OBJCIN_UNDEF, input_file, line_number, "No objcin typemap defined for %s\n", SwigType_str(pt, 0)); |
| } |
| |
| // Add parameter to proxy function |
| if (gencomma >= 1) { // Subsequent arguments. |
| Printf(constructor_decl, " %s:", arg); |
| } else { // First valid argument, prefix it with 'With' and capitalize the first letter |
| Printf(constructor_decl, "With"); |
| Putc(toupper((int) *Char(arg)), constructor_decl); |
| Printf(constructor_decl, "%s:", (Char(arg) + 1)); |
| } |
| |
| Printf(constructor_decl, " (%s)%s", objcparmtype, arg); |
| gencomma++; |
| |
| Delete(arg); |
| Delete(objcparmtype); |
| |
| } |
| |
| // First line of function definition |
| Printv(constructor_defn, constructor_decl, "\n{\n", NIL); |
| Printf(constructor_decl, ";"); |
| |
| // End the call to the intermediate function |
| Printv(imcall, ")", NIL); |
| |
| // Insert the objcconstructor typemap |
| Hash *attributes = NewHash(); |
| String *constructor_code = NewString(""); |
| const String *construct_tm = typemapLookup(n, "objcconstructor", name, WARN_NONE, attributes); |
| if (construct_tm) { |
| Printv(constructor_code, construct_tm, NIL); |
| Replaceall(constructor_code, "$imcall", imcall); |
| } |
| Printf(constructor_defn, " %s\n}\n", constructor_code); |
| |
| Delete(attributes); |
| Delete(constructor_code); |
| |
| /* Write the function declaration to the proxy_class_function_decls |
| and function definition to the proxy_class_function_defns */ |
| Printv(proxy_class_function_decls, constructor_decl, "\n", NIL); |
| Printv(proxy_class_function_defns, constructor_defn, "\n", NIL); |
| |
| //Delete(paramstring); |
| Delete(proxyfunctionname); |
| Delete(objcrettype); |
| Delete(imcall); |
| Delete(constructor_decl); |
| Delete(constructor_defn); |
| } |
| |
| |
| /* --------------------------------------------------------------------------- |
| * emitProxyClass() |
| * |
| * Collects all the code fragments generated by the handler function while |
| * traversing the tree from the proxy_class_* variables and writes the |
| * class definition (including any additional code) to proxy_h and proxy_mm files. |
| * |
| * Inputs: |
| * n – The class node currently processed. |
| * --------------------------------------------------------------------------- */ |
| void OBJECTIVEC::emitProxyClass(Node *n) { |
| if (!proxy_flag) |
| return; |
| |
| SwigType *typemap_lookup_type = Getattr(n, "classtypeobj"); |
| |
| /* |
| * Handle inheriting from ObjectiveC and C++ classes. |
| */ |
| String *baseclass = NULL; |
| String *c_baseclassname = NULL; |
| |
| // Inheritance from pure ObjectiveC classes. |
| Node *attributes = NewHash(); |
| const String *pure_baseclass = typemapLookup(n, "objcbase", typemap_lookup_type, WARN_NONE, attributes); |
| bool purebase_replace = GetFlag(attributes, "tmap:objcbase:replace") ? true : false; |
| bool purebase_notderived = GetFlag(attributes, "tmap:objcbase:notderived") ? true : false; |
| Delete(attributes); |
| |
| // C++ inheritance. |
| if (!purebase_replace) { |
| List *baselist = Getattr(n, "bases"); |
| if (baselist) { |
| Iterator base = First(baselist); |
| while (base.item && GetFlag(base.item, "feature:ignore")) { |
| base = Next(base); |
| } |
| if (base.item) { |
| c_baseclassname = Getattr(base.item, "name"); |
| baseclass = Copy(createProxyName(c_baseclassname)); |
| base = Next(base); |
| /* Warn about multiple inheritance for additional base class(es) */ |
| while (base.item) { |
| if (GetFlag(base.item, "feature:ignore")) { |
| base = Next(base); |
| continue; |
| } |
| String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0); |
| String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0); |
| Swig_warning(WARN_OBJC_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), |
| "Base %s of class %s ignored: multiple inheritance is not supported in ObjectiveC.\n", baseclassname, proxyclassname); |
| base = Next(base); |
| } |
| } |
| } |
| } |
| |
| bool derived = baseclass && createProxyName(c_baseclassname); |
| if (derived && purebase_notderived) { |
| pure_baseclass = empty_string; |
| } |
| const String *wanted_base = baseclass ? baseclass : pure_baseclass; |
| |
| if (purebase_replace) { |
| wanted_base = pure_baseclass; |
| derived = false; |
| Delete(baseclass); |
| baseclass = NULL; |
| if (purebase_notderived) { |
| Swig_error(Getfile(n), Getline(n), |
| "The objcbase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n", typemap_lookup_type); |
| } |
| } else if (Len(pure_baseclass) > 0 && Len(baseclass) > 0) { |
| Swig_warning(WARN_OBJC_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), |
| "Warning for %s proxy: Base class %s ignored. Multiple inheritance is not supported in ObjectiveC. " |
| "Perhaps you need one of the 'replace' or 'notderived' attributes in the objcbase typemap?\n", typemap_lookup_type, pure_baseclass); |
| } |
| |
| /* Destructor handling */ |
| // If the C++ destructor is accessible (public), it is wrapped by the |
| // dealloc() method in ObjectiveC. If it is not accessible, dealloc() method is written and throws an exception. |
| String *destructor_decl = NewString(""); |
| String *destructor_defn = NewString(""); |
| const String *tm = NULL; |
| |
| String *destructor_methodname; |
| String *destructor_methodmodifiers; |
| attributes = NewHash(); |
| |
| tm = typemapLookup(n, "objcdestructor", typemap_lookup_type, WARN_NONE, attributes); |
| destructor_methodname = Getattr(attributes, "tmap:objcdestructor:methodname"); |
| destructor_methodmodifiers = Getattr(attributes, "tmap:objcdestructor:methodmodifiers"); |
| |
| if (tm && *Char(tm)) { |
| if (!destructor_methodname) { |
| Swig_error(Getfile(n), Getline(n), "No methodname attribute defined in the objcdestructor typemap for %s\n", proxy_class_name); |
| } |
| if (!destructor_methodmodifiers) { |
| Swig_error(Getfile(n), Getline(n), "No methodmodifiers attribute defined in objcdestructor typemap for %s.\n", proxy_class_name); |
| } |
| } |
| |
| if (tm) { |
| // Write the dealloc() method declaration for the proxy interface |
| Printv(destructor_decl, "\n", "-(void)", destructor_methodname, ";\n", NIL); |
| |
| // And, the dealloc() method definition for the proxy implementation |
| String *destructor_code = NewString(""); |
| Printv(destructor_code, tm, NIL); |
| |
| if (*Char(destrcutor_call)) { |
| Replaceall(destructor_code, "$imcall", destrcutor_call); |
| } else { |
| Replaceall(destructor_code, "$imcall", "[NSException raise:@\"UnsupportedOperationException\" format: @\"%@\", \ |
| @\"C++ destructor does not have public access\"]"); |
| } |
| |
| if (*Char(destructor_code)) { |
| Printv(destructor_defn, "\n", "-(void)", destructor_methodname, "{\n", destructor_code, "\n}\n", NIL); |
| } |
| |
| Delete(destructor_code); |
| } |
| |
| |
| /* Write the proxy class declaration */ |
| // Class modifiers. |
| const String *objcinterfacemodifier = typemapLookup(n, "objcinterfacemodifier", typemap_lookup_type, WARN_OBJC_INTERFACE_MOD); |
| |
| // User-defined protocols. |
| const String *protocols = typemapLookup(n, derived ? "objcprotocols_derived" : "objcprotocols", typemap_lookup_type, WARN_NONE); |
| |
| // Default interface code |
| const String *objcinterfacecode; |
| if (derived) { |
| objcinterfacecode = typemapLookup(n, "objcinterfacecode_derived", typemap_lookup_type, WARN_NONE); |
| } else { |
| objcinterfacecode = typemapLookup(n, "objcinterfacecode", typemap_lookup_type, WARN_NONE); |
| } |
| |
| // the class interface |
| Printv(proxy_class_decl_code, proxy_class_imports, proxy_class_enums_code, |
| objcinterfacemodifier, " $objcclassname", |
| (*Char(wanted_base) || *Char(protocols)) ? " : " : "", wanted_base, |
| (*Char(wanted_base) && *Char(protocols)) ? ", " : "", protocols, |
| objcinterfacecode, proxy_class_function_decls, destructor_decl, "\n", typemapLookup(n, "objcclassclose", typemap_lookup_type, WARN_NONE), "\n\n", NIL); |
| |
| |
| /* Write the proxy class definition */ |
| // Class modifiers. |
| const String *objccimplementationmodifier = typemapLookup(n, "objcimplementationmodifier", typemap_lookup_type, WARN_OBJC_IMPLEMENTATION_MOD); |
| |
| // Default implementationcode code |
| const String *objcimplementationcode; |
| if (derived) { |
| objcimplementationcode = typemapLookup(n, "objcimplementationcode_derived", typemap_lookup_type, WARN_NONE); |
| } else { |
| objcimplementationcode = typemapLookup(n, "objcimplementationcode", typemap_lookup_type, WARN_NONE); |
| } |
| |
| // the class implementation |
| Printv(proxy_class_defn_code, "\n", objccimplementationmodifier, " $objcclassname", objcimplementationcode, "\n", |
| proxy_class_function_defns, destructor_defn, "\n", typemapLookup(n, "objcclassclose", typemap_lookup_type, WARN_NONE), "\n\n", NIL); |
| |
| Replaceall(proxy_class_decl_code, "$objcbaseclass", proxy_class_name); |
| Replaceall(proxy_class_defn_code, "$objcbaseclass", proxy_class_name); |
| |
| Delete(baseclass); |
| Delete(destructor_decl); |
| Delete(destructor_defn); |
| } |
| |
| |
| /* --------------------------------------------------------------------------- |
| * emitTypeWrapperClass() |
| * --------------------------------------------------------------------------- */ |
| void OBJECTIVEC::emitTypeWrapperClass(String *classname, SwigType *type) { |
| Node *n = NewHash(); |
| Setfile(n, input_file); |
| Setline(n, line_number); |
| |
| // Pure ObjectiveC baseclass and interfaces. |
| const String *pure_baseclass = typemapLookup(n, "objcbase", type, WARN_NONE); |
| const String *pure_interfaces = typemapLookup(n, "objcprotocols", type, WARN_NONE); |
| |
| /* Write the type wrapper class declaration */ |
| // Class modifiers. |
| const String *objcinterfacemodifier = typemapLookup(n, "objcinterfacemodifier", type, WARN_OBJC_INTERFACE_MOD); |
| |
| // Default interface code |
| const String *objcinterfacecode = typemapLookup(n, "objcinterfacecode", type, WARN_NONE); |
| |
| Printv(swigtypes_h_code, objcinterfacemodifier, " $objcclassname", |
| (*Char(pure_baseclass) || *Char(pure_interfaces)) ? " : " : "", pure_baseclass, |
| (*Char(pure_baseclass) && *Char(pure_interfaces)) ? ", " : "", pure_interfaces, |
| objcinterfacecode, "\n", typemapLookup(n, "objcclassclose", type, WARN_NONE), "\n\n", NIL); |
| |
| /* Write the type wrapper class definition */ |
| // Class modifiers. |
| const String *objccimplementationmodifier = typemapLookup(n, "objcimplementationmodifier", type, WARN_OBJC_IMPLEMENTATION_MOD); |
| |
| // Default implementationcode code |
| const String *objcimplementationcode = typemapLookup(n, "objcimplementationcode", type, WARN_NONE); |
| |
| Printv(swigtypes_mm_code, "\n", objccimplementationmodifier, " $objcclassname", objcimplementationcode, |
| "\n", typemapLookup(n, "objcclassclose", type, WARN_NONE), "\n\n", NIL); |
| |
| Replaceall(swigtypes_h_code, "$objcclassname", classname); |
| Replaceall(swigtypes_mm_code, "$objcclassname", classname); |
| |
| Delete(n); |
| } |
| |
| |
| /* ----------------------------------------------------------------------------- |
| * substituteClassname() |
| * |
| * Substitute $objcclassname with the proxy class name for classes/structs/unions that SWIG knows about. |
| * Also substitutes enums with enum name. |
| * Otherwise use the $descriptor name for the Objective-C class name. Note that the $&objcclassname substitution |
| * is the same as a $&descriptor substitution, ie one pointer added to descriptor name. |
| * |
| * Inputs: |
| * tm - String to perform the substitution at (will usually come from a |
| * typemap. |
| * pt - The type to substitute for the variables. |
| * Outputs: |
| * tm - String with the variables substituted. |
| * Return: |
| * substitution_performed - flag indicating if a substitution was performed |
| * ----------------------------------------------------------------------------- */ |
| |
| bool OBJECTIVEC::substituteClassname(String *tm, SwigType *pt) { |
| bool substitution_performed = false; |
| SwigType *type = Copy(SwigType_typedef_resolve_all(pt)); |
| SwigType *strippedtype = SwigType_strip_qualifiers(type); |
| |
| if (Strstr(tm, "$objcclassname")) { |
| SwigType *type = Copy(strippedtype); |
| substituteClassnameVariable(tm, "$objcclassname", type); |
| substitution_performed = true; |
| Delete(type); |
| } |
| if (Strstr(tm, "$*objcclassname")) { |
| SwigType *type = Copy(strippedtype); |
| Delete(SwigType_pop(type)); |
| substituteClassnameVariable(tm, "$*objcclassname", type); |
| substitution_performed = true; |
| Delete(type); |
| } |
| if (Strstr(tm, "$&objcclassname")) { |
| SwigType *type = Copy(strippedtype); |
| SwigType_add_pointer(type); |
| substituteClassnameVariable(tm, "$&objcclassname", type); |
| substitution_performed = true; |
| Delete(type); |
| } |
| |
| Delete(strippedtype); |
| Delete(type); |
| |
| return substitution_performed; |
| } |
| |
| /* ----------------------------------------------------------------------------- |
| * substituteClassnameVariable() |
| * ----------------------------------------------------------------------------- */ |
| |
| void OBJECTIVEC::substituteClassnameVariable(String *tm, const char *classnamevariable, SwigType *type) { |
| String *type_name; |
| |
| if (SwigType_isenum(type)) { |
| Node *n = enumLookup(type); |
| String *enum_name = Getattr(n, "sym:name"); |
| Node *p = parentNode(n); |
| if (p && !Strcmp(nodeType(p), "class")) { |
| // This is a nested enum. |
| String *parent_name = Getattr(p, "sym:name"); |
| type_name = NewStringf("enum %s_%s", parent_name, enum_name); |
| } else { |
| type_name = NewStringf("enum %s", enum_name); |
| } |
| } else { |
| String *class_name = createProxyName(type); |
| if (class_name) { |
| type_name = Copy(class_name); |
| } else { |
| // SWIG does not know anything about the type (after resolving typedefs). |
| // Just mangle the type name string like $descriptor(type) would do. |
| String *descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(type)); |
| type_name = Copy(descriptor); |
| |
| // Add to hash table so that the type wrapper classes can be created later |
| Setattr(unknown_types, descriptor, type); |
| Delete(descriptor); |
| } |
| } |
| Replaceall(tm, classnamevariable, type_name); |
| Delete(type_name); |
| } |
| |
| /* --------------------------------------------------------------------- |
| * skipIgnoredArgs() |
| * |
| * --------------------------------------------------------------------- */ |
| Parm *OBJECTIVEC::skipIgnoredArgs(Parm *p) { |
| while (checkAttribute(p, "tmap:in:numinputs", "0")) { |
| p = Getattr(p, "tmap:in:next"); |
| } |
| return p; |
| } |
| |
| /* --------------------------------------------------------------------- |
| * marshalInputArgs() |
| * |
| * Process all of the arguments passed and convert them into C/C++ |
| * function arguments using the supplied typemaps. |
| * --------------------------------------------------------------------- */ |
| |
| void OBJECTIVEC::marshalInputArgs(ParmList *parmlist, Wrapper *wrapper) { |
| String *tm; |
| Parm *p; |
| int i = 0; |
| |
| for (p = parmlist; p; p = nextSibling(p), i++) { |
| p = skipIgnoredArgs(p); |
| SwigType *pt = Getattr(p, "type"); |
| |
| String *arg = NewString(""); |
| Printf(arg, "imarg%d", i + 1); |
| |
| // Get the "in" typemap for this argument and add to the wrapper->code |
| if ((tm = Getattr(p, "tmap:in"))) { |
| Replaceall(tm, "$input", arg); |
| Setattr(p, "emit:input", arg); |
| Printf(wrapper->code, "%s\n", tm); |
| } else { |
| Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0)); |
| p = nextSibling(p); |
| } |
| Delete(arg); |
| } |
| |
| } |
| |
| /* --------------------------------------------------------------------- |
| * makeParameterList() |
| * |
| * --------------------------------------------------------------------- */ |
| |
| void OBJECTIVEC::makeParameterList(ParmList *parmlist, Wrapper *wrapper) { |
| |
| // Attach the non-standard typemaps to the parameter list |
| Swig_typemap_attach_parms("imtype", parmlist, wrapper); |
| |
| String *tm; |
| Parm *p; |
| int i = 0; |
| int gencomma = 0; |
| |
| for (p = parmlist; p; p = nextSibling(p), i++) { |
| p = skipIgnoredArgs(p); |
| SwigType *pt = Getattr(p, "type"); |
| |
| String *imparmtype = NewString(""); |
| String *arg = NewString(""); |
| |
| Printf(arg, "imarg%d", i + 1); |
| |
| // Get the intermediate parameter type for this parameter |
| if ((tm = Getattr(p, "tmap:imtype"))) { |
| Printv(imparmtype, tm, NIL); |
| if (gencomma) |
| Printf(wrapper->def, ", "); |
| Printv(wrapper->def, imparmtype, " ", arg, NIL); // Add parameter to the function signature (wrapper->def) |
| ++gencomma; |
| } else { |
| Swig_warning(WARN_OBJC_TYPEMAP_IMTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(pt, 0)); |
| p = nextSibling(p); |
| } |
| |
| Delete(imparmtype); |
| Delete(arg); |
| } |
| } |
| |
| /* --------------------------------------------------------------------- |
| * marshalOutput() |
| * |
| * Process the return value of the C/C++ function call |
| * and convert it into the intermediate type using the |
| * supplied typemaps. |
| * --------------------------------------------------------------------- */ |
| |
| void OBJECTIVEC::marshalOutput(Node *n, String *actioncode, Wrapper *wrapper) { |
| SwigType *type = Getattr(n, "type"); |
| // Emit the out typemap |
| String *tm; |
| if ((tm = Swig_typemap_lookup_out("out", n, "result", wrapper, actioncode))) { |
| Replaceall(tm, "$result", "imresult"); |
| Printf(wrapper->code, "%s", tm); |
| if (Len(tm)) |
| Printf(wrapper->code, "\n"); |
| } else { |
| Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(type, 0), Getattr(n, "name")); |
| } |
| // Emits a variable declaration for a function return value |
| emit_return_variable(n, type, wrapper); |
| } |
| |
| |
| /* --------------------------------------------------------------------------- |
| * makeParameterName() |
| * |
| * Inputs: |
| * n - Node |
| * p - parameter node |
| * arg_num - parameter argument number |
| * setter - set this flag when wrapping variables |
| * Return: |
| * arg - a unique parameter name |
| * --------------------------------------------------------------------------- */ |
| String *OBJECTIVEC::makeParameterName(Node *n, Parm *p, int argnumber, bool setter) const { |
| String *arg = 0; |
| String *pn = Getattr(p, "name"); |
| |
| // Use C parameter name unless it is a duplicate or an empty parameter name |
| int count = 0; |
| ParmList *plist = Getattr(n, "parms"); |
| while (plist) { |
| if ((Cmp(pn, Getattr(plist, "name")) == 0)) |
| count++; |
| plist = nextSibling(plist); |
| } |
| String *wrn = pn ? Swig_name_warning(p, 0, pn, 0) : 0; |
| arg = (!pn || (count > 1) || wrn) ? NewStringf("arg%d", argnumber) : Copy(pn); |
| |
| if (setter && Cmp(arg, "self") != 0) { |
| // In theory, we could use the normal parameter name for setter functions. |
| // Unfortunately, it is set to "Class::VariableName" for static public |
| // members by the parser, which is not legal ObjectiveC syntax. Thus, we just force |
| // it to "value". |
| Delete(arg); |
| arg = NewString("value"); |
| } |
| |
| |
| return arg; |
| } |
| |
| |
| /* ----------------------------------------------------------------------------- |
| * createProxyName() |
| * |
| * Returns the ObjectiveC class name if a type corresponds to something wrapped with a |
| * proxy class, NULL otherwise. |
| * ----------------------------------------------------------------------------- */ |
| |
| String *OBJECTIVEC::createProxyName(SwigType *t) { // TODO: See this once more for nspaces. |
| if (proxy_flag) { |
| Node *n = classLookup(t); |
| if (n) { |
| return Getattr(n, "sym:name"); |
| } |
| } |
| return NULL; |
| } |
| |
| /* ----------------------------------------------------------------------------- |
| * typemapLookup() |
| * n - for input only and must contain info for Getfile(n) and Getline(n) to work |
| * tmap_method - typemap method name |
| * type - typemap type to lookup |
| * warning - warning number to issue if no typemaps found |
| * typemap_attributes - the typemap attributes are attached to this node and will |
| * also be used for temporary storage if non null |
| * return is never NULL, unlike Swig_typemap_lookup() |
| * ----------------------------------------------------------------------------- */ |
| |
| const String *OBJECTIVEC::typemapLookup(Node *n, const_String_or_char_ptr tmap_method, SwigType *type, int warning, Node *typemap_attributes) { |
| Node *node = !typemap_attributes ? NewHash() : typemap_attributes; |
| Setattr(node, "type", type); |
| Setfile(node, Getfile(n)); |
| Setline(node, Getline(n)); |
| const String *tm = Swig_typemap_lookup(tmap_method, node, "", 0); |
| if (!tm) { |
| tm = empty_string; |
| if (warning != WARN_NONE) |
| Swig_warning(warning, Getfile(n), Getline(n), "No %s typemap defined for %s\n", tmap_method, SwigType_str(type, 0)); |
| } |
| if (!typemap_attributes) |
| Delete(node); |
| return tm; |
| } |
| |
| |
| /* ----------------------------------------------------------------------------- |
| * swig_objectivec() - Instantiate module |
| * ----------------------------------------------------------------------------- */ |
| |
| static Language *new_swig_objectivec() { |
| return new OBJECTIVEC(); |
| } |
| extern "C" Language *swig_objectivec(void) { |
| return new_swig_objectivec(); |
| } |
| |
| /* ----------------------------------------------------------------------------- |
| * Static member variables |
| * ----------------------------------------------------------------------------- */ |
| |
| // Usage message. |
| const char *const OBJECTIVEC::usage = (char *) "\ |
| ObjectiveC options (available with -objc)\n\ |
| -noproxy - Do not generate proxy files (Only C wrappers will be generated) \n\ |
| -help - This message \n\ |
| \n"; |