file_py3.i revision 291767
1/* 2 * file_py3.i: Typemaps for FILE* for Python 3 3 * 4 * Copyright (c) 2011, Karel Slany (karel.slany AT nic.cz) 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: 9 * 10 * * Redistributions of source code must retain the above copyright notice, 11 * this list of conditions and the following disclaimer. 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * * Neither the name of the organization nor the names of its 16 * contributors may be used to endorse or promote products derived from this 17 * software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32%{ 33#include <unistd.h> 34#include <fcntl.h> 35%} 36 37%types(FILE *); 38 39//#define SWIG_FILE3_DEBUG 40 41/* converts basic file descriptor flags onto a string */ 42%fragment("fdfl_to_str", "header") { 43const char * 44fdfl_to_str(int fdfl) { 45 46 static const char * const file_mode[] = {"w+", "w", "r"}; 47 48 if (fdfl & O_RDWR) { 49 return file_mode[0]; 50 } else if (fdfl & O_WRONLY) { 51 return file_mode[1]; 52 } else { 53 return file_mode[2]; 54 } 55} 56} 57 58%fragment("is_obj_file", "header") { 59int 60is_obj_file(PyObject *obj) { 61 int fd, fdfl; 62 if (!PyLong_Check(obj) && /* is not an integer */ 63 PyObject_HasAttrString(obj, "fileno") && /* has fileno method */ 64 (PyObject_CallMethod(obj, "flush", NULL) != NULL) && /* flush() succeeded */ 65 ((fd = PyObject_AsFileDescriptor(obj)) != -1) && /* got file descriptor */ 66 ((fdfl = fcntl(fd, F_GETFL)) != -1) /* got descriptor flags */ 67 ) { 68 return 1; 69 } 70 else { 71 return 0; 72 } 73} 74} 75 76%fragment("obj_to_file","header", fragment="fdfl_to_str,is_obj_file") { 77FILE * 78obj_to_file(PyObject *obj) { 79 int fd, fdfl; 80 FILE *fp; 81 if (is_obj_file(obj)) { 82 fd = PyObject_AsFileDescriptor(obj); 83 fdfl = fcntl(fd, F_GETFL); 84 fp = fdopen(dup(fd), fdfl_to_str(fdfl)); /* the FILE* must be flushed 85 and closed after being used */ 86#ifdef SWIG_FILE3_DEBUG 87 fprintf(stderr, "opening fd %d (fl %d \"%s\") as FILE %p\n", 88 fd, fdfl, fdfl_to_str(fdfl), (void *)fp); 89#endif 90 return fp; 91 } 92 return NULL; 93} 94} 95 96/* returns -1 if error occurred */ 97/* caused magic SWIG Syntax errors when was commented out */ 98#if 0 99%fragment("dispose_file", "header") { 100int 101dispose_file(FILE **fp) { 102#ifdef SWIG_FILE3_DEBUG 103 fprintf(stderr, "flushing FILE %p\n", (void *)fp); 104#endif 105 if (*fp == NULL) { 106 return 0; 107 } 108 if ((fflush(*fp) == 0) && /* flush file */ 109 (fclose(*fp) == 0)) { /* close file */ 110 *fp = NULL; 111 return 0; 112 } 113 return -1; 114} 115} 116#endif 117 118%typemap(arginit, noblock = 1) FILE* { 119 $1 = NULL; 120} 121 122/* 123 * added due to ub_ctx_debugout since since it is overloaded: 124 * takes void* and FILE*. In reality only FILE* but the wrapper 125 * and the function is declared in such way. 126 */ 127%typemap(typecheck, noblock = 1, fragment = "is_obj_file", precedence = SWIG_TYPECHECK_POINTER) FILE* { 128 $1 = is_obj_file($input); 129} 130 131%typemap(check, noblock = 1) FILE* { 132 if ($1 == NULL) { 133 /* The generated wrapper function raises TypeError on mismatching types. */ 134 SWIG_exception_fail(SWIG_TypeError, "in method '" "$symname" "', argument " 135 "$argnum"" of type '" "$type""'"); 136 } 137} 138 139%typemap(in, noblock = 1, fragment = "obj_to_file") FILE* { 140 $1 = obj_to_file($input); 141} 142 143/* 144 * Commented out due the way how ub_ctx_debugout() uses the parameter. 145 * This typemap would cause the FILE* to be closed after return from 146 * the function. This caused Python interpreter to crash, since the 147 * function just stores the FILE* internally in ctx and use it for 148 * logging. So we'll leave the closing of the file on the OS. 149 */ 150/*%typemap(freearg, noblock = 1, fragment = "dispose_file") FILE* { 151 if (dispose_file(&$1) == -1) { 152 SWIG_exception_fail(SWIG_IOError, "closing file in method '" "$symname" "', argument " 153 "$argnum"" of type '" "$type""'"); 154 } 155}*/ 156