#Saluton Emacson! Bonvolu elekti -*- mode: awk; -*-. Dankon.

BEGIN{
  headerfile="wrapped.h";
  deffile="wrapdef.h";
  structfile="wrapstruct.h";
  tmpffile="wraptmpf.h";
  FS=";";
  WARNING="/* Automatically generated file. Do not edit. Edit wrapawk_macosx/wrapfunc.inp. */";
  print WARNING > headerfile;
  print "#ifndef WRAPPED_H" > headerfile;
  print "#define WRAPPED_H" > headerfile;
  print "#define MY_GLUE2(a,b) a ## b"      > headerfile;
  print "#define MY_DEF(a) MY_GLUE2(my_,a)" > headerfile;
  print WARNING > deffile;
  print "#ifndef WRAPDEF_H" > deffile;
  print "#define WRAPDEF_H" > deffile;
  print WARNING > tmpffile;
  print "#ifndef WRAPTMPF_H" > tmpffile;
  print "#define WRAPTMPF_H" > tmpffile;
  print WARNING > structfile;
  print "#ifndef WRAPSTRUCT_H" > structfile;
  print "#define WRAPSTRUCT_H" > structfile;
  print "typedef struct interpose_s {"      > structfile;
  print "  void *new_func;"                 > structfile;
  print "  void *orig_func;"                > structfile;
  print "} interpose_t;"                    > structfile;
  print "#define INTERPOSE(newf,oldf) \\"   > structfile;
  print "  __attribute__((used)) static const interpose_t MY_GLUE2(_interpose_,oldf) \\" > structfile;
  print "    __attribute__((section(\"__DATA,__interpose\"))) = {(void *)newf, (void *)oldf}" > structfile;
  print ""                                  > structfile;
}

/\/\*/{
}
/^(\#)/{
  print $0 > structfile;
  print $0 > tmpffile;
  print $0 > deffile;
  print $0 > headerfile;

}
/^[^\/].*;.*;.*/{
  name=$1;
  ret=$2;
  argtype=$3;
  argname=$4;
  MACRO=$5;
  if(MACRO){
    print "extern " ret " MY_DEF(" name ")" argtype " __attribute__((visibility(\"hidden\")));" > headerfile;
    print "INTERPOSE(MY_DEF(" name "_RAW)," name "_RAW);"   > structfile;
    print "#undef " name                      > deffile
    print "#define " name " MY_DEF(" name "_RAW)" > deffile

    print "extern " ret, name, argtype ";"              > tmpffile;
    print "static __inline__ " ret " NEXT_" MACRO "_NOARG " argtype " __attribute__((always_inline));" > tmpffile;
    print "static __inline__ " ret " NEXT_" MACRO "_NOARG " argtype " {" > tmpffile;
    print "  return " name, argname ";"                 > tmpffile;
    print "}"                                           > tmpffile;
    print ""                                            > tmpffile;
  } else {
    print "extern " ret " my_" name, argtype " __attribute__((visibility(\"hidden\")));" > headerfile;
    print "#undef " name                                > structfile;
    print "INTERPOSE(my_" name "," name ");"            > structfile;
    print "#define " name " my_" name                   > structfile
    print "#define " name " my_" name                   > deffile

    print "extern " ret, name, argtype ";"              > tmpffile;
    if(argname){
        print "static __inline__ " ret " next_" name, argtype " __attribute__((always_inline));" > tmpffile;
        print "static __inline__ " ret " next_" name, argtype " {" > tmpffile;
        print "  return " name, argname ";"             > tmpffile;
        print "}"                                       > tmpffile;
    }
    print ""                                            > tmpffile;
  }
}

/^ *$/{
  print > structfile;
  print > headerfile;
  print > deffile;
  print > tmpffile;
}

END{
  print ""                > structfile;
  print "struct next_wrap_st next_wrap[]= {" > structfile;
  print "  {NULL, NULL}," > structfile;
  print "};"              > structfile;
  print "#endif"          > structfile;
  print "#endif"          > tmpffile;
  print "#endif"          > deffile;
  print "#endif"          > headerfile;
}
