Warning: this is an htmlized version!
The original is across this link,
and the conversion rules are here.
#######
#
# E-scripts about Swig.
#
# Note 1: use the eev command (defined in eev.el) and the
# ee alias (in my .zshrc) to execute parts of this file.
# Executing this file as a whole makes no sense.
#
# Note 2: be VERY careful and make sure you understand what
# you're doing.
#
# Note 3: If you use a shell other than zsh things like |&
# and the for loops may not work.
#
# Note 4: I always run as root.
#
# Note 5: some parts are too old and don't work anymore. Some
# never worked.
#
# Note 6: the definitions for the find-xxxfile commands are on my
# .emacs.
#
# Note 7: if you see a strange command check my .zshrc -- it may
# be defined there as a function or an alias.
#
# Note 8: the sections without dates are always older than the
# sections with dates.
#
# This file is at <http://angg.twu.net/e/swig.e>
#           or at <http://angg.twu.net/e/swig.e.html>.
#        See also <http://angg.twu.net/emacs.html>,
#                 <http://angg.twu.net/.emacs[.html]>,
#                 <http://angg.twu.net/.zshrc[.html]>,
#                 <http://angg.twu.net/escripts.html>,
#             and <http://angg.twu.net/>.
#
#######





# «.swig-debian»		(to "swig-debian")
# «.swig-upstream»		(to "swig-upstream")
# «.swig-lua-compile»		(to "swig-lua-compile")
# «.swig-lua-examples»		(to "swig-lua-examples")
# «.swig-docs»			(to "swig-docs")
# «.single-source»		(to "single-source")
# «.making-L-accessible»	(to "making-L-accessible")
# «.making-L-accessible-long»	(to "making-L-accessible-long")
# «.mla.c»			(to "mla.c")
# «.returning-malloced-blocks»	(to "returning-malloced-blocks")
# «.C-types-as-strings»		(to "C-types-as-strings")
# «.myswiglua»			(to "myswiglua")






#####
#
# Swig for Debian (2012)
# 2012mar04
#
#####

# «swig-debian»  (to ".swig-debian")
# (find-status   "swig")
# (find-vldifile "swig.list")
# (find-udfile   "swig/")
# (find-status   "swig-doc")
# (find-vldifile "swig-doc.list")
# (find-udfile   "swig-doc/")
# (find-status   "swig-examples")
# (find-vldifile "swig-examples.list")
# (find-udfile   "swig-examples/")
# (find-fline "/usr/share/doc/swig-examples/lua/")




#####
#
# swig from sarge (too old - doesn't support Lua)
# 2006jun22
#
#####

# (find-status   "swig")
# (find-vldifile "swig.list")
# (find-udfile   "swig/")





#####
#
# swig-1.3.29 (upstream)
# 2006jun22
#
#####

# http://heanet.dl.sourceforge.net/sourceforge/swig/swig-1.3.29.tar.gz
# (code-c-d "swig" "~/usrc/swig-1.3.29/")
# (find-swigfile "")
# (find-swigfile "configure.in" "--with-lua=path")
# (find-zsh "set | grep -a LUA")
# (find-fline "$LUASRC/")
# (find-swigfile "oc")
# (find-swigfile "oc" "checking for lua")
# (find-swigfile "om")
# (find-swigfile "omi")
#*
# «swig-upstream»  (to ".swig-upstream")
# «swig-lua-compile»  (to ".swig-lua-compile")
# (find-angg ".zshrc" "lua" "SWIGSRC")

rm -Rv ~/usrc/swig-1.3.29/
tar -C ~/usrc/ -xvzf \
  $S/http/heanet.dl.sourceforge.net/sourceforge/swig/swig-1.3.29.tar.gz
cd     ~/usrc/swig-1.3.29/

# ./configure |& tee oc
  ./configure \
    --with-lua=$LUASRC/bin/lua \
    --with-luaincl=$LUASRC/include \
    --with-lualib=$LUASRC/lib \
  |& tee oc

# make install is semi-dummy, "--prefix=/tmp/ulocal" is not needed

