Home | History | Annotate | Download | only in ocaml
      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