~ubuntu-branches/ubuntu/oneiric/swig1.3/oneiric

« back to all changes in this revision

Viewing changes to Source/Swig/typemap.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Vogt
  • Date: 2008-11-10 16:29:56 UTC
  • mfrom: (1.2.8 upstream) (2.1.3 lenny)
  • Revision ID: james.westby@ubuntu.com-20081110162956-xue6itkuqhbza87s
Tags: 1.3.36-1ubuntu1
* Merge from debian unstable, remaining changes:
  - Drop pike and libchicken-dev from the build-depends 
    (both are universe)
  - Use python2.5 instead of python2.4.
  - use php5
  - Clean Runtime/ as well.
  - debian/Rules (clean): Remove Lib/ocaml/swigp4.ml.
  - drop "--without-mzscheme", we don't have it in our build-depends

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
 * A somewhat generalized implementation of SWIG1.1 typemaps.
8
8
 * ----------------------------------------------------------------------------- */
9
9
 
10
 
char cvsroot_typemap_c[] = "$Id: typemap.c 9889 2007-08-10 02:55:27Z wuzzeb $";
 
10
char cvsroot_typemap_c[] = "$Id: typemap.c 10453 2008-05-15 21:18:44Z wsfulton $";
11
11
 
12
12
#include "swig.h"
13
13
#include "cparse.h"
802
802
}
803
803
 
804
804
static
805
 