make |& tee om
make |& tee omi
cd ~/usrc/swig-1.3.29/Examples/lua/class/     && make |& tee om
cd ~/usrc/swig-1.3.29/Examples/lua/constants/ && make |& tee om
cd ~/usrc/swig-1.3.29/Examples/lua/functest/  && make |& tee om
cd ~/usrc/swig-1.3.29/Examples/lua/pointer/   && make |& tee om
cd ~/usrc/swig-1.3.29/Examples/lua/simple/    && make |& tee om
cd ~/usrc/swig-1.3.29/Examples/lua/variables/ && make |& tee om

#*
# «swig-lua-examples»  (to ".swig-lua-examples")
# (find-swigfile "oc")
# (find-swigfile "om")
# (find-swigfile "omi")
# (find-swigfile "Examples/lua/")
# (find-swigfile "Examples/lua/check.list")
# (find-swigfile "Examples/lua/class/")
# (find-swigfile "Examples/lua/constants/")
# (find-swigfile "Examples/lua/functest/")
# (find-swigfile "Examples/lua/pointer/")
# (find-swigfile "Examples/lua/simple/")
# (find-swigfile "Examples/lua/variables/")
# (find-swigfile "Examples/lua/simple/")
# (find-swigfile "Examples/lua/simple/om")
# (find-swigfile "Examples/lua/simple/runme.lua")
# (find-man "3 dlopen")

cd ~/usrc/swig-1.3.29/Examples/lua/class/
LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH \
  lua50 runme.lua |& tee o
cd ~/usrc/swig-1.3.29/Examples/lua/constants/
LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH \
  lua50 runme.lua |& tee o
cd ~/usrc/swig-1.3.29/Examples/lua/functest/
LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH \
  lua50 runme.lua |& tee o
cd ~/usrc/swig-1.3.29/Examples/lua/pointer/
LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH \
  lua50 runme.lua |& tee o
cd ~/usrc/swig-1.3.29/Examples/lua/simple/
LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH \
  lua50 runme.lua |& tee o
cd ~/usrc/swig-1.3.29/Examples/lua/variables/
LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH \
  lua50 runme.lua |& tee o

#*
# (find-swigfile "Examples/Makefile" "lua:")

# (find-node "(gcc)Preprocessor Options" "`-isystem DIR'")

# (find-swigfile "")
# (find-swigfile "Doc/")
# (find-swigw3m  "Doc/Manual/Lua.html")
# (find-swigw3m  "Doc/Manual/Lua.html" "If you specify `module example'")
# (find-swigfile "Examples/lua/")
# (find-fline "/tmp/swiglua/")

# (find-swigsh "find")
# (find-swigfile "preinst-swig")




#####
#
# swig docs
# 2006jun27
#
#####

# «swig-docs»  (to ".swig-docs")
# (find-es "swig")
# (find-swigmanualfile "")
# file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/SWIG.html




#####
#
# A file that is both a .c and a swig interface file (.swg/.i)
# 2006jun27
#
#####

# «single-source»  (to ".single-source")
# (find-swigfile "Examples/lua/simple/")
# (find-node "(cpp)Else")
# (find-swigmanualw3m "Preprocessor.html")
# (find-swigmanualw3m "Preprocessor.html" "defined when SWIG is processing")
# (find-swigmanualw3m "Preprocessor.html#Preprocessor_condition_compilation")
# (find-swigmanualw3m "Preprocessor.html" "SWIGLUA")
#*
rm -Rv /tmp/swig/
mkdir  /tmp/swig/
cd     /tmp/swig/

cat > example.c <<'---'
#ifdef SWIG
%module example
%inline %{
extern int    gcd(int x, int y);
extern double Foo;
%}
#else /* Not SWIG */
double Foo = 3.0;
int gcd(int x, int y) {
  int g = y;
  while (x > 0) {
    g = x;
    x = y % x;
    y = g;
  }
  return g;
}
#endif /* Not SWIG */
---

cat > runme.lua <<'---'
lib = loadlib('example.so','Example_Init')
assert(lib)()
x = 42
y = 105
g = example.gcd(x,y)
print("The gcd of",x,"and",y,"is",g)
print("Foo = ", example.Foo)
example.Foo = 3.1415926
print("Foo = ", example.Foo)
---

