From 3180f56c81e3d3540e0413f861f1ddfc7b47c555 Mon Sep 17 00:00:00 2001 From: nishi Date: Tue, 6 Feb 2024 07:16:57 +0000 Subject: [PATCH] Tcl binding git-svn-id: file:///raid/svn-main/nishi-libw3/trunk@174 d27a3e52-49c5-7645-884c-6793ebffc270 --- Library/Makefile | 4 ++ Library/Tcl.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++ Library/W3Tcl.h | 9 ++++ Makefile | 13 +++-- W3Version.h.p | 2 +- 5 files changed, 162 insertions(+), 4 deletions(-) create mode 100644 Library/Tcl.c create mode 100644 Library/W3Tcl.h diff --git a/Library/Makefile b/Library/Makefile index 4a3eda1..e93619f 100644 --- a/Library/Makefile +++ b/Library/Makefile @@ -3,6 +3,10 @@ OBJS = ./Core.o ./Util.o ./DNS.o ./HTTP.o ./Gopher.o ./POP3.o ./File.o ./URL.o ./Tag.o +ifeq ($(TCL),YES) +OBJS += ./Tcl.o +endif + ifeq ($(WINDOWS),YES) ./w3.dll: $(OBJS) $(CC) $(LDFLAGS) -fstack-protector -L../openssl/lib/mingw/$(WINARCH) -shared -Wl,--out-implib,./w3.lib -o $@ $^ $(LIBS) diff --git a/Library/Tcl.c b/Library/Tcl.c new file mode 100644 index 0000000..e402968 --- /dev/null +++ b/Library/Tcl.c @@ -0,0 +1,138 @@ +/* $Id$ */ +#include "W3Tcl.h" + +#include + +#include "W3Util.h" +#include "W3Core.h" + +#include +#include +#include + +extern int strcasecmp(const char* s1, const char* s2); + +void** __dictionary; + +int Tcl_W3Cmd(ClientData dummy, Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]){ + if(objc < 2){ + const char* errmsg = "argument error: arguments should be \"w3 subcommand arg1 arg2 ...\""; + Tcl_SetObjResult(interp, Tcl_NewStringObj(errmsg, strlen(errmsg))); + return TCL_ERROR; + } + char* subcommand = Tcl_GetString(objv[1]); + if(strcasecmp(subcommand, "create") == 0){ + if(objc != 6){ + const char* errmsg = "argument error: arguments should be \"w3 create name protocol hostname port\""; + Tcl_SetObjResult(interp, Tcl_NewStringObj(errmsg, strlen(errmsg))); + return TCL_ERROR; + } + char* name = Tcl_GetString(objv[2]); + char* protocol = Tcl_GetString(objv[3]); + char* hostname = Tcl_GetString(objv[4]); + int port = atoi(Tcl_GetString(objv[5])); + struct W3* w3 = W3_Create(protocol, hostname, port); + if(w3 == NULL){ + const char* errmsg = "connect error: failed to connect"; + Tcl_SetObjResult(interp, Tcl_NewStringObj(errmsg, strlen(errmsg))); + return TCL_ERROR; + }else{ + int len = 0; + if(__dictionary == NULL) { + __dictionary = malloc(sizeof(*__dictionary) * (len + 3)); + __dictionary[len] = __W3_Strdup(name); + __dictionary[len + 1] = w3; + int i; + for(i = 0; ((char*)__dictionary[len])[i] != 0; i++) { + ((char*)__dictionary[len])[i] = tolower(((char*)__dictionary[len])[i]); + } + __dictionary[len + 2] = NULL; + } else { + for(len = 0; __dictionary[len] != NULL; len++) + ; + void** __dictionary2 = __dictionary; + __dictionary = malloc(sizeof(*__dictionary) * (len + 3)); + for(len = 0; __dictionary2[len] != NULL; len++) { + __dictionary[len] = __dictionary2[len]; + } + __dictionary[len] = __W3_Strdup(name); + __dictionary[len + 1] = w3; + __dictionary[len + 2] = NULL; + int i; + for(i = 0; ((char*)__dictionary[len])[i] != 0; i++) { + ((char*)__dictionary[len])[i] = tolower(((char*)__dictionary[len])[i]); + } + free(__dictionary2); + } + Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); + } + }else if(strcasecmp(subcommand, "set_method") == 0 || strcasecmp(subcommand, "set_path") == 0){ + if(objc != 4){ + if(strcasecmp(subcommand, "set_method") == 0){ + const char* errmsg = "argument error: arguments should be \"w3 set_method name method\""; + Tcl_SetObjResult(interp, Tcl_NewStringObj(errmsg, strlen(errmsg))); + }else{ + const char* errmsg = "argument error: arguments should be \"w3 set_path name path\""; + Tcl_SetObjResult(interp, Tcl_NewStringObj(errmsg, strlen(errmsg))); + } + return TCL_ERROR; + } + char* name = Tcl_GetString(objv[2]); + if(__dictionary == NULL){ + const char* errmsg = "argument error: a client named that does not exist"; + Tcl_SetObjResult(interp, Tcl_NewStringObj(errmsg, strlen(errmsg))); + }else{ + int i; + for(i = 0; __dictionary[i] != NULL; i += 2){ + if(strcasecmp((char*)__dictionary[i], name) == 0){ + if(strcasecmp(subcommand, "set_method") == 0){ + W3_Set_Method(__dictionary[i + 1], Tcl_GetString(objv[3])); + }else{ + W3_Set_Path(__dictionary[i + 1], Tcl_GetString(objv[3])); + } + Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); + return TCL_OK; + } + } + const char* errmsg = "argument error: a client named that does not exist"; + Tcl_SetObjResult(interp, Tcl_NewStringObj(errmsg, strlen(errmsg))); + } + }else if(strcasecmp(subcommand, "send_request") == 0){ + if(objc != 3){ + const char* errmsg = "argument error: arguments should be \"w3 send_request name\""; + Tcl_SetObjResult(interp, Tcl_NewStringObj(errmsg, strlen(errmsg))); + return TCL_ERROR; + } + char* name = Tcl_GetString(objv[2]); + if(__dictionary == NULL){ + const char* errmsg = "argument error: a client named that does not exist"; + Tcl_SetObjResult(interp, Tcl_NewStringObj(errmsg, strlen(errmsg))); + }else{ + int i; + for(i = 0; __dictionary[i] != NULL; i += 2){ + if(strcasecmp((char*)__dictionary[i], name) == 0){ + W3_Send_Request(__dictionary[i + 1]); + Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); + return TCL_OK; + } + } + const char* errmsg = "argument error: a client named that does not exist"; + Tcl_SetObjResult(interp, Tcl_NewStringObj(errmsg, strlen(errmsg))); + } + }else{ + const char* errmsg = "argument error: invalid subcommand"; + Tcl_SetObjResult(interp, Tcl_NewStringObj(errmsg, strlen(errmsg))); + return TCL_ERROR; + } + return TCL_OK; +} + +int W3_Init(Tcl_Interp* interp){ + __W3_Debug("Tcl", "Initializing the binding"); + W3_Library_Init(); + __dictionary = malloc(sizeof(*__dictionary)); + __dictionary[0] = NULL; + Tcl_CreateObjCommand(interp, "w3", Tcl_W3Cmd, NULL, NULL); + __W3_Debug("Tcl", "Initialized the binding"); + return TCL_OK; +} diff --git a/Library/W3Tcl.h b/Library/W3Tcl.h new file mode 100644 index 0000000..f935ec5 --- /dev/null +++ b/Library/W3Tcl.h @@ -0,0 +1,9 @@ +/* $Id$ */ +#ifndef __W3URL_H__ +#define __W3URL_H__ + +#include + +int W3_Init(Tcl_Interp* interp); + +#endif diff --git a/Makefile b/Makefile index 816f19e..91c9b3f 100644 --- a/Makefile +++ b/Makefile @@ -33,6 +33,13 @@ WINDOWS := YES WINARCH := x64 endif +PKGCONF := pkg-config + +ifeq ($(TCL),YES) +CFLAGS += $(shell $(PKGCONF) --cflags tcl) -DTCL_BINDING +LIBS += $(shell $(PKGCONF) --libs tcl) +endif + ifeq ($(WINDOWS),YES) LIBS += -lws2_32 endif @@ -58,7 +65,7 @@ ALL := ./Library/w3.dll ./Example all: ./Library/W3Version.h ./w3.pc $(ALL) ./Library/w3.dll: - $(MAKE) -C ./Library CC=$(CC) CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)" WINDOWS=YES WINARCH=$(WINARCH) + $(MAKE) -C ./Library CC=$(CC) CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)" WINDOWS=YES WINARCH=$(WINARCH) TCL=$(TCL) ./Example: ./Library/w3.dll $(MAKE) -C ./Example CC=$(CC) examples SUFFIX=.exe @@ -75,10 +82,10 @@ ALL := ./Library/libw3.so ./Library/libw3.a ./Example all: ./Library/W3Version.h ./w3.pc $(ALL) ./Library/libw3.so: - $(MAKE) -C ./Library CC=$(CC) CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)" ./libw3.so + $(MAKE) -C ./Library CC=$(CC) CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)" TCL=$(TCL) ./libw3.so ./Library/libw3.a: - $(MAKE) -C ./Library CC=$(CC) CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)" ./libw3.a + $(MAKE) -C ./Library CC=$(CC) CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)" TCL=$(TCL) ./libw3.a ./Example: ./Library/libw3.so $(MAKE) -C ./Example CC=$(CC) examples diff --git a/W3Version.h.p b/W3Version.h.p index a9d56ea..ddd3c0b 100644 --- a/W3Version.h.p +++ b/W3Version.h.p @@ -6,7 +6,7 @@ extern "C" { #endif -#define LIBW3_VERSION "2.2P" \ +#define LIBW3_VERSION "2.3" \ SUFFIX #ifdef __cplusplus -- 2.43.0