void typemap_replace_vars(String *s, ParmList *locals, SwigType *type, SwigType *rtype, String *pname, String *lname, int index) {
 
805
int typemap_replace_vars(String *s, ParmList *locals, SwigType *type, SwigType *rtype, String *pname, String *lname, int index) {
806
806
  char var[512];
807
807
  char *varname;
808
808
  SwigType *ftype;
 
809
  int bare_substitution_count = 0;
809
810
 
810
811
  Replaceall(s, "$typemap", "$TYPEMAP");
811
812
 
1086
1087
 
1087
1088
  /* Replace the bare $n variable */
1088
1089
  sprintf(var, "$%d", index);
1089
 
  Replace(s, var, lname, DOH_REPLACE_ANY);
 
1090
  bare_substitution_count = Replace(s, var, lname, DOH_REPLACE_ANY);
1090
1091
  Delete(ftype);
 
1092
  return bare_substitution_count;
1091
1093
}
1092
1094
 
1093
1095
/* ------------------------------------------------------------------------
1160
1162
/* -----------------------------------------------------------------------------
1161
1163
 * Swig_typemap_lookup()
1162
1164
 *
1163
 
 * Perform a typemap lookup (ala SWIG1.1)
1164
 
 * ----------------------------------------------------------------------------- */
1165
 
 
1166
 
String *Swig_typemap_lookup(const String_or_char *op, SwigType *type, String_or_char *pname,
1167
 
                            String_or_char *lname, String_or_char *source, String_or_char *target, Wrapper *f) {
1168
 
  Hash *tm;
1169
 
  String *s = 0;
1170
 
  SwigType *mtype = 0;
1171
 
  ParmList *locals;
1172
 
  tm = Swig_typemap_search(op, type, pname, &mtype);
1173
 
  if (!tm)
1174
 
    return 0;
1175
 
 
1176
 
  s = Getattr(tm, "code");
1177
 
  if (!s) {
1178
 
    if (mtype)
1179
 
      Delete(mtype);
1180
 
    return 0;
1181
 
  }
1182
 
 
1183
 
 
1184
 
  /* Blocked */
1185
 
  if (Cmp(s, "pass") == 0) {
1186
 
    Delete(mtype);
1187
 
    return 0;
1188
 
  }
1189
 
 
1190
 
  s = Copy(s);                  /* Make a local copy of the typemap code */
1191
 
 
1192
 
  locals = Getattr(tm, "locals");
1193
 
  if (locals)
1194
 
    locals = CopyParmList(locals);
1195
 
 
1196
 
  /* This is wrong.  It replaces locals in place.   Need to fix this */
1197
 
  if (mtype && SwigType_isarray(mtype)) {
1198
 
    typemap_replace_vars(s, locals, mtype, type, pname, lname, 1);
1199
 
  } else {
1200
 
    typemap_replace_vars(s, locals, type, type, pname, lname, 1);
1201
 
  }
1202
 
 
1203
 
  if (locals && f) {
1204
 
    typemap_locals(s, locals, f, -1);
1205
 
  }
1206
 
 
1207
 
  replace_embedded_typemap(s);
1208
 
 
1209
 
  /* Now perform character replacements */
1210
 
  Replace(s, "$source", source, DOH_REPLACE_ANY);
1211
 
  Replace(s, "$target", target, DOH_REPLACE_ANY);
1212
 
 
1213
 
  /*  {
1214
 
     String *tmname = Getattr(tm,"typemap");
1215
 
     if (tmname) Replace(s,"$typemap",tmname, DOH_REPLACE_ANY);
1216
 
     }
1217
 
   */
1218
 
 
1219
 
  Replace(s, "$parmname", pname, DOH_REPLACE_ANY);
1220
 
  /*  Replace(s,"$name",pname,DOH_REPLACE_ANY); */
1221
 
 
1222
 
  Delete(locals);
1223
 
  Delete(mtype);
1224
 
  return s;
1225
 
}
1226
 
 
1227
 
/* -----------------------------------------------------------------------------
1228
 
 * Swig_typemap_lookup_new()
1229
 
 *
1230
 
 * Attach one or more typemaps to a node
1231
 
 * op    - typemap name, eg "out", "newfree"
1232
 
 * node  - the node to attach the typemaps to
1233
 
 * lname -
1234
 
 * f     -
1235
 
 * ----------------------------------------------------------------------------- */
1236
 
 
1237
 
String *Swig_typemap_lookup_new(const String_or_char *op, Node *node, const String_or_char *lname, Wrapper *f) {
 
1165
 * Attach one or more typemaps to a node and optionally generate the typemap contents
 
1166
 * into the wrapper.
 
1167
 * op         - typemap name, eg "out", "newfree"
 
1168
 * node       - the node to attach the typemaps to
 
1169
 * lname      - name of variable to substitute $1, $2 etc for
 
1170
 * f          - wrapper code to generate into if non null
 
1171
 * actioncode - code to generate into f before the out typemap code, unless
 
1172
 *              the optimal attribute is set in the out typemap in which case
 
1173
 *              $1 in the out typemap will be replaced  by the code in actioncode.
 
1174
 * ----------------------------------------------------------------------------- */
 
1175
 
 
1176
static String *Swig_typemap_lookup_impl(const String_or_char *op, Node *node, const String_or_char *lname, Wrapper *f, String *actioncode) {
1238
1177
  SwigType *type;
1239
1178
  SwigType *mtype = 0;
1240
1179
  String *pname;
1248
1187
  String *cname = 0;
1249
1188
  String *clname = 0;
1250
1189
  char *cop = Char(op);
 
1190
  int optimal_attribute = 0;
 
1191
  int optimal_substitution = 0;
 
1192
  int num_substitutions = 0;
 
1193
 
1251
1194
  /* special case, we need to check for 'ref' call 
1252
1195
     and set the default code 'sdef' */
1253
1196
  if (node && Cmp(op, "newfree") == 0) {
1297
1240
 
1298
1241
  s = Copy(s);                  /* Make a local copy of the typemap code */
1299
1242
 
 
1243
  /* Attach kwargs - ie the typemap attributes */
 
1244
  kw = Getattr(tm, "kwargs");
 
1245
  while (kw) {
 
1246
    String *value = Copy(Getattr(kw, "value"));
 
1247
    String *type = Getattr(kw, "type");
 
1248
    char *ckwname = Char(Getattr(kw, "name"));
 
1249
    if (type) {
 
1250
      String *mangle = Swig_string_mangle(type);
 
1251
      Append(value, mangle);
 
1252
      Delete(mangle);
 
1253
    }
 
1254
    sprintf(temp, "%s:%s", cop, ckwname);
 
1255
    Setattr(node, tmop_name(temp), value);
 
1256
    if (Cmp(temp, "out:optimal") == 0)
 
1257
      optimal_attribute = (Cmp(value, "0") != 0) ? 1 : 0;
 
1258
    Delete(value);
 
1259
    kw = nextSibling(kw);
 
1260
  }
 
1261
  
 
1262
  if (optimal_attribute) {
 
1263
    /* Note: "out" typemap is the only typemap that will have the "optimal" attribute set.
 
1264
     * If f and actioncode are NULL, then the caller is just looking to attach the "out" attributes
 
1265
     * ie, not use the typemap code, otherwise both f and actioncode must be non null. */
 
1266
    if (actioncode) {
 
1267
      clname = Copy(actioncode);
 
1268
      /* check that the code in the typemap can be used in this optimal way.
 
1269
       * The code should be in the form "result = ...;\n". We need to extract
 
1270
       * the "..." part. This may not be possible for various reasons, eg
 
1271
       * code added by %exception. This optimal code generation is bit of a
 
1272
       * hack and circumvents the normal requirement for a temporary variable 
 
1273
       * to hold the result returned from a wrapped function call.
 
1274
       */
 
1275
      if (Strncmp(clname, "result = ", 9) == 0) {
 
1276
        int numreplacements = Replace(clname, "result = ", "", DOH_REPLACE_ID_BEGIN);
 
1277
        if (numreplacements == 1) {
 
1278
          numreplacements = Replace(clname, ";\n", "", DOH_REPLACE_ID_END);
 
1279
          if (numreplacements == 1) {
 
1280
            if (Strchr(clname, ';') == 0) {
 
1281
              lname = clname;
 
1282
              actioncode = 0;
 
1283
              optimal_substitution = 1;
 
1284
            }
 
1285
          }
 
1286
        }
 
1287
      }
 
1288
      if (!optimal_substitution) {
 
1289
        Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_IGNORED, Getfile(node), Getline(node), "Method %s usage of the optimal attribute in the out typemap at %s:%d ignored as the following cannot be used to generate optimal code: %s\n", Swig_name_decl(node), Getfile(s), Getline(s), clname);
 
1290
        Delattr(node, "tmap:out:optimal");
 
1291
      }
 
1292
    } else {
 
1293
      assert(!f);
 
1294
    }
 
1295
  }
 
1296
  if (actioncode) {
 
1297
    assert(f);
 
1298
    Append(f->code, actioncode);
 
1299
  }
 
1300
 
 
1301
  /* emit local variables declared in typemap, eg emit declarations for aa and bb in:
 
1302
   * %typemap(in) foo (int aa, int bb) "..." */
1300
1303
  locals = Getattr(tm, "locals");
1301
1304
  if (locals)
1302
1305
    locals = CopyParmList(locals);
1313
1316
  }
1314
1317
 
1315
1318
  if (mtype && SwigType_isarray(mtype)) {
1316
 
    typemap_replace_vars(s, locals, mtype, type, pname, (char *) lname, 1);
 
1319
    num_substitutions = typemap_replace_vars(s, locals, mtype, type, pname, (char *) lname, 1);
1317
1320
  } else {
1318
 
    typemap_replace_vars(s, locals, type, type, pname, (char *) lname, 1);
 
1321
    num_substitutions = typemap_replace_vars(s, locals, type, type, pname, (char *) lname, 1);
1319
1322
  }
 
1323
  if (optimal_substitution && num_substitutions > 1)
 
1324
    Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_MULTIPLE, Getfile(node), Getline(node), "Multiple calls to %s might be generated due to optimal attribute usage in the out typemap at %s:%d.\n", Swig_name_decl(node), Getfile(s), Getline(s));
1320
1325
 
1321
1326
  if (locals && f) {
1322
1327
    typemap_locals(s, locals, f, -1);
1323
1328
  }
1324
1329
  replace_embedded_typemap(s);
1325
 
  /*  {
1326
 
     String *tmname = Getattr(tm,"typemap");
1327
 
     if (tmname) Replace(s,"$typemap",tmname, DOH_REPLACE_ANY);
1328
 
     } */
1329
1330
 
1330
1331
  Replace(s, "$name", pname, DOH_REPLACE_ANY);
1331
1332
 
1346
1347
    Setattr(node, tmop_name(temp), "1");
1347
1348
  }