# (find-swigfile "preinst-swig")
# (find-swigfile "Examples/lua/simple/om")
# (find-node "(gcc)Code Gen Options" "`-fpic'")
# (find-node "(gcc)Overall Options" "more than one input file")

~/usrc/swig-1.3.29/preinst-swig -lua example.c
laf
gcc -shared \
  -L       $HOME/usrc/lua-5.0.2/lib -llua -llualib \
  -isystem $HOME/usrc/lua-5.0.2/include \
  -g \
  -o example.so \
  example.c example_wrap.c
lua50 runme.lua
laf

#*
# (find-sh "set | grep -a src/lua")





#####
#
# real-world tests: titanl
# 2006jun29
#
#####

# (find-eevex "lua.e")
# (find-eevex "lua.e" "lua-gdb-1")
# (find-es "swig")
# (find-es "swig" "single-source")
# (find-fline "titanl_wrap.c")
# (find-efunction 'eeb-gdb-start)

#*
cd ~/TITAN/
$SWIGSRC/preinst-swig -lua titanl.c
gcc -L     $LUA50SRC/lib -llua -llualib \
  -isystem $LUA50SRC/include \
  -g -shared -o titanl.so \
  titanl.c titanl_wrap.c

# If there are any broken symbols this will report them:
lua50 -e 'print(loadlib("./titanl.so", "Titanl_Init"))'

cat > runme.lua <<'---'
  lib = loadlib("./titanl.so", "Titanl_Init")
  assert(lib)()
  math.sin(0)
  print(titanl.parse_prog_get_max_jump("foo :123 :325 :102 bar"))
---

lua50 runme.lua

#*
# (ee-once (eeb-luagdb-start "bin/lua"))
# br loadlib
set args runme.lua
cd ~/TITAN/
br math_sin
run
br parse_prog_get_max_jump
# cont

#*

# (find-angg "LUA/lua50init.lua" "load_PP")
source ~/.lua50/PP.gdb







#####
#
# calling Lua back from a C function (making L accessible)
# This is the short demo, the long demo is below...
# 2006jul14
#
#####

# «making-L-accessible»  (to ".making-L-accessible")
# (find-angg "SWIG/demo_luaClua.c")
#*
rm -Rv /tmp/mla/
mkdir  /tmp/mla/
cd     /tmp/mla/

cat > mla.c <<'---'
#ifdef SWIG
%module C
%typemap(in) lua_State *L "$1 = L;"
%inline %{
  extern int foo(char *str, int n, lua_State *L);
%}
#else /* Not SWIG */
#include "lua.h"
#include "lauxlib.h"
void foo(char *str, int n, lua_State *L) {
  printf("C.foo: str=\"%s\", n=%d\n", str, n);
  lua_pushstring(L, "bar");                              /* function name */
  lua_gettable(L, LUA_GLOBALSINDEX);             /* function to be called */
  lua_call(L, 0, 0);      /* call function with 0 arguments and 0 results */
}
#endif /* Not SWIG */
---

cat > runme.lua <<'---'
assert(loadlib('mla.so','C_Init'))()
bar = function () print("bar: hello!") end
C.foo("abc", 154)
print("bye!")
---

# (find-angg ".zshrc" "lua" "SWIGSRC")

$SWIGSRC/preinst-swig -lua mla.c
gcc -L $LUA50SRC/lib -llua -llualib -isystem $LUA50SRC/include \
  -shared -g   -o mla.so   mla.c mla_wrap.c

lua50 runme.lua

#*





#####
#
# calling Lua back from a C function (making L accessible)
# This is the long demo, there's a shorter one above.
# 2006jul14
#
#####

# «making-L-accessible-long»  (to ".making-L-accessible-long")

<edrx> a swig-lua question, maybe a bit hurried... I'm writing a
       function in C, called (say) "process_record", that parses
       "records" very quickly... I use swig to call this function from
       Lua, and that's working fine
<edrx> but parse_record needs to call a function in Lua called
       "traced_p" to check if a certain field of the record is
       "traced"... the problem: to call Lua back I need the "L" of the
       Lua environment that called the C function...
