1 /* ----------------------------------------------------------------------------- 2 * cstring.i 3 * 4 * This file provides typemaps and macros for dealing with various forms 5 * of C character string handling. The primary use of this module 6 * is in returning character data that has been allocated or changed in 7 * some way. 8 * ----------------------------------------------------------------------------- */ 9 10 /* %cstring_input_binary(TYPEMAP, SIZE) 11 * 12 * Macro makes a function accept binary string data along with 13 * a size. 14 */ 15 16 %define %cstring_input_binary(TYPEMAP, SIZE) 17 %apply (char *STRING, int LENGTH) { (TYPEMAP, SIZE) }; 18 %enddef 19 20 /* 21 * %cstring_bounded_output(TYPEMAP, MAX) 22 * 23 * This macro is used to return a NULL-terminated output string of 24 * some maximum length. For example: 25 * 26 * %cstring_bounded_output(char *outx, 512); 27 * void foo(char *outx) { 28 * sprintf(outx,"blah blah\n"); 29 * } 30 * 31 */ 32 33 %define %cstring_bounded_output(TYPEMAP,MAX) 34 %typemap(ignore) TYPEMAP(char temp[MAX+1]) { 35 $1 = ($1_ltype) temp; 36 } 37 %typemap(argout) TYPEMAP { 38 $1[MAX] = 0; 39 $result = caml_list_append($result,caml_val_string(str)); 40 } 41 %enddef 42 43 /* 44 * %cstring_chunk_output(TYPEMAP, SIZE) 45 * 46 * This macro is used to return a chunk of binary string data. 47 * Embedded NULLs are okay. For example: 48 * 49 * %cstring_chunk_output(char *outx, 512); 50 * void foo(char *outx) { 51 * memmove(outx, somedata, 512); 52 * } 53 * 54 */ 55 56 %define %cstring_chunk_output(TYPEMAP,SIZE) 57 %typemap(ignore) TYPEMAP(char temp[SIZE]) { 58 $1 = ($1_ltype) temp; 59 } 60 %typemap(argout) TYPEMAP { 61 $result = caml_list_append($result,caml_val_string_len($1,SIZE)); 62 } 63 %enddef 64 65 /* 66 * %cstring_bounded_mutable(TYPEMAP, SIZE) 67 * 68 * This macro is used to wrap a string that's going to mutate. 69 * 70 * %cstring_bounded_mutable(char *in, 512); 71 * void foo(in *x) { 72 * while (*x) { 73 * *x = toupper(*x); 74 * x++; 75 * } 76 * } 77 * 78 */ 79 80 81 %define %cstring_bounded_mutable(TYPEMAP,MAX) 82 %typemap(in) TYPEMAP(char temp[MAX+1]) { 83 char *t = (char *)caml_ptr_val($input); 84 strncpy(temp,t,MAX); 85 $1 = ($1_ltype) temp; 86 } 87 %typemap(argout) TYPEMAP { 88 $result = caml_list_append($result,caml_val_string_len($1,MAX)); 89 } 90 %enddef 91 92 /* 93 * %cstring_mutable(TYPEMAP [, expansion]) 94 * 95 * This macro is used to wrap a string that will mutate in place. 96 * It may change size up to a user-defined expansion. 97 * 98 * %cstring_mutable(char *in); 99 * void foo(in *x) { 100 * while (*x) { 101 * *x = toupper(*x); 102 * x++; 103 * } 104 * } 105 * 106 */ 107 108 %define %cstring_mutable(TYPEMAP,...) 109 %typemap(in) TYPEMAP { 110 char *t = String_val($input); 111 int n = string_length($input); 112 $1 = ($1_ltype) t; 113 #if #__VA_ARGS__ == "" 114 #ifdef __cplusplus 115 $1 = ($1_ltype) new char[n+1]; 116 #else 117 $1 = ($1_ltype) malloc(n+1); 118 #endif 119 #else 120 #ifdef __cplusplus 121 $1 = ($1_ltype) new char[n+1+__VA_ARGS__]; 122 #else 123 $1 = ($1_ltype) malloc(n+1+__VA_ARGS__); 124 #endif 125 #endif 126 memmove($1,t,n); 127 $1[n] = 0; 128 } 129 130 %typemap(argout) TYPEMAP { 131 $result = caml_list_append($result,caml_val_string($1)); 132 #ifdef __cplusplus 133 delete[] $1; 134 #else 135 free($1); 136 #endif 137 } 138 %enddef 139 140 /* 141 * %cstring_output_maxsize(TYPEMAP, SIZE) 142 * 143 * This macro returns data in a string of some user-defined size. 144 * 145 * %cstring_output_maxsize(char *outx, int max) { 146 * void foo(char *outx, int max) { 147 * sprintf(outx,"blah blah\n"); 148 * } 149 */ 150 151 %define %cstring_output_maxsize(TYPEMAP, SIZE) 152 %typemap(in) (TYPEMAP, SIZE) { 153 $2 = caml_val_long($input); 154 #ifdef __cplusplus 155 $1 = ($1_ltype) new char[$2+1]; 156 #else 157 $1 = ($1_ltype) malloc($2+1); 158 #endif 159 } 160 %typemap(argout) (TYPEMAP,SIZE) { 161 $result = caml_list_append($result,caml_val_string($1)); 162 #ifdef __cplusplus 163 delete [] $1; 164 #else 165 free($1); 166 #endif 167 } 168 %enddef 169 170 /* 171 * %cstring_output_withsize(TYPEMAP, SIZE) 172 * 173 * This macro is used to return character data along with a size 174 * parameter. 175 * 176 * %cstring_output_maxsize(char *outx, int *max) { 177 * void foo(char *outx, int *max) { 178 * sprintf(outx,"blah blah\n"); 179 * *max = strlen(outx); 180 * } 181 */ 182 183 %define %cstring_output_withsize(TYPEMAP, SIZE) 184 %typemap(in) (TYPEMAP, SIZE) { 185 int n = caml_val_long($input); 186 #ifdef __cplusplus 187 $1 = ($1_ltype) new char[n+1]; 188 $2 = ($2_ltype) new $*1_ltype; 189 #else 190 $1 = ($1_ltype) malloc(n+1); 191 $2 = ($2_ltype) malloc(sizeof($*1_ltype)); 192 #endif 193 *$2 = n; 194 } 195 %typemap(argout) (TYPEMAP,SIZE) { 196 $result = caml_list_append($result,caml_val_string_len($1,$2)); 197 #ifdef __cplusplus 198 delete [] $1; 199 delete $2; 200 #else 201 free($1); 202 free($2); 203 #endif 204 } 205 %enddef 206 207 /* 208 * %cstring_output_allocate(TYPEMAP, RELEASE) 209 * 210 * This macro is used to return character data that was 211 * allocated with new or malloc. 212 * 213 * %cstring_output_allocated(char **outx, free($1)); 214 * void foo(char **outx) { 215 * *outx = (char *) malloc(512); 216 * sprintf(outx,"blah blah\n"); 217 * } 218 */ 219 220 %define %cstring_output_allocate(TYPEMAP, RELEASE) 221 %typemap(ignore) TYPEMAP($*1_ltype temp = 0) { 222 $1 = &temp; 223 } 224 225 %typemap(argout) TYPEMAP { 226 if (*$1) { 227 $result = caml_list_append($result,caml_val_string($1)); 228 RELEASE; 229 } else { 230 $result = caml_list_append($result,caml_val_ptr($1)); 231 } 232 } 233 %enddef 234 235 /* 236 * %cstring_output_allocate_size(TYPEMAP, SIZE, RELEASE) 237 * 238 * This macro is used to return character data that was 239 * allocated with new or malloc. 240 * 241 * %cstring_output_allocated(char **outx, int *sz, free($1)); 242 * void foo(char **outx, int *sz) { 243 * *outx = (char *) malloc(512); 244 * sprintf(outx,"blah blah\n"); 245 * *sz = strlen(outx); 246 * } 247 */ 248 249 %define %cstring_output_allocate_size(TYPEMAP, SIZE, RELEASE) 250 %typemap(ignore) (TYPEMAP, SIZE) ($*1_ltype temp = 0, $*2_ltype tempn) { 251 $1 = &temp; 252 $2 = &tempn; 253 } 254 255 %typemap(argout)(TYPEMAP,SIZE) { 256 if (*$1) { 257 $result = caml_list_append($result,caml_val_string_len($1,$2)); 258 RELEASE; 259 } else 260 $result = caml_list_append($result,caml_val_ptr($1)); 261 } 262 %enddef 263 264 265 266 267 268 269