Update of /cvsroot/mingw/msys/packages/gawk/3.1.5/extension In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv30392/3.1.5/extension Added Files: ChangeLog Makefile.pc arrayparm.c dl.c doit filefuncs.c foo.awk fork.c ordchr.c pcext.def readfile.c steps testarg.awk testarg.c testarrayparm.awk testff.awk testfork.awk testordchr.awk xreadlink.c xreadlink.h Log Message: Update package --- NEW FILE: testarg.c --- #include "awk.h" static NODE * do_check_arg(tree) NODE *tree; { int ret = 0, argc; NODE *arg1, *arg2, *arg3; argc = get_curfunc_arg_count(); printf("arg count: defined = %d, supplied = %d\n", tree->param_cnt, argc); arg1 = get_scalar_argument(tree, 0, FALSE); arg2 = get_array_argument(tree, 1, FALSE); arg3 = get_scalar_argument(tree, 2, TRUE); /* optional */ if (argc > 3) { /* try to use an extra arg */ NODE *arg4; arg4 = get_array_argument(tree, 3, TRUE); } if (arg3 != NULL) printf("3rd arg present\n\n"); else printf("no 3rd arg\n\n"); /* Set the return value */ set_value(tmp_number((AWKNUM) ret)); /* Just to make the interpreter happy */ return tmp_number((AWKNUM) 0); } /* dlload --- load new builtins in this library */ NODE * dlload(tree, dl) NODE *tree; void *dl; { make_builtin("check_arg", do_check_arg, 3); return tmp_number((AWKNUM) 0); } --- NEW FILE: testarg.awk --- BEGIN { extension("./testarg.so", "dlload") check_arg(x, a); check_arg(y, b, z); check_arg(p, q, r, s); } --- NEW FILE: fork.c --- /* * fork.c - Provide fork and waitpid functions for gawk. * * Revised 6/2004 */ /* * Copyright (C) 2001, 2004 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Programming Language. * * GAWK is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * GAWK is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "awk.h" /* do_fork --- provide dynamically loaded fork() builtin for gawk */ static NODE * do_fork(tree) NODE *tree; { int ret = -1; NODE **aptr; if (do_lint && get_curfunc_arg_count() > 0) lintwarn("fork: called with too many arguments"); ret = fork(); if (ret < 0) update_ERRNO(); else if (ret == 0) { /* update PROCINFO in the child */ aptr = assoc_lookup(PROCINFO_node, tmp_string("pid", 3), FALSE); (*aptr)->numbr = (AWKNUM) getpid(); aptr = assoc_lookup(PROCINFO_node, tmp_string("ppid", 4), FALSE); (*aptr)->numbr = (AWKNUM) getppid(); } /* Set the return value */ set_value(tmp_number((AWKNUM) ret)); /* Just to make the interpreter happy */ return tmp_number((AWKNUM) 0); } /* do_waitpid --- provide dynamically loaded waitpid() builtin for gawk */ static NODE * do_waitpid(tree) NODE *tree; { NODE *pidnode; int ret = -1; double pidval; pid_t pid; int options = 0; if (do_lint && get_curfunc_arg_count() > 1) lintwarn("waitpid: called with too many arguments"); pidnode = get_argument(tree, 0); if (pidnode != NULL) { pidval = force_number(pidnode); pid = (int) pidval; options = WNOHANG|WUNTRACED; ret = waitpid(pid, NULL, options); if (ret < 0) update_ERRNO(); } else if (do_lint) lintwarn("wait: called with no arguments"); /* Set the return value */ set_value(tmp_number((AWKNUM) ret)); /* Just to make the interpreter happy */ return tmp_number((AWKNUM) 0); } /* dlload --- load new builtins in this library */ NODE * dlload(tree, dl) NODE *tree; void *dl; { make_builtin("fork", do_fork, 0); make_builtin("waitpid", do_waitpid, 1); return tmp_number((AWKNUM) 0); } --- NEW FILE: testfork.awk --- BEGIN { extension("./fork.so", "dlload") printf "before fork, pid = %d, ppid = %d\n", PROCINFO["pid"], PROCINFO["ppid"] fflush() ret = fork() if (ret < 0) printf("ret = %d, ERRNO = %s\n", ret, ERRNO) else if (ret == 0) printf "child, pid = %d, ppid = %d\n", PROCINFO["pid"], PROCINFO["ppid"] else { system("sleep 3") printf "parent, ret = %d\n", ret printf "parent, pid = %d, ppid = %d\n", PROCINFO["pid"], PROCINFO["ppid"] } } --- NEW FILE: ordchr.c --- /* * ordchr.c - Builtin functions that provide ord() and chr() functions. * * Arnold Robbins * ar...@sk... * 8/2001 * Revised 6/2004 */ /* * Copyright (C) 2001, 2004 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Programming Language. * * GAWK is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * GAWK is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "awk.h" /* do_ord --- return numeric value of first char of string */ static NODE * do_ord(tree) NODE *tree; { NODE *str; int ret = -1; if (do_lint && get_curfunc_arg_count() > 1) lintwarn("ord: called with too many arguments"); str = get_argument(tree, 0); if (str != NULL) { (void) force_string(str); ret = str->stptr[0]; free_temp(str); } else if (do_lint) lintwarn("ord: called with no arguments"); /* Set the return value */ set_value(tmp_number((AWKNUM) ret)); /* Just to make the interpreter happy */ return tmp_number((AWKNUM) 0); } /* do_chr --- turn numeric value into a string */ static NODE * do_chr(tree) NODE *tree; { NODE *num; unsigned int ret = 0; AWKNUM val = 0.0; char str[2]; str[0] = str[1] = '\0'; if (do_lint && get_curfunc_arg_count() > 1) lintwarn("chr: called with too many arguments"); num = get_argument(tree, 0); if (num != NULL) { val = force_number(num); ret = val; /* convert to int */ free_temp(num); ret &= 0xff; str[0] = ret; str[1] = '\0'; } else if (do_lint) lintwarn("chr: called with no arguments"); /* Set the return value */ set_value(tmp_string(str, 1)); /* Just to make the interpreter happy */ return tmp_number((AWKNUM) 0); } /* dlload --- load new builtins in this library */ NODE * dlload(tree, dl) NODE *tree; void *dl; { make_builtin("ord", do_ord, 1); make_builtin("chr", do_chr, 1); return tmp_number((AWKNUM) 0); } --- NEW FILE: ChangeLog --- Tue Jul 26 21:46:16 2005 Arnold D. Robbins <ar...@sk...> * Release 3.1.5: Release tar file made. Sun Jun 26 09:03:32 2005 Arnold D. Robbins <ar...@sk...> * filefuncs.c (do_stat): Check return value from readlink() for error. Pass in `sizeof(buf) - 1' to leave room for trailing zero byte. From: Glenn Zazulia <gn...@t1...>. Mon Aug 2 12:18:15 2004 Arnold D. Robbins <ar...@sk...> * Release 3.1.4: Release tar file made. Mon Jun 21 17:02:37 2004 Arnold D. Robbins <ar...@sk...> More from John Haque. * testarg.c, testarg.awk: New files. * arrayparm.c (do_mkarray): Change call of `get_curfunc_parm_count' to `get_curfunc_arg_count'. * filefuncs.c (do_chdir, do_stat): Ditto. * fork.c (do_fork, do_waitpid): Ditto. * ordchr.c (do_ord, do_chr): Ditto. * readfile.c (do_readfile): Ditto. * steps: Updated. Mon Jun 14 14:01:16 2004 Arnold D. Robbins <ar...@sk...> ChangeLog started. Changes from John Haque and ADR to rationalize extension functions. * extension/filefuncs.c: Revised for new functionality. See corresponding entry in main ChangeLog. --- NEW FILE: arrayparm.c --- /* * arrayparm.c --- figure out how to make a parameter be an array * * Arnold Robbins * ar...@sk... * 10/2001 * * Revised 7/2003 * Revised 6/2004 */ /* * Copyright (C) 2001, 2003, 2004 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Programming Language. * * GAWK is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * GAWK is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "awk.h" /* do_mkarray --- turn a variable into an array */ /* * From awk, call * * mkarray(var, sub, val) */ static NODE * do_mkarray(tree) NODE *tree; { int ret = -1; NODE *var, *sub, *val; NODE **elemval; if (do_lint && get_curfunc_arg_count() > 3) lintwarn("mkarray: called with too many arguments"); var = get_argument(tree, 0); if (var == NULL) var = stack_ptr[0]; var = get_array(var); sub = get_argument(tree, 1); val = get_argument(tree, 2); printf("var->type = %s\n", nodetype2str(var->type)); printf("sub->type = %s\n", nodetype2str(sub->type)); printf("val->type = %s\n", nodetype2str(val->type)); assoc_clear(var); elemval = assoc_lookup(var, sub, 0); *elemval = dupnode(val); ret = 0; /* Set the return value */ set_value(tmp_number((AWKNUM) ret)); /* Just to make the interpreter happy */ return tmp_number((AWKNUM) 0); } /* dlload --- load new builtins in this library */ NODE * dlload(tree, dl) NODE *tree; void *dl; { make_builtin("mkarray", do_mkarray, 3); return tmp_number((AWKNUM) 0); } --- NEW FILE: Makefile.pc --- # Makefile for gawk extensions Mar 2003 # - for GNU C (mingw32) [Windows32 executable for Windows 9x/NT] # - for Microsoft C 7 [16bit ececutable for DOS] # see README.pc for comments #------------------------------------------------------------------------ # Some makes do not define MAKE (and ndmake does not allow a define). # Define MAK to be your make command. #MAKE = dmake MAK = $(MAKE) $(MAKEFILE) #MAK = $(MAKE) #MAKEFILE = -f Makefile #MAK = make45 $(MAKEFILE) VCCFLAGS=-nologo -O2 -DWIN32 -DWIN32_EXTENSION -D__STDC__=0 -DGAWK -I.. -DHAVE_CONFIG_H -DDYNAMIC VCLDFLAGS=-LD ../gawk.lib VCCC=cl -nologo MWCFLAGS=-O -shared -DWIN32 -DWIN32_EXTENSION -DGAWK -I.. -DHAVE_CONFIG_H -DDYNAMIC MWLDFLAGS=-s -Wl,--enable-stdcall-fixup -L.. -lgawk MWCC=gcc # this DEFFILE will work provided the exported function is always called # dlload DEFFILE=pcext.def default: @echo "Enter $(MAK) target " @echo " where 'target' is chosen from " @echo " mingw32 . Windows32 exe [Mingw32 GNU C] " @echo " vcWin32 . Windows32 exe [Microsoft Visual C] " .SUFFIXES: .c .dll .c.dll: $(CC) $(CFLAGS) $< -o$@ $(LDFLAGS) $(DEFFILE) # dl.c, fork.c, and filefuncs.c don't compile cleanly... all : readfile.dll ordchr.dll arrayparm.dll vcWin32: $(MAK) CFLAGS="$(VCCFLAGS)" LDFLAGS="$(VCLDFLAGS)" CC="$(VCCC)" all mingw32: $(MAK) CFLAGS="$(MWCFLAGS)" LDFLAGS="$(MWLDFLAGS)" CC="$(MWCC)" all clean: -rm *.dll -rm *.o -rm *.obj -rm *.lib --- NEW FILE: filefuncs.c --- /* * filefuncs.c - Builtin functions that provide initial minimal iterface * to the file system. * * Arnold Robbins, update for 3.1, Mon Nov 23 12:53:39 EST 1998 * Arnold Robbins and John Haque, update for 3.1.4, applied Mon Jun 14 13:55:30 IDT 2004 */ /* * Copyright (C) 2001, 2004, 2005 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Programming Language. * * GAWK is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * GAWK is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "awk.h" #include <sys/sysmacros.h> /* do_chdir --- provide dynamically loaded chdir() builtin for gawk */ static NODE * do_chdir(tree) NODE *tree; { NODE *newdir; int ret = -1; if (do_lint && get_curfunc_arg_count() != 1) lintwarn("chdir: called with incorrect number of arguments"); newdir = get_scalar_argument(tree, 0, FALSE); (void) force_string(newdir); ret = chdir(newdir->stptr); if (ret < 0) update_ERRNO(); free_temp(newdir); /* Set the return value */ set_value(tmp_number((AWKNUM) ret)); /* Just to make the interpreter happy */ return tmp_number((AWKNUM) 0); } /* format_mode --- turn a stat mode field into something readable */ static char * format_mode(fmode) unsigned long fmode; { static char outbuf[12]; int i; strcpy(outbuf, "----------"); /* first, get the file type */ i = 0; switch (fmode & S_IFMT) { #ifdef S_IFSOCK case S_IFSOCK: outbuf[i] = 's'; break; #endif #ifdef S_IFLNK case S_IFLNK: outbuf[i] = 'l'; break; #endif case S_IFREG: outbuf[i] = '-'; /* redundant */ break; case S_IFBLK: outbuf[i] = 'b'; break; case S_IFDIR: outbuf[i] = 'd'; break; #ifdef S_IFDOOR /* Solaris weirdness */ case S_IFDOOR: outbuf[i] = 'D'; break; #endif /* S_IFDOOR */ case S_IFCHR: outbuf[i] = 'c'; break; #ifdef S_IFIFO case S_IFIFO: outbuf[i] = 'p'; break; #endif } i++; if ((fmode & S_IRUSR) != 0) outbuf[i] = 'r'; i++; if ((fmode & S_IWUSR) != 0) outbuf[i] = 'w'; i++; if ((fmode & S_IXUSR) != 0) outbuf[i] = 'x'; i++; if ((fmode & S_IRGRP) != 0) outbuf[i] = 'r'; i++; if ((fmode & S_IWGRP) != 0) outbuf[i] = 'w'; i++; if ((fmode & S_IXGRP) != 0) outbuf[i] = 'x'; i++; if ((fmode & S_IROTH) != 0) outbuf[i] = 'r'; i++; if ((fmode & S_IWOTH) != 0) outbuf[i] = 'w'; i++; if ((fmode & S_IXOTH) != 0) outbuf[i] = 'x'; i++; outbuf[i] = '\0'; if ((fmode & S_ISUID) != 0) { if (outbuf[3] == 'x') outbuf[3] = 's'; else outbuf[3] = 'S'; } /* setgid without execute == locking */ if ((fmode & S_ISGID) != 0) { if (outbuf[6] == 'x') outbuf[6] = 's'; else outbuf[6] = 'l'; } if ((fmode & S_ISVTX) != 0) { if (outbuf[9] == 'x') outbuf[9] = 't'; else outbuf[9] = 'T'; } return outbuf; } /* do_stat --- provide a stat() function for gawk */ static NODE * do_stat(tree) NODE *tree; { NODE *file, *array; struct stat sbuf; int ret; NODE **aptr; char *pmode; /* printable mode */ char *type = "unknown"; if (do_lint && get_curfunc_arg_count() > 2) lintwarn("stat: called with too many arguments"); /* directory is first arg, array to hold results is second */ file = get_scalar_argument(tree, 0, FALSE); array = get_array_argument(tree, 1, FALSE); /* empty out the array */ assoc_clear(array); /* lstat the file, if error, set ERRNO and return */ (void) force_string(file); ret = lstat(file->stptr, & sbuf); if (ret < 0) { update_ERRNO(); set_value(tmp_number((AWKNUM) ret)); free_temp(file); return tmp_number((AWKNUM) 0); } /* fill in the array */ aptr = assoc_lookup(array, tmp_string("name", 4), FALSE); *aptr = dupnode(file); aptr = assoc_lookup(array, tmp_string("dev", 3), FALSE); *aptr = make_number((AWKNUM) sbuf.st_dev); aptr = assoc_lookup(array, tmp_string("ino", 3), FALSE); *aptr = make_number((AWKNUM) sbuf.st_ino); aptr = assoc_lookup(array, tmp_string("mode", 4), FALSE); *aptr = make_number((AWKNUM) sbuf.st_mode); aptr = assoc_lookup(array, tmp_string("nlink", 5), FALSE); *aptr = make_number((AWKNUM) sbuf.st_nlink); aptr = assoc_lookup(array, tmp_string("uid", 3), FALSE); *aptr = make_number((AWKNUM) sbuf.st_uid); aptr = assoc_lookup(array, tmp_string("gid", 3), FALSE); *aptr = make_number((AWKNUM) sbuf.st_gid); aptr = assoc_lookup(array, tmp_string("size", 4), FALSE); *aptr = make_number((AWKNUM) sbuf.st_size); aptr = assoc_lookup(array, tmp_string("blocks", 6), FALSE); *aptr = make_number((AWKNUM) sbuf.st_blocks); aptr = assoc_lookup(array, tmp_string("atime", 5), FALSE); *aptr = make_number((AWKNUM) sbuf.st_atime); aptr = assoc_lookup(array, tmp_string("mtime", 5), FALSE); *aptr = make_number((AWKNUM) sbuf.st_mtime); aptr = assoc_lookup(array, tmp_string("ctime", 5), FALSE); *aptr = make_number((AWKNUM) sbuf.st_ctime); /* for block and character devices, add rdev, major and minor numbers */ if (S_ISBLK(sbuf.st_mode) || S_ISCHR(sbuf.st_mode)) { aptr = assoc_lookup(array, tmp_string("rdev", 4), FALSE); *aptr = make_number((AWKNUM) sbuf.st_rdev); aptr = assoc_lookup(array, tmp_string("major", 5), FALSE); *aptr = make_number((AWKNUM) major(sbuf.st_rdev)); aptr = assoc_lookup(array, tmp_string("minor", 5), FALSE); *aptr = make_number((AWKNUM) minor(sbuf.st_rdev)); } #ifdef HAVE_ST_BLKSIZE aptr = assoc_lookup(array, tmp_string("blksize", 7), FALSE); *aptr = make_number((AWKNUM) sbuf.st_blksize); #endif /* HAVE_ST_BLKSIZE */ aptr = assoc_lookup(array, tmp_string("pmode", 5), FALSE); pmode = format_mode(sbuf.st_mode); *aptr = make_string(pmode, strlen(pmode)); /* for symbolic links, add a linkval field */ if (S_ISLNK(sbuf.st_mode)) { char buf[BUFSIZ*2]; int linksize; linksize = readlink(file->stptr, buf, sizeof(buf) - 1); if (linksize >= 0) { /* should make this smarter */ if (linksize >= sizeof(buf) - 1) fatal("size of symbolic link too big"); buf[linksize] = '\0'; aptr = assoc_lookup(array, tmp_string("linkval", 7), FALSE); *aptr = make_string(buf, linksize); } } /* add a type field */ switch (sbuf.st_mode & S_IFMT) { #ifdef S_IFSOCK case S_IFSOCK: type = "socket"; break; #endif #ifdef S_IFLNK case S_IFLNK: type = "symlink"; break; #endif case S_IFREG: type = "file"; break; case S_IFBLK: type = "blockdev"; break; case S_IFDIR: type = "directory"; break; #ifdef S_IFDOOR case S_IFDOOR: type = "door"; break; #endif case S_IFCHR: type = "chardev"; break; #ifdef S_IFIFO case S_IFIFO: type = "fifo"; break; #endif } aptr = assoc_lookup(array, tmp_string("type", 4), FALSE); *aptr = make_string(type, strlen(type)); free_temp(file); /* Set the return value */ set_value(tmp_number((AWKNUM) ret)); /* Just to make the interpreter happy */ return tmp_number((AWKNUM) 0); } /* dlload --- load new builtins in this library */ NODE * dlload(tree, dl) NODE *tree; void *dl; { make_builtin("chdir", do_chdir, 1); make_builtin("stat", do_stat, 2); return tmp_number((AWKNUM) 0); } --- NEW FILE: readfile.c --- /* * readfile.c - Read an entire file into a string. * * Arnold Robbins * Tue Apr 23 17:43:30 IDT 2002 * Revised per Peter Tillier * Mon Jun 9 17:05:11 IDT 2003 * Revised for new dynamic function facilities * Mon Jun 14 14:53:07 IDT 2004 */ /* * Copyright (C) 2002, 2003, 2004 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Programming Language. * * GAWK is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * GAWK is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "awk.h" #include <fcntl.h> #ifndef O_BINARY #define O_BINARY 0 #endif /* do_readfile --- read a file into memory */ NODE * do_readfile(tree) NODE *tree; { NODE *filename; int ret = -1; struct stat sbuf; char *text; int fd; if (do_lint && get_curfunc_arg_count() > 1) lintwarn("readfile: called with too many arguments"); filename = get_argument(tree, 0); if (filename != NULL) { (void) force_string(filename); ret = stat(filename->stptr, & sbuf); if (ret < 0) { update_ERRNO(); free_temp(filename); goto done; } else if ((sbuf.st_mode & S_IFMT) != S_IFREG) { errno = EINVAL; ret = -1; update_ERRNO(); free_temp(filename); goto done; } if ((fd = open(filename->stptr, O_RDONLY|O_BINARY)) < 0) { ret = -1; update_ERRNO(); free_temp(filename); goto done; } emalloc(text, char *, sbuf.st_size + 2, "do_readfile"); memset(text, '\0', sbuf.st_size + 2); if ((ret = read(fd, text, sbuf.st_size)) != sbuf.st_size) { (void) close(fd); ret = -1; update_ERRNO(); free_temp(filename); goto done; } close(fd); free_temp(filename); set_value(tmp_string(text, sbuf.st_size)); return tmp_number((AWKNUM) 0); } else if (do_lint) lintwarn("filename: called with no arguments"); done: /* Set the return value */ set_value(tmp_number((AWKNUM) ret)); /* Just to make the interpreter happy */ return tmp_number((AWKNUM) 0); } /* dlload --- load new builtins in this library */ NODE * dlload(tree, dl) NODE *tree; void *dl; { make_builtin("readfile", do_readfile, 1); return tmp_number((AWKNUM) 0); } --- NEW FILE: doit --- ../gawk -f foo.awk --- NEW FILE: pcext.def --- EXPORTS dlload @1 --- NEW FILE: testff.awk --- BEGIN { extension("./filefuncs.so", "dlload") # printf "before: " # fflush() # system("pwd") # # chdir("..") # # printf "after: " # fflush() # system("pwd") chdir(".") data[1] = 1 print "Info for testff.awk" ret = stat("testff.awk", data) print "ret =", ret for (i in data) printf "data[\"%s\"] = %s\n", i, data[i] print "testff.awk modified:", strftime("%m %d %y %H:%M:%S", data["mtime"]) print "\nInfo for JUNK" ret = stat("JUNK", data) print "ret =", ret for (i in data) printf "data[\"%s\"] = %s\n", i, data[i] print "JUNK modified:", strftime("%m %d %y %H:%M:%S", data["mtime"]) } --- NEW FILE: steps --- # what to do under linux to make dl.so # Tue Nov 24 15:04:14 EST 1998 # Sun Aug 26 16:03:58 IDT 2001 # Sun Apr 28 15:59:57 IDT 2002 # Mon Jun 21 17:03:37 IDT 2004 gcc -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. dl.c gcc -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. filefuncs.c gcc -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. fork.c gcc -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. ordchr.c gcc -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. arrayparm.c gcc -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. readfile.c gcc -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. testarg.c ld -o dl.so -shared dl.o ld -o filefuncs.so -shared filefuncs.o ld -o fork.so -shared fork.o ld -o ordchr.so -shared ordchr.o ld -o arrayparm.so -shared arrayparm.o ld -o readfile.so -shared readfile.o ld -o testarg.so -shared testarg.o --- NEW FILE: xreadlink.h --- /* readlink wrapper to return the link name in malloc'd storage Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Written by Jim Meyering <ji...@me...> */ #include <stddef.h> char *xreadlink (char const *, size_t); --- NEW FILE: dl.c --- /* * dl.c - Example of adding a new builtin function to gawk. * * Christos Zoulas, Thu Jun 29 17:40:41 EDT 1995 * Arnold Robbins, update for 3.1, Wed Sep 13 09:38:56 2000 */ /* * Copyright (C) 1995 - 2001 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Programming Language. * * GAWK is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * GAWK is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "awk.h" #include <dlfcn.h> static void *sdl = NULL; static NODE * zaxxon(tree) NODE *tree; { NODE *obj; int i; int comma = 0; /* * Print the arguments */ printf("External linkage %s(", tree->param); for (i = 0; i < tree->param_cnt; i++) { obj = get_argument(tree, i); if (obj == NULL) break; force_string(obj); printf(comma ? ", %s" : "%s", obj->stptr); free_temp(obj); comma = 1; } printf(");\n"); /* * Do something useful */ obj = get_argument(tree, 0); if (obj != NULL) { force_string(obj); if (strcmp(obj->stptr, "unload") == 0 && sdl) { /* * XXX: How to clean up the function? * I would like the ability to remove a function... */ dlclose(sdl); sdl = NULL; } free_temp(obj); } /* Set the return value */ set_value(tmp_number((AWKNUM) 3.14)); /* Just to make the interpreter happy */ return tmp_number((AWKNUM) 0); } NODE * dlload(tree, dl) NODE *tree; void *dl; { sdl = dl; make_builtin("zaxxon", zaxxon, 4); return tmp_number((AWKNUM) 0); } --- NEW FILE: foo.awk --- BEGIN { extension("./dl.so","dlload") zaxxon("hi there", "this is", "a test", "of argument passing") zaxxon(1) zaxxon(1,2) z = zaxxon(1,2,3,4) z = zaxxon(1,zaxxon(zaxxon("foo")),3,4) print z } --- NEW FILE: testarrayparm.awk --- #! /bin/awk -f BEGIN { extension("./arrayparm.so", "dlload") mkarray(newvar, "hi", "hello") for (i in newvar) printf ("newvar[\"%s\"] = \"%s\"\n", i, newvar[i]) } --- NEW FILE: xreadlink.c --- /* xreadlink.c -- readlink wrapper to return the link name in malloc'd storage Copyright (C) 2001, 2003, 2004, 2005 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Written by Jim Meyering <ji...@me...> */ #if HAVE_CONFIG_H # include <config.h> #endif #include "xreadlink.h" #include <stdio.h> #include <errno.h> #include <limits.h> #include <sys/types.h> #include <stdlib.h> #if HAVE_UNISTD_H # include <unistd.h> #endif #ifndef SIZE_MAX # define SIZE_MAX ((size_t) -1) #endif #ifndef SSIZE_MAX # define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2)) #endif #define MAXSIZE (SIZE_MAX < SSIZE_MAX ? SIZE_MAX : SSIZE_MAX) #include "xalloc.h" /* Call readlink to get the symbolic link value of FILE. SIZE is a hint as to how long the link is expected to be; typically it is taken from st_size. It need not be correct. Return a pointer to that NUL-terminated string in malloc'd storage. If readlink fails, return NULL (caller may use errno to diagnose). If malloc fails, or if the link value is longer than SSIZE_MAX :-), give a diagnostic and exit. */ char * xreadlink (char const *file, size_t size) { /* The initial buffer size for the link value. A power of 2 detects arithmetic overflow earlier, but is not required. */ size_t buf_size = size < MAXSIZE ? size + 1 : MAXSIZE; while (1) { char *buffer = xmalloc (buf_size); ssize_t r = readlink (file, buffer, buf_size); size_t link_length = r; /* On AIX 5L v5.3 and HP-UX 11i v2 04/09, readlink returns -1 with errno == ERANGE if the buffer is too small. */ if (r < 0 && errno != ERANGE) { int saved_errno = errno; free (buffer); errno = saved_errno; return NULL; } if (link_length < buf_size) { buffer[link_length] = 0; return buffer; } free (buffer); if (buf_size <= MAXSIZE / 2) buf_size *= 2; else if (buf_size < MAXSIZE) buf_size = MAXSIZE; else xalloc_die (); } } --- NEW FILE: testordchr.awk --- BEGIN { extension("./ordchr.so", "dlload") print "ord(\"a\") is", ord("a") print "chr(65) is", chr(65) } |