<edrx> reading parserecord_wrap.c, generated by swig...
<Wallbraker> edrx: you could do a typemap for lua_State
<Wallbraker> abit of a hack but hey.
<edrx> makes sense, lemme find out how...
<Wallbraker> %typemap %typemap(in) lua_State
<edrx> thanks :)
<Wallbraker> %{$1 = L; %}
<Wallbraker> now this is not a small hack tho, make shure you have the
             lua_State last in the argument

# (find-swigmanualw3m "SWIG.html")
# (find-swigmanualw3m "Typemaps.html")
# (find-swigmanualw3m "Typemaps.html#Typemaps_nn4")
# (find-swigmanualfile "")
# file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/Typemaps.html
# file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/Typemaps.html#Typemaps_mixed_default

# (find-swigfile "")
# (find-swigfile "Lib/lua/")
# (find-swigfile "Lib/lua/lua.swg")
# (find-swigfile "Lib/lua/luarun.swg")
# (find-swigfile "Lib/lua/typemaps.i")
# (find-swigsh "find | grep -i lua")

%typemap %typemap(in) lua_State
%{ $1 = L; %}

# Bad syntax: this thing doesn't work yet
# «mla.c»  (to ".mla.c")
# (find-es "lua5" "monitored_p_C")
#*
rm -Rv /tmp/mla/
mkdir  /tmp/mla/
cd     /tmp/mla/

cat > mla.c <<'---'
#ifdef SWIG
%module C
%typemap(in) lua_State *L "$1 = L;"
%inline %{
  extern int foo(char *str, int n, lua_State *L);
%}
#else /* Not SWIG */
  /*
   * (find-node "(cpp)The preprocessing language" "before and after the `#'")
   * (find-lua50file "include/")
   * (find-lua50file "include/lua.h" "#define LUA_GLOBALSINDEX")
   * (find-luamanual-ff  "pushing")
   * (find-luamanualw3m+ "pushing")
   * (find-luamanualw3m+ "lua-to" "lua_tonumber converts the Lua value")
   * (find-luamanualw3m+ "3.14" "lua_call")
   * (find-fline "/tmp/mla/")
   * (find-fline "/tmp/mla/mla_wrap.c" "_wrap_foo")
   * (find-swigfile "")
   */
  #include "lua.h"
  #include "lauxlib.h"
  int foo(char *str, int n, lua_State *L) {
    int subfoo_result;
    printf("C.foo:  depth at the beginning: %d\n", lua_gettop(L));
    lua_pushstring(L, "subfoo");                        /* function name */
    lua_gettable(L, LUA_GLOBALSINDEX);          /* function to be called */
    lua_pushstring(L, str[0] ? str+1 : "empty");         /* 1st argument */
    lua_pushnumber(L, n*10);                             /* 2nd argument */
    lua_call(L, 2, 1);    /* call function with 2 arguments and 1 result */
      /* now convert the returned value to an int and return it (plus 5) */
    subfoo_result = lua_tonumber(L, -1);  /* index=-1 means top of stack */
    lua_pop(L, 1);                          /* remove results from stack */
    printf("C.foo:  depth after lua_pop:    %d\n", lua_gettop(L));
    return subfoo_result + 5;
  }
#endif /* Not SWIG */
---

cat > runme.lua <<'---'
assert(loadlib('mla.so','C_Init'))()
PP(C)
subfoo = function (str, n) print("subfoo: received:", str, n); return 40 end
math.sin(0)
print("subfoo should receive and print: \"bcdef\" 99*10")
print("           and it should return: 40+5")
print("main:   C.foo returned:", C.foo("abcdef", 99))
---

~/usrc/swig-1.3.29/preinst-swig -lua mla.c

cd /tmp/mla/
gcc -shared \
  -L       $HOME/usrc/lua-5.0.2/lib -llua -llualib \
  -isystem $HOME/usrc/lua-5.0.2/include \
  -g \
  -o mla.so \
  mla.c mla_wrap.c

laf
lua50 runme.lua

#*


cat > runme.lua <<'---'
  lib = loadlib("./titanl.so", "Titanl_Init")
  assert(lib)()
  math.sin(0)
  print(titanl.parse_prog_get_max_jump("foo :123 :325 :102 bar"))