1348
1349
 
1349
 
  /* Attach kwargs */
1350
 
  kw = Getattr(tm, "kwargs");
1351
 
  while (kw) {
1352
 
    String *value = Copy(Getattr(kw, "value"));
1353
 
    String *type = Getattr(kw, "type");
1354
 
    char *ckwname = Char(Getattr(kw, "name"));
1355
 
    if (type) {
1356
 
      String *mangle = Swig_string_mangle(type);
1357
 
      Append(value, mangle);
1358
 
      Delete(mangle);
1359
 
    }
1360
 
    sprintf(temp, "%s:%s", cop, ckwname);
1361
 
    Setattr(node, tmop_name(temp), value);
1362
 
    Delete(value);
1363
 
    kw = nextSibling(kw);
1364
 
  }
1365
 
 
1366
1350
  /* Look for warnings */
1367
1351
  {
1368
1352
    String *w;
1387
1371
    }
1388
1372
  }
1389
1373
 
1390
 
  if (cname)
1391
 
    Delete(cname);
1392
 
  if (clname)
1393
 
    Delete(clname);
1394
 
  if (mtype)
1395
 
    Delete(mtype);
 
1374
  Delete(cname);
 
1375
  Delete(clname);
 
1376
  Delete(mtype);
1396
1377
  if (sdef) {                   /* put 'ref' and 'newfree' codes together */
1397
1378
    String *p = NewStringf("%s\n%s", sdef, s);
1398
1379
    Delete(s);
1399
1380
    Delete(sdef);
1400
1381
    s = p;
1401
1382
  }
 
1383
  Delete(actioncode);
1402
1384
  return s;
1403
1385
}
1404
1386
 
 
1387
String *Swig_typemap_lookup_out(const String_or_char *op, Node *node, const String_or_char *lname, Wrapper *f, String *actioncode) {
 
1388
  assert(actioncode);
 
1389
  assert(Cmp(op, "out") == 0);
 
1390
  return Swig_typemap_lookup_impl(op, node, lname, f, actioncode);
 
1391
}
 
1392
 
 
1393
String *Swig_typemap_lookup(const String_or_char *op, Node *node, const String_or_char *lname, Wrapper *f) {
 
1394
  return Swig_typemap_lookup_impl(op, node, lname, f, 0);
 
1395
}
 
1396
 
 
1397
 
1405
1398
/* -----------------------------------------------------------------------------
1406
1399
 * Swig_typemap_attach_kwargs()
1407
1400
 *