---

lua50 runme.lua

#*
# (ee-once (eeb-luagdb-start "bin/lua"))
# br loadlib
set args runme.lua
cd ~/tmp/mla/
br math_sin
run
br foo_wrap
# cont

#*


# (find-sh "set | grep -a src/lua")

laf


# (find-node "(cpp)The preprocessing language" "before and after the `#'")







#####
#
# C functions that return malloc'ed blocks to Lua 
# 2006jul20
#
#####

# «returning-malloced-blocks»  (to ".returning-malloced-blocks")
# (find-angg "SWIG/demo_retlstring.c")
# (find-swigmanualfile "")
# (find-swigmanualw3m "")
# file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/
# file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/SWIG.html
# file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/SWIG.html#SWIG_nn32
# file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/Lua.html
# file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/Typemaps.html
# (find-swigmanualw3m "SWIG.html" "%inline")
#*
rm -Rv /tmp/malbl/
mkdir  /tmp/malbl/
cd     /tmp/malbl/

cat > malbl.c <<'---'
typedef struct malloced_block {
  void *ptr;
  int len;
} malloced_block;

#ifdef SWIG
%module C
%typemap(out) malloced_block %{
  lua_pushstring(L, $1.ptr, $1.len);
  free($1.ptr);
%}
%inline %{
  extern malloced_block foo(void);
%}
#else /* Not SWIG */
#include <stdlib.h>
#include <string.h>

malloced_block foo(void) {
  malloced_block mb;
  mb.ptr = malloc(7);
  mb.len = 7;
  strcpy(mb.ptr, "Hello!");
  return mb;
}

#endif
---

cat > runme.lua <<'---'
assert(loadlib('malbl.so','C_Init'))()
print(C.foo())
---

$SWIGSRC/preinst-swig -lua malbl.c
gcc -L $LUA50SRC/lib -llua -llualib -isystem $LUA50SRC/include \
  -Wall \
  -shared -g   -o malbl.so   malbl.c malbl_wrap.c

lua50 runme.lua

#*

# (find-angg ".zshrc" "lua" "SWIGSRC")





#####
#
# swig's encoding of C types as strings
# 2006jul21
#
#####

# «C-types-as-strings»  (to ".C-types-as-strings")
# (find-es "anatocc" "cdecl")
# file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/Extending.html#Extending_nn24
# (find-swigmanualw3m "Extending.html#Extending_nn24")

  C datatype               SWIG encoding (strings)
  -----------------------  -------------------------
  int                      "int"
  int *                    "p.int"
  const int *              "p.q(const).int"
  int (*x)(int,double)     "p.f(int,double).int"
  int [20][30]             "a(20).a(30).int"
  int (F::*)(int)          "m(F).f(int).int"
  vector<int> *            "p.vector<(int)>"




#####
#
# how %inline works
# 2006jul21
#
#####

file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/SWIG.html
file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/SWIG.html#SWIG_nn43

file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/Typemaps.html

<edrx> is it possible to use typemaps to create new "primitive" types,
       like int? I just read the section "string encoding of types" in
       the "Extending Swig" section of the manual...
<edrx> actually I'm a newcomer to swig - I'm trying to find a way to
       have C functions that malloc a region of memory and then return
       that region (a pointer + a length) as a Lua string...
<edrx> my idea was to use a typemap and something like
<edrx> %typemap(out) lstring %{ lua_pushlstring(L, $1.ptr, $1.len);
       free($1.ptr); %}
<edrx> but to make things cleaner I'd like to tell swig to not look
       inside lstrings and do not provide accessor functions





#####
#
# myswiglua
# 2006jul24
#
#####

# «myswiglua»  (to ".myswiglua")
# (find-angg ".zshrc" "swig")
# (find-angg "LUA/lua50init.lua" "loadswigso")




# file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/Contents.html





#  Local Variables:
#  coding:               raw-text-unix
#  ee-delimiter-hash:    "\n#*\n"
#  ee-delimiter-percent: "\n%*\n"
#  ee-anchor-format:     "«%s»"
#  End: