added win32 nwio

This commit is contained in:
hyung-hwan 2012-04-30 09:46:58 +00:00
parent 9425ec0730
commit 31739d58f4
21 changed files with 5637 additions and 509 deletions

View File

@ -29,7 +29,6 @@
#include <qse/cmn/main.h>
#include <qse/cmn/mbwc.h>
#include <qse/cmn/xma.h>
#include <qse/cmn/nwio.h>
#include <string.h>
#include <signal.h>
@ -56,10 +55,6 @@
# include <errno.h>
#endif
#include <sys/socket.h>
static qse_awk_rtx_t* app_rtx = QSE_NULL;
static int app_debug = 0;
@ -98,11 +93,6 @@ struct gvmv_t
qse_size_t len;
};
struct rtx_xtn_t
{
qse_awk_rio_fun_t old_pipe_handler;
};
static void dprint (const qse_char_t* fmt, ...)
{
if (app_debug)
@ -894,143 +884,6 @@ static qse_mmgr_t debug_mmgr =
};
#endif
static qse_ssize_t nwio_handler_open (
qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod, int flags, qse_nwad_t* nwad)
{
qse_nwio_t* handle;
handle = qse_nwio_open (
qse_awk_rtx_getmmgr(rtx), 0, nwad,
flags | QSE_NWIO_TEXT | QSE_NWIO_IGNOREMBWCERR |
QSE_NWIO_READNORETRY | QSE_NWIO_WRITENORETRY
);
if (handle == QSE_NULL) return -1;
#if defined(QSE_CHAR_IS_WCHAR)
{
qse_cmgr_t* cmgr = qse_awk_rtx_getcmgrstd (rtx, riod->name);
if (cmgr) qse_nwio_setcmgr (handle, cmgr);
}
#endif
riod->handle2 = (void*)handle;
return 1;
}
static qse_ssize_t nwio_handler_rest (
qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_rio_arg_t* riod,
qse_char_t* data, qse_size_t size)
{
switch (cmd)
{
case QSE_AWK_RIO_OPEN:
{
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINTERN, QSE_NULL);
return -1;
}
case QSE_AWK_RIO_CLOSE:
{
qse_nwio_close ((qse_nwio_t*)riod->handle2);
riod->handle2 = QSE_NULL;
return 0;
}
case QSE_AWK_RIO_READ:
{
return qse_nwio_read ((qse_nwio_t*)riod->handle2, data, size);
}
case QSE_AWK_RIO_WRITE:
{
return qse_nwio_write ((qse_nwio_t*)riod->handle2, data, size);
}
case QSE_AWK_RIO_FLUSH:
{
/*if (riod->mode == QSE_AWK_RIO_PIPE_READ) return -1;*/
return qse_nwio_flush ((qse_nwio_t*)riod->handle2);
}
case QSE_AWK_RIO_NEXT:
{
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINTERN, QSE_NULL);
return -1;
}
}
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINTERN, QSE_NULL);
return -1;
}
static int parse_pipe_uri (const qse_char_t* uri, int* flags, qse_nwad_t* nwad)
{
static struct
{
qse_char_t* prefix;
qse_size_t len;
int flags;
} x[] =
{
{ QSE_T("tcp://"), 6, QSE_NWIO_TCP },
{ QSE_T("udp://"), 6, QSE_NWIO_UDP },
{ QSE_T("tcpd://"), 7, QSE_NWIO_TCP | QSE_NWIO_PASSIVE },
{ QSE_T("udpd://"), 7, QSE_NWIO_UDP | QSE_NWIO_PASSIVE }
};
int i;
for (i = 0; i < QSE_COUNTOF(x); i++)
{
if (qse_strzcmp (uri, x[i].prefix, x[i].len) == 0)
{
if (qse_strtonwad (uri + x[i].len, nwad) <= -1) return -1;
*flags = x[i].flags;
return 0;
}
}
return -1;
}
static qse_ssize_t new_pipe_handler (
qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_rio_arg_t* riod,
qse_char_t* data, qse_size_t size)
{
struct rtx_xtn_t* xtn;
int flags;
qse_nwad_t nwad;
xtn = qse_awk_rtx_getxtnstd (rtx);
if (cmd == QSE_AWK_RIO_OPEN && parse_pipe_uri (riod->name, &flags, &nwad) >= 0)
return nwio_handler_open (rtx, riod, flags, &nwad);
else if (riod->handle2)
return nwio_handler_rest (rtx, cmd, riod, data, size);
else
return xtn->old_pipe_handler (rtx, cmd, riod, data, size);
}
static void extend_pipe_handler (qse_awk_rtx_t* rtx)
{
struct rtx_xtn_t* xtn;
qse_awk_rio_t rio;
xtn = qse_awk_rtx_getxtnstd (rtx);
/* get the previous handler functions */
qse_awk_rtx_getrio (rtx, &rio);
/* remember the old pipe handler function */
xtn->old_pipe_handler = rio.pipe;
/* change the pipe handler to a new one */
rio.pipe = new_pipe_handler;
/* changes the handlers with a new set */
qse_awk_rtx_setrio (rtx, &rio);
}
static int awk_main (int argc, qse_char_t* argv[])
{
qse_awk_t* awk = QSE_NULL;
@ -1146,7 +999,7 @@ static int awk_main (int argc, qse_char_t* argv[])
#endif
rtx = qse_awk_rtx_openstd (
awk, QSE_SIZEOF(struct rtx_xtn_t), QSE_T("qseawk"),
awk, 0, QSE_T("qseawk"),
(const qse_char_t*const*)arg.icf, QSE_NULL, arg.console_cmgr);
if (rtx == QSE_NULL)
{
@ -1160,8 +1013,6 @@ static int awk_main (int argc, qse_char_t* argv[])
goto oops;
}
extend_pipe_handler (rtx);
app_rtx = rtx;
#ifdef ENABLE_CALLBACK
qse_awk_rtx_pushrcb (rtx, &rcb);
@ -1213,9 +1064,14 @@ oops:
int qse_main (int argc, qse_achar_t* argv[])
{
int ret;
#if defined(_WIN32)
char locale[100];
UINT codepage = GetConsoleOutputCP();
UINT codepage;
WSADATA wsadata;
codepage = GetConsoleOutputCP();
if (codepage == CP_UTF8)
{
/*SetConsoleOUtputCP (CP_UTF8);*/
@ -1227,10 +1083,24 @@ int qse_main (int argc, qse_achar_t* argv[])
setlocale (LC_ALL, locale);
qse_setdflcmgr (qse_slmbcmgr);
}
if (WSAStartup (MAKEWORD(2,0), &wsadata) != 0)
{
print_error (QSE_T("Failed to start up winsock\n"));
return -1;
}
#else
setlocale (LC_ALL, "");
qse_setdflcmgr (qse_slmbcmgr);
#endif
return qse_runmain (argc, argv, awk_main);
ret = qse_runmain (argc, argv, awk_main);
#if defined(_WIN32)
WSACleanup ();
#endif
return ret;
}

4
qse/configure vendored
View File

@ -16326,6 +16326,10 @@ if test "x$ac_cv_lib_socket_connect" = xyes; then :
fi
fi
if test "${platform_win32}" = "yes"
then
SOCKET_LIBS="$SOCKET_LIBS -lws2_32"
fi
for ac_func in sendfile sendfile64 sendfilev sendfilev64

View File

@ -137,6 +137,10 @@ then
AC_DEFINE(HAVE_CONNECT, 1)
])
fi
if test "${platform_win32}" = "yes"
then
SOCKET_LIBS="$SOCKET_LIBS -lws2_32"
fi
AC_SUBST(SOCKET_LIBS)
dnl check if sendfile and its variants exist in the standard c library

View File

@ -1,14 +1,26 @@
/** @page awk AWK
@section awk_content CONTENTS
- @ref awk_intro "INTRODUCTION"
- @ref awk_lang "AWK LANGUAGE"
- @ref awk_ext "AWK LANGUAGE EXTENSIONS"
- @ref awk_ext_vardecl " VARIABLE DECLARATION"
- @ref awk_ext_include "INCLUDE"
- @ref awk_ext_rwpipe "TWO-WAY PIPE"
- @ref awk_ext_return "RETURN"
- @ref awk_ext_comment "COMMENT"
- @ref awk_ext_fnc "EXTENDED FUNCTIONS"
- @ref awk_ext_fs "EXTENDED FS"
- @ref awk_ext_binnum "BINARY NUMBER"
- @ref awk_ext_unicode "UNICODE ESCAPE SEQUENCE"
- @ref awk_ext_ioenc "I/O ENCODING"
@section awk_intro INTRODUCTION
QSEAWK is an embeddable AWK interpreter and is a part of the @ref qse_intro
"QSE" library. The interpreter implements the language described in the book
<a class="el" href="http://cm.bell-labs.com/cm/cs/awkbook/">
The AWK Proramming Language</a>
with @ref awk_ext "extensions". Its design focuses on building a flexible
and robust embedding API with minimal platform dependency. An embedding
application is capable of
"QSE" library. Its design focuses on building a flexible and robust embedding
API with minimal platform dependency. An embedding application is capable of
- adding new global variables and functions.
- getting and set the value of a global variable.
- calling a function with or without parameters and getting its return value.
@ -39,40 +51,42 @@ The code example below demonstrates the steps in C. It executes the one liner
int main ()
{
qse_awk_t* awk = QSE_NULL;
qse_awk_rtx_t* rtx = QSE_NULL;
qse_awk_val_t* retv;
qse_awk_parsestd_in_t psin;
int ret = -1;
qse_awk_t* awk = QSE_NULL;
qse_awk_rtx_t* rtx = QSE_NULL;
qse_awk_val_t* retv;
qse_awk_parsestd_t psin;
int ret = -1;
awk = qse_awk_openstd (0); /* open a new interpreter */
if (!awk) FAIL ("cannot open awk");
awk = qse_awk_openstd (0); /* open a new interpreter */
if (!awk) FAIL ("cannot open awk");
/* parse the hello world script from a string */
psin.type = QSE_AWK_PARSESTD_CP;
psin.u.cp = QSE_T("BEGIN { print \"hello, world\" }");
if (qse_awk_parsestd (awk, &psin, QSE_NULL) <= -1)
FAIL (qse_awk_geterrmsg(awk));
/* parse the hello world script from a string */
psin.type = QSE_AWK_PARSESTD_STR;
psin.u.str.ptr = QSE_T("BEGIN { print \"hello, world\" }");
psin.u.str.len = qse_strlen(psin.u.str.ptr);
if (qse_awk_parsestd (awk, &psin, QSE_NULL) <= -1)
FAIL (qse_awk_geterrmsg(awk));
rtx = qse_awk_rtx_openstd ( /* open a runtime context */
awk, 0, /* no extension */
QSE_T("hello"), /* ARGV[0] */
QSE_NULL, /* stdin */
QSE_NULL /* stdout */
);
if (!rtx) FAIL (qse_awk_geterrmsg(awk));
rtx = qse_awk_rtx_openstd ( /* open a runtime context */
awk, 0, /* no extension */
QSE_T("hello"), /* ARGV[0] */
QSE_NULL, /* stdin */
QSE_NULL, /* stdout */
QSE_NULL /* default cmgr */
);
if (!rtx) FAIL (qse_awk_geterrmsg(awk));
/* exeucte BEGIN,pattern-action,END blocks */
retv = qse_awk_rtx_loop (rtx);
if (!retv) FAIL (qse_awk_rtx_geterrmsg(rtx));
/* exeucte BEGIN,pattern-action,END blocks */
retv = qse_awk_rtx_loop (rtx);
if (!retv) FAIL (qse_awk_rtx_geterrmsg(rtx));
qse_awk_rtx_refdownval (rtx, retv); /* destroy the return value */
ret = 0;
qse_awk_rtx_refdownval (rtx, retv); /* destroy the return value */
ret = 0;
oops:
if (rtx) qse_awk_rtx_close (rtx); /* close the runtime context */
if (awk) qse_awk_close (awk); /* close the interpreter */
return ret;
if (rtx) qse_awk_rtx_close (rtx); /* close the runtime context */
if (awk) qse_awk_close (awk); /* close the interpreter */
return ret;
}
@endcode
@ -119,9 +133,63 @@ int main (int argc, char* argv[])
}
@endcode
@section awk_ext EXTENSIONS
Some language extensions are implemented and they can be enabled by setting the
corresponding options.
This library also provides a stand-alone AWK interpreter that you can use
in a console environment. The source code is located under the
<project-root>/cmd/awk subdirectory.
@code
$ qseawk
USAGE: qseawk [options] -f sourcefile [ -- ] [datafile]*
qseawk [options] [ -- ] sourcestring [datafile]*
Where options are:
-h/--help print this message
--version print version
-D show extra information
-c/--call name call a function instead of entering
the pattern-action loop
-f/--file sourcefile set the source script file
-d/--deparsed-file deparsedfile set the deparsing output file
-F/--field-separator string set a field separator(FS)
-v/--assign var=value add a global variable with a value
-m/--memory-limit number limit the memory usage (bytes)
-X number fail the number'th memory allocation
--script-encoding string specify script file encoding name
--console-encoding string specify console encoding name
--implicit on/off allow undeclared variables
--explicit on/off allow declared variables(local,global)
--extraops on/off enable extra operators(<<,>>,^^,\)
--rio on/off enable builtin I/O including getline & print
--rwpipe on/off allow a dual-directional pipe
--newline on/off enable a newline to terminate a statement
--striprecspc on/off strip spaces in splitting a record
--stripstrspc on/off strip spaces in converting a string to a number
--nextofile on/off enable 'nextofile'
--reset on/off enable 'reset'
--crlf on/off use CRLF for a newline
--maptovar on/off allow a map to be assigned or returned
--pablock on/off enable pattern-action loop
--rexbound on/off enable {n,m} in a regular expression
--ncmponstr on/off perform numeric comparsion on numeric strings
--strictnaming on/off enable the strict naming rule
--include on/off enable 'include'
@endcode
@section awk_lang AWK LANGUAGE
QSEAWK implements the language described in the book
<a class="el" href="http://cm.bell-labs.com/cm/cs/awkbook/">
The AWK Proramming Language</a> with various @ref awk_ext "extensions".
- BEGIN block
- END block
- Pattern-action block
- User-defined functions
- Expressions
- Statements
- Streams
@section awk_ext AWK LANGUAGE EXTENSIONS
Some language extensions are implemented and those can be enabled by setting
the corresponding options.
@subsection awk_ext_vardecl VARIABLE DECLARATION
@ -186,6 +254,29 @@ BEGIN {
}
@endcode
This two-way pipe can create a TCP or UDP connection if the pipe command
string is prefixed with one of the followings:
- tcp:// - establishes a TCP connection to a specified IP address/port.
- udp:// - establishes a TCP connection to a specified IP address/port.
- tcpd:// - binds a TCP socket to a specified IP address/port and waits for the first connection.
- udpd:// - binds a TCP socket to a specified IP address/port and waits for the first sender.
@code
BEGIN {
# it binds a TCP socket to the IPv6 address :: and the port number
# 9999 and waits for the first coming connection. It repeats writing
# "hello world" to the first connected peer and reading a line from
# it until the session is torn down.
do {
print "hello world" || "tcpd://[::]:9999";
if (("tcpd://[::]:9999" || getline x) <= 0) break;
print x;
}
while(1);
}
@endcode
@subsection awk_ext_return RETURN
The return statement is valid in BEGIN blocks, END blocks, and pattern-action
blocks as well as in functions. The execution of a calling block is aborted
@ -232,24 +323,123 @@ BEGIN {
@endcode
@subsection awk_ext_fs EXTENDED FS
If the value for FS begins with a question mark followed by 4
additional letters, QSEAWK can split a record with quoted fields
delimited by a single-letter separator.
The 4 additional letters are composed of a field separator,
an escaper, a opening quote, and a closing quote.
@code
BEGIN { FS="?:\\\"\""; }
$ cat x.awk
BEGIN { FS="?:\\[]"; }
{
for (i = 1; i <= NF; i++)
print "$" i ": " $i;
print "---------------";
}
@endcode
The value of FS above means the following.
- : is a field separator.
- a backslash is an escaper.
- a left bracket is an opening quote.
- a right bracket is a closing quote.
See the following output.
@code
$ cat x.dat
[fx1]:[fx2]:[f\[x\]3]
abc:def:[a b c]
$ qseawk -f x.awk x.dat
$1: fx1
$2: fx2
$3: f[x]3
---------------
$1: abc
$2: def
$3: a b c
---------------
@endcode
@subsection awk_ext_binnum BINARY NUMBER
Use 0b to begin a binary number sequence.
@code
BEGIN { print 0b1101; }
$ qseawk 'BEGIN { printf ("%b %o %d %x\n", 0b1101, 0b1101, 0b1101, 0b1101); }'
1101 15 13 d
@endcode
@subsection awk_ext_unicode UNICODE ESCAPE SEQUENCE
If QSE is compiled for #QSE_CHAR_IS_WCHAR, you can use \\u and \\U in a
string to specify a character by unicode.
@code
BEGIN { print "string=>[\uB313\U0000B313]"; }
$ qseawk 'BEGIN { print "\uC720\uB2C8\uCF54\uB4DC \U00007D71\U00004E00\U000078BC"; }'
유니코드 統一碼
@endcode
@subsection awk_ext_ioenc I/O ENCODING
You can call setenc() to set the character encoding of a stream resource like
a pipe or a file. See qse_findcmgr() for a list of supported encoding names.
Let's say you run this simple echoing script on a WIN32 platform that has
the active code page of 949 and is reachable at the IP address 192.168.2.8.
@code
C:\> chcp
Active code page: 949
C:\> type s.awk
BEGIN {
sock = "tcpd://0.0.0.0:9999";
setenc (sock, "cp949"); # this is not needed since the active
# code page is already 949.
do {
if ((sock || getline x) <= 0) break;
print "PEER: " x;
print x || sock;
}
while(1);
}
C:\> qseawk --rwpipe=on -f r.awk
PEER: 안녕
PEER: ?好!
@endcode
Now you run the following script on a UTF-8 console of a Linux box.
@code
$ echo $LANG
en_US.UTF-8
$ cat c.awk
BEGIN {
peer = "tcp://192.168.2.8:9999";
setenc (peer, "cp949");
do
{
printf "> ";
if ((getline x) <= 0) break;
print x || peer;
if ((peer || getline line) <= -1) break;
print "PEER: " line;
}
while (1);
}
$ qseawk --rwpipe=on -f c.awk
> 안녕
PEER: 안녕
> 你好!
PEER: ?好!
@endcode
Note that 你 has been converted to a question mark since the letter is
not supported by cp949.
*/

View File

@ -4,5 +4,5 @@
- Generic text stream interface #qse_tio_t
- Simple text stream over a file #qse_sio_t
- Pipe stream to/from a process #qse_pio_t
- Network stream to/from a remote/local host #qse_nwio_t
*/

View File

@ -11,10 +11,10 @@ pkginclude_HEADERS += Types.hpp
endif
install-data-hook:
@$(ECHO) "#ifndef _QSE_CONFIG_H_" > "$(DESTDIR)$(pkgincludedir)/config.h"
@$(ECHO) "#define _QSE_CONFIG_H_" >> "$(DESTDIR)$(pkgincludedir)/config.h"
@echo "#ifndef _QSE_CONFIG_H_" > "$(DESTDIR)$(pkgincludedir)/config.h"
@echo "#define _QSE_CONFIG_H_" >> "$(DESTDIR)$(pkgincludedir)/config.h"
@$(EGREP) "#define[ ]+QSE_" "$(top_builddir)/include/qse/config.h" >> "$(DESTDIR)$(pkgincludedir)/config.h"
@$(ECHO) "#endif" >> "$(DESTDIR)$(pkgincludedir)/config.h"
@echo "#endif" >> "$(DESTDIR)$(pkgincludedir)/config.h"
@$(RM) "$(DESTDIR)$(pkgincludedir)/config.h.in"
@$(SED) 's|/\*#define QSE_HAVE_CONFIG_H\*/|#define QSE_HAVE_CONFIG_H|' "$(srcdir)/types.h" > "$(DESTDIR)$(pkgincludedir)/types.h"

View File

@ -661,10 +661,10 @@ uninstall-am: uninstall-pkgincludeHEADERS
install-data-hook:
@$(ECHO) "#ifndef _QSE_CONFIG_H_" > "$(DESTDIR)$(pkgincludedir)/config.h"
@$(ECHO) "#define _QSE_CONFIG_H_" >> "$(DESTDIR)$(pkgincludedir)/config.h"
@echo "#ifndef _QSE_CONFIG_H_" > "$(DESTDIR)$(pkgincludedir)/config.h"
@echo "#define _QSE_CONFIG_H_" >> "$(DESTDIR)$(pkgincludedir)/config.h"
@$(EGREP) "#define[ ]+QSE_" "$(top_builddir)/include/qse/config.h" >> "$(DESTDIR)$(pkgincludedir)/config.h"
@$(ECHO) "#endif" >> "$(DESTDIR)$(pkgincludedir)/config.h"
@echo "#endif" >> "$(DESTDIR)$(pkgincludedir)/config.h"
@$(RM) "$(DESTDIR)$(pkgincludedir)/config.h.in"
@$(SED) 's|/\*#define QSE_HAVE_CONFIG_H\*/|#define QSE_HAVE_CONFIG_H|' "$(srcdir)/types.h" > "$(DESTDIR)$(pkgincludedir)/types.h"

View File

@ -56,6 +56,7 @@
* @example awk10.c
* This programs shows how to manipuate a map using qse_awk_rtx_makemapval()
* and qse_awk_rtx_setmapvalfld().
*
*/
/** @struct qse_awk_t

View File

@ -37,6 +37,11 @@
/**
* @example awk09.c
* This programs shows how to specify multiple console output files.
*
* @example awk11.c
* This programs shows how to extend an I/O handler implemented by
* qse_awk_rtx_openstd().
*
*/
/**
@ -44,9 +49,9 @@
*/
enum qse_awk_parsestd_type_t
{
QSE_AWK_PARSESTD_NULL = 0, /* invalid type */
QSE_AWK_PARSESTD_FILE = 1,
QSE_AWK_PARSESTD_STR = 2
QSE_AWK_PARSESTD_NULL = 0, /**< invalid type */
QSE_AWK_PARSESTD_FILE = 1, /**< file */
QSE_AWK_PARSESTD_STR = 2 /**< length-bounded string */
};
typedef enum qse_awk_parsestd_type_t qse_awk_parsestd_type_t;

View File

@ -45,8 +45,9 @@ extern qse_cmgr_t* qse_cp950cmgr;
/**
* The qse_getfindcmgr() function find a builtin cmgr matching a given
* @a name and returns it. It returns #QSE_NULL if no match is found.
* The @a name can be one of "utf8", "slmb", and an empty string. Calling this
* function with an empty string is the same as calling qse_getdflcmgr().
* The @a name can be one of "utf8", "slmb", "cp949", "cp950", and an
* empty string. Calling this function with an empty string is the same
* as calling qse_getdflcmgr().
*/
qse_cmgr_t* qse_findcmgr (
const qse_char_t* name

View File

@ -22,7 +22,7 @@
#define _QSE_CMN_NWIO_H_
/** @file
* This file defines a generic text I/O interface.
* This file defines a network-based text I/O interface.
*/
#include <qse/types.h>
@ -70,18 +70,20 @@ enum qse_nwio_errnum_t
typedef enum qse_nwio_errnum_t qse_nwio_errnum_t;
#if defined(_WIN32)
/* TODO: */
typedef qse_intptr_t qse_nwio_hnd_t;
#elif defined(__OS2__)
/* TODO: */
#elif defined(__DOS__)
/* TODO: */
#else
typedef int qse_nwio_hnd_t; /**< defines a pipe handle type */
# define QSE_NWIO_HND_NIL ((qse_nwio_hnd_t)-1)
#endif
typedef struct qse_nwio_t qse_nwio_t;
/**
* The qse_nwio_t type defines a structure for a network-based stream.
*/
struct qse_nwio_t
{
QSE_DEFINE_COMMON_FIELDS (nwio)

View File

@ -22,6 +22,7 @@
#include <qse/awk/std.h>
#include <qse/cmn/sio.h>
#include <qse/cmn/pio.h>
#include <qse/cmn/nwio.h>
#include <qse/cmn/str.h>
#include <qse/cmn/mbwc.h>
#include <qse/cmn/time.h>
@ -734,6 +735,10 @@ static qse_ssize_t sf_out (
break;
}
default:
/* other code must not trigger this function */
break;
}
qse_awk_seterrnum (awk, QSE_AWK_EINTERN, QSE_NULL);
@ -793,7 +798,30 @@ int qse_awk_parsestd (
/*** RTX_OPENSTD ***/
static qse_ssize_t awk_rio_pipe (
static qse_ssize_t nwio_handler_open (
qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod, int flags, qse_nwad_t* nwad)
{
qse_nwio_t* handle;
handle = qse_nwio_open (
qse_awk_rtx_getmmgr(rtx), 0, nwad,
flags | QSE_NWIO_TEXT | QSE_NWIO_IGNOREMBWCERR |
QSE_NWIO_READNORETRY | QSE_NWIO_WRITENORETRY
);
if (handle == QSE_NULL) return -1;
#if defined(QSE_CHAR_IS_WCHAR)
{
qse_cmgr_t* cmgr = qse_awk_rtx_getcmgrstd (rtx, riod->name);
if (cmgr) qse_nwio_setcmgr (handle, cmgr);
}
#endif
riod->handle2 = (void*)handle;
return 1;
}
static qse_ssize_t nwio_handler_rest (
qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_rio_arg_t* riod,
qse_char_t* data, qse_size_t size)
{
@ -801,55 +829,135 @@ static qse_ssize_t awk_rio_pipe (
{
case QSE_AWK_RIO_OPEN:
{
qse_pio_t* handle;
int flags;
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINTERN, QSE_NULL);
return -1;
}
if (riod->mode == QSE_AWK_RIO_PIPE_READ)
{
/* TODO: should ERRTOOUT be unset? */
flags = QSE_PIO_READOUT |
QSE_PIO_ERRTOOUT;
}
else if (riod->mode == QSE_AWK_RIO_PIPE_WRITE)
{
flags = QSE_PIO_WRITEIN;
}
else if (riod->mode == QSE_AWK_RIO_PIPE_RW)
{
flags = QSE_PIO_READOUT |
QSE_PIO_ERRTOOUT |
QSE_PIO_WRITEIN;
}
else
{
/* this must not happen */
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINTERN, QSE_NULL);
return -1;
}
case QSE_AWK_RIO_CLOSE:
{
qse_nwio_close ((qse_nwio_t*)riod->handle2);
riod->handle2 = QSE_NULL;
return 0;
}
handle = qse_pio_open (
rtx->awk->mmgr,
0,
riod->name,
QSE_NULL,
flags|QSE_PIO_SHELL|QSE_PIO_TEXT|QSE_PIO_IGNOREMBWCERR
);
if (handle == QSE_NULL) return -1;
case QSE_AWK_RIO_READ:
{
return qse_nwio_read ((qse_nwio_t*)riod->handle2, data, size);
}
case QSE_AWK_RIO_WRITE:
{
return qse_nwio_write ((qse_nwio_t*)riod->handle2, data, size);
}
case QSE_AWK_RIO_FLUSH:
{
/*if (riod->mode == QSE_AWK_RIO_PIPE_READ) return -1;*/
return qse_nwio_flush ((qse_nwio_t*)riod->handle2);
}
case QSE_AWK_RIO_NEXT:
break;
}
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINTERN, QSE_NULL);
return -1;
}
static int parse_rwpipe_uri (const qse_char_t* uri, int* flags, qse_nwad_t* nwad)
{
static struct
{
qse_char_t* prefix;
qse_size_t len;
int flags;
} x[] =
{
{ QSE_T("tcp://"), 6, QSE_NWIO_TCP },
{ QSE_T("udp://"), 6, QSE_NWIO_UDP },
{ QSE_T("tcpd://"), 7, QSE_NWIO_TCP | QSE_NWIO_PASSIVE },
{ QSE_T("udpd://"), 7, QSE_NWIO_UDP | QSE_NWIO_PASSIVE }
};
int i;
for (i = 0; i < QSE_COUNTOF(x); i++)
{
if (qse_strzcmp (uri, x[i].prefix, x[i].len) == 0)
{
if (qse_strtonwad (uri + x[i].len, nwad) <= -1) return -1;
*flags = x[i].flags;
return 0;
}
}
return -1;
}
static qse_ssize_t pio_handler_open (
qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod)
{
qse_pio_t* handle;
int flags;
if (riod->mode == QSE_AWK_RIO_PIPE_READ)
{
/* TODO: should ERRTOOUT be unset? */
flags = QSE_PIO_READOUT |
QSE_PIO_ERRTOOUT;
}
else if (riod->mode == QSE_AWK_RIO_PIPE_WRITE)
{
flags = QSE_PIO_WRITEIN;
}
else if (riod->mode == QSE_AWK_RIO_PIPE_RW)
{
flags = QSE_PIO_READOUT |
QSE_PIO_ERRTOOUT |
QSE_PIO_WRITEIN;
}
else
{
/* this must not happen */
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINTERN, QSE_NULL);
return -1;
}
handle = qse_pio_open (
rtx->awk->mmgr,
0,
riod->name,
QSE_NULL,
flags|QSE_PIO_SHELL|QSE_PIO_TEXT|QSE_PIO_IGNOREMBWCERR
);
if (handle == QSE_NULL) return -1;
#if defined(QSE_CHAR_IS_WCHAR)
{
qse_cmgr_t* cmgr = qse_awk_rtx_getcmgrstd (rtx, riod->name);
if (cmgr)
{
qse_pio_setcmgr (handle, QSE_PIO_IN, cmgr);
qse_pio_setcmgr (handle, QSE_PIO_OUT, cmgr);
qse_pio_setcmgr (handle, QSE_PIO_ERR, cmgr);
}
}
{
qse_cmgr_t* cmgr = qse_awk_rtx_getcmgrstd (rtx, riod->name);
if (cmgr)
{
qse_pio_setcmgr (handle, QSE_PIO_IN, cmgr);
qse_pio_setcmgr (handle, QSE_PIO_OUT, cmgr);
qse_pio_setcmgr (handle, QSE_PIO_ERR, cmgr);
}
}
#endif
riod->handle = (void*)handle;
return 1;
riod->handle = (void*)handle;
return 1;
}
static qse_ssize_t pio_handler_rest (
qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_rio_arg_t* riod,
qse_char_t* data, qse_size_t size)
{
switch (cmd)
{
case QSE_AWK_RIO_OPEN:
{
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINTERN, QSE_NULL);
return -1;
}
case QSE_AWK_RIO_CLOSE:
@ -900,14 +1008,34 @@ static qse_ssize_t awk_rio_pipe (
}
case QSE_AWK_RIO_NEXT:
{
return -1;
}
break;
}
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINTERN, QSE_NULL);
return -1;
}
static qse_ssize_t awk_rio_pipe (
qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_rio_arg_t* riod,
qse_char_t* data, qse_size_t size)
{
if (cmd == QSE_AWK_RIO_OPEN)
{
int flags;
qse_nwad_t nwad;
if (riod->mode != QSE_AWK_RIO_PIPE_RW ||
parse_rwpipe_uri (riod->name, &flags, &nwad) <= -1)
return pio_handler_open (rtx, riod);
else
return nwio_handler_open (rtx, riod, flags, &nwad);
}
else if (riod->handle2)
return nwio_handler_rest (rtx, cmd, riod, data, size);
else
return pio_handler_rest (rtx, cmd, riod, data, size);
}
static qse_ssize_t awk_rio_file (
qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_rio_arg_t* riod,
qse_char_t* data, qse_size_t size)

View File

@ -104,10 +104,7 @@ libqsecmn_la_SOURCES = \
xma.c
libqsecmn_la_LDFLAGS = -L$(libdir) -version-info 1:0:0 -no-undefined
#if WIN32
#libqsecmn_la_LIBADD = -lpsapi
#endif
libqsecmn_la_LIBADD = $(SOCKET_LIBS)
if ENABLE_CXX
@ -115,6 +112,7 @@ lib_LTLIBRARIES += libqsecmnxx.la
libqsecmnxx_la_SOURCES = \
Mmgr.cpp StdMmgr.cpp
libqsecmnxx_la_LDFLAGS = -L$(libdir) -version-info 1:0:0 -no-undefined
libqsecmnxx_la_LIBADD =
endif

View File

@ -35,10 +35,6 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
#if WIN32
#libqsecmn_la_LIBADD = -lpsapi
#endif
@ENABLE_CXX_TRUE@am__append_1 = libqsecmnxx.la
subdir = lib/cmn
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
@ -78,7 +74,8 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(libdir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libqsecmn_la_LIBADD =
am__DEPENDENCIES_1 =
libqsecmn_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
am_libqsecmn_la_OBJECTS = alg-rand.lo alg-search.lo alg-sort.lo \
assert.lo chr.lo cp949.lo cp950.lo dll.lo env.lo gdl.lo htb.lo \
lda.lo fio.lo fma.lo fmt.lo fs.lo fs-err.lo fs-move.lo hton.lo \
@ -98,7 +95,7 @@ libqsecmn_la_OBJECTS = $(am_libqsecmn_la_OBJECTS)
libqsecmn_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libqsecmn_la_LDFLAGS) $(LDFLAGS) -o $@
libqsecmnxx_la_LIBADD =
libqsecmnxx_la_DEPENDENCIES =
am__libqsecmnxx_la_SOURCES_DIST = Mmgr.cpp StdMmgr.cpp
@ENABLE_CXX_TRUE@am_libqsecmnxx_la_OBJECTS = Mmgr.lo StdMmgr.lo
libqsecmnxx_la_OBJECTS = $(am_libqsecmnxx_la_OBJECTS)
@ -384,10 +381,12 @@ libqsecmn_la_SOURCES = \
xma.c
libqsecmn_la_LDFLAGS = -L$(libdir) -version-info 1:0:0 -no-undefined
libqsecmn_la_LIBADD = $(SOCKET_LIBS)
@ENABLE_CXX_TRUE@libqsecmnxx_la_SOURCES = \
@ENABLE_CXX_TRUE@ Mmgr.cpp StdMmgr.cpp
@ENABLE_CXX_TRUE@libqsecmnxx_la_LDFLAGS = -L$(libdir) -version-info 1:0:0 -no-undefined
@ENABLE_CXX_TRUE@libqsecmnxx_la_LIBADD =
all: all-am
.SUFFIXES:

View File

@ -22,7 +22,9 @@
#include "mem.h"
#if defined(_WIN32)
/* TODO: */
# include <winsock2.h>
# include <ws2tcpip.h> /* sockaddr_in6 */
# include <windows.h>
#elif defined(__OS2__)
/* TODO: */
#elif defined(__DOS__)
@ -97,28 +99,24 @@ static qse_nwio_errnum_t syserr_to_errnum (DWORD e)
{
switch (e)
{
case ERROR_NOT_ENOUGH_MEMORY:
case ERROR_OUTOFMEMORY:
case WSA_NOT_ENOUGH_MEMORY:
return QSE_NWIO_ENOMEM;
case ERROR_INVALID_PARAMETER:
case ERROR_INVALID_HANDLE:
case ERROR_INVALID_NAME:
case WSA_INVALID_PARAMETER:
case WSA_INVALID_HANDLE:
return QSE_NWIO_EINVAL;
case ERROR_ACCESS_DENIED:
case WSAEACCES:
return QSE_NWIO_EACCES;
case ERROR_FILE_NOT_FOUND:
case ERROR_PATH_NOT_FOUND:
return QSE_NWIO_ENOENT;
case WSAEINTR:
return QSE_NWIO_EINTR;
case ERROR_ALREADY_EXISTS:
case ERROR_FILE_EXISTS:
return QSE_NWIO_EEXIST;
case ERROR_BROKEN_PIPE:
return QSE_NWIO_EPIPE;
case WSAECONNREFUSED:
case WSAENETUNREACH:
case WSAEHOSTUNREACH:
case WSAEHOSTDOWN:
return QSE_NWIO_ECONN;
default:
return QSE_NWIO_ESYSERR;
@ -205,12 +203,18 @@ static qse_nwio_errnum_t syserr_to_errnum (int e)
case EPIPE:
return QSE_NWIO_EPIPE;
#if defined(ECONNREFUSED) || defined(ENETUNREACH)
#if defined(ECONNREFUSED) || defined(ENETUNREACH) || defined(EHOSTUNREACH) || defined(EHOSTDOWN)
#if defined(ECONNREFUSED)
case ECONNREFUSED:
#endif
#if defined(ENETUNREACH)
case ENETUNREACH:
#endif
#if defined(EHOSTUNREACH)
case EHOSTUNREACH:
#endif
#if defined(EHOSTDOWN)
case EHOSTDOWN:
#endif
return QSE_NWIO_ECONN;
#endif
@ -285,13 +289,6 @@ int qse_nwio_init (
addrlen = nwad_to_sockaddr (nwad, &family, &addr);
#if defined(_WIN32)
/* TODO: */
#elif defined(__OS2__)
/* TODO: */
#elif defined(__DOS__)
/* TODO: */
#else
if (flags & QSE_NWIO_TCP) type = SOCK_STREAM;
else if (flags & QSE_NWIO_UDP) type = SOCK_DGRAM;
else
@ -300,6 +297,65 @@ int qse_nwio_init (
return -1;
}
#if defined(_WIN32)
nwio->handle = socket (family, type, 0);
if (nwio->handle == INVALID_SOCKET)
{
nwio->errnum = syserr_to_errnum (WSAGetLastError());
goto oops;
}
if (flags & QSE_NWIO_PASSIVE)
{
qse_nwio_hnd_t handle;
if (bind (nwio->handle, (struct sockaddr*)&addr, addrlen) == SOCKET_ERROR)
{
nwio->errnum = syserr_to_errnum (WSAGetLastError());
goto oops;
}
if (flags & QSE_NWIO_TCP)
{
if (listen (nwio->handle, 10) == SOCKET_ERROR)
{
nwio->errnum = syserr_to_errnum (WSAGetLastError());
goto oops;
}
handle = accept (nwio->handle, (struct sockaddr*)&addr, &addrlen);
if (handle == INVALID_SOCKET)
{
nwio->errnum = syserr_to_errnum (WSAGetLastError());
goto oops;
}
closesocket (nwio->handle);
nwio->handle = handle;
}
else if (flags & QSE_NWIO_UDP)
{
nwio->status |= UDP_CONNECT_NEEDED;
}
}
else
{
if (connect (nwio->handle, (struct sockaddr*)&addr, addrlen) == SOCKET_ERROR)
{
nwio->errnum = syserr_to_errnum (WSAGetLastError());
goto oops;
}
}
#elif defined(__OS2__)
nwio->errnum = QSE_NWIO_ENOIMPL;
return -1;
#elif defined(__DOS__)
nwio->errnum = QSE_NWIO_ENOIMPL;
return -1;
#else
nwio->handle = socket (family, type, 0);
if (nwio->handle <= -1)
{
@ -307,12 +363,12 @@ int qse_nwio_init (
goto oops;
}
#if defined(FD_CLOEXEC)
#if defined(FD_CLOEXEC)
{
int tmp = fcntl (nwio->handle, F_GETFD);
if (tmp >= 0) fcntl (nwio->handle, F_SETFD, tmp | FD_CLOEXEC);
}
#endif
#endif
if (flags & QSE_NWIO_PASSIVE)
{
@ -339,7 +395,15 @@ int qse_nwio_init (
goto oops;
}
#if defined(_WIN32)
closesocket (nwio->handle);
#elif defined(__OS2__)
/* TODO: */
#elif defined(__DOS__)
/* TODO: */
#else
QSE_CLOSE (nwio->handle);
#endif
nwio->handle = handle;
}
else if (flags & QSE_NWIO_UDP)
@ -386,16 +450,22 @@ int qse_nwio_init (
return 0;
oops:
if (nwio->tio) qse_tio_close (nwio->tio);
if (nwio->tio)
{
qse_tio_close (nwio->tio);
nwio->tio = QSE_NULL;
}
#if defined(_WIN32)
/* TODO: */
if (nwio->handle != INVALID_SOCKET) closesocket (nwio->handle);
#elif defined(__OS2__)
/* TODO: */
#elif defined(__DOS__)
/* TODO: */
#else
QSE_CLOSE (nwio->handle);
if (nwio->handle >= 0) QSE_CLOSE (nwio->handle);
#endif
return -1;
}
@ -409,6 +479,16 @@ void qse_nwio_fini (qse_nwio_t* nwio)
qse_tio_close (nwio->tio);
nwio->tio = QSE_NULL;
}
#if defined(_WIN32)
closesocket (nwio->handle);
#elif defined(__OS2__)
/* TODO: */
#elif defined(__DOS__)
/* TODO: */
#else
QSE_CLOSE (nwio->handle);
#endif
}
qse_nwio_errnum_t qse_nwio_geterrnum (const qse_nwio_t* nwio)
@ -428,7 +508,7 @@ void qse_nwio_setcmgr (qse_nwio_t* nwio, qse_cmgr_t* cmgr)
qse_nwio_hnd_t qse_nwio_gethandle (const qse_nwio_t* nwio)
{
return QSE_NWIO_HANDLE(nwio);
return nwio->handle;
}
qse_ubi_t qse_nwio_gethandleasubi (const qse_nwio_t* nwio)
@ -436,11 +516,11 @@ qse_ubi_t qse_nwio_gethandleasubi (const qse_nwio_t* nwio)
qse_ubi_t ubi;
#if defined(_WIN32)
/* TODO: */
ubi.intptr = nwio->handle;
#elif defined(__OS2__)
/* TODO: */
/* TODO: */
#elif defined(__DOS__)
/* TODO: */
/* TODO: */
#else
ubi.i = nwio->handle;
#endif
@ -473,7 +553,7 @@ void qse_nwio_purge (qse_nwio_t* nwio)
static qse_ssize_t nwio_read (qse_nwio_t* nwio, void* buf, qse_size_t size)
{
#if defined(_WIN32)
DWORD count;
int count;
#elif defined(__OS2__)
ULONG count;
APIRET rc;
@ -484,13 +564,48 @@ static qse_ssize_t nwio_read (qse_nwio_t* nwio, void* buf, qse_size_t size)
#endif
#if defined(_WIN32)
/* TODO: */
if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(int)))
size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(int);
if (nwio->status & UDP_CONNECT_NEEDED)
{
union sockaddr_t addr;
int addrlen;
addrlen = QSE_SIZEOF(addr);
count = recvfrom (
nwio->handle, buf, size, 0,
(struct sockaddr*)&addr, &addrlen);
if (count == SOCKET_ERROR) nwio->errnum = syserr_to_errnum (WSAGetLastError());
else if (count >= 1)
{
/* for udp, it just creates a stream with the
* first sender */
if (connect (nwio->handle, (struct sockaddr*)&addr, addrlen) <= -1)
{
nwio->errnum = syserr_to_errnum (WSAGetLastError());
return -1;
}
nwio->status &= ~UDP_CONNECT_NEEDED;
}
}
else
{
count = recv (nwio->handle, buf, size, 0);
if (count == SOCKET_ERROR) nwio->errnum = syserr_to_errnum (WSAGetLastError());
}
return count;
#elif defined(__OS2__)
/* TODO: */
nwio->errnum = QSE_NWIO_ENOIMPL;
return -1;
#elif defined(__DOS__)
/* TODO: */
nwio->errnum = QSE_NWIO_ENOIMPL;
return -1;
#else
if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(size_t)))
@ -577,7 +692,7 @@ qse_ssize_t qse_nwio_read (qse_nwio_t* nwio, void* buf, qse_size_t size)
static qse_ssize_t nwio_write (qse_nwio_t* nwio, const void* data, qse_size_t size)
{
#if defined(_WIN32)
DWORD count;
int count;
#elif defined(__OS2__)
ULONG count;
APIRET rc;
@ -589,15 +704,22 @@ static qse_ssize_t nwio_write (qse_nwio_t* nwio, const void* data, qse_size_t si
#if defined(_WIN32)
/* TODO: */
if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(int)))
size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(int);
count = send (nwio->handle, data, size, 0);
if (count == SOCKET_ERROR) nwio->errnum = syserr_to_errnum (WSAGetLastError());
return count;
#elif defined(__OS2__)
/* TODO: */
nwio->errnum = QSE_NWIO_ENOIMPL;
return -1;
#elif defined(__DOS__)
/* TODO: */
nwio->errnum = QSE_NWIO_ENOIMPL;
return -1;
#else

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -278,7 +278,7 @@ run_test()
echo_so " You may execute 'diff ${base_outfile} ${outfile}.test' for more info."
return 1
}
rm -f "${outfile}.test"
#rm -f "${outfile}.test"
return 0
}

View File

@ -5,7 +5,7 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/include \
-I$(includedir)
bin_PROGRAMS = awk01 awk02 awk03 awk04 awk09 awk10
bin_PROGRAMS = awk01 awk02 awk03 awk04 awk09 awk10 awk11
LDFLAGS = -L../../lib/awk -L../../lib/cmn
LDADD = -lqseawk -lqsecmn $(LIBM)
@ -20,6 +20,7 @@ awk03_SOURCES = awk03.c
awk04_SOURCES = awk04.c
awk09_SOURCES = awk09.c
awk10_SOURCES = awk10.c
awk11_SOURCES = awk11.c
if ENABLE_CXX

View File

@ -35,7 +35,8 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
bin_PROGRAMS = awk01$(EXEEXT) awk02$(EXEEXT) awk03$(EXEEXT) \
awk04$(EXEEXT) awk09$(EXEEXT) awk10$(EXEEXT) $(am__EXEEXT_1)
awk04$(EXEEXT) awk09$(EXEEXT) awk10$(EXEEXT) awk11$(EXEEXT) \
$(am__EXEEXT_1)
@WIN32_TRUE@am__append_1 = $(UNICOWS_LIBS)
@ENABLE_CXX_TRUE@am__append_2 = awk05 awk06 awk07 awk08
subdir = samples/awk
@ -103,6 +104,10 @@ am_awk10_OBJECTS = awk10.$(OBJEXT)
awk10_OBJECTS = $(am_awk10_OBJECTS)
awk10_LDADD = $(LDADD)
awk10_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
am_awk11_OBJECTS = awk11.$(OBJEXT)
awk11_OBJECTS = $(am_awk11_OBJECTS)
awk11_LDADD = $(LDADD)
awk11_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
DEFAULT_INCLUDES =
depcomp = $(SHELL) $(top_srcdir)/ac/depcomp
am__depfiles_maybe = depfiles
@ -128,11 +133,12 @@ CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
SOURCES = $(awk01_SOURCES) $(awk02_SOURCES) $(awk03_SOURCES) \
$(awk04_SOURCES) $(awk05_SOURCES) $(awk06_SOURCES) \
$(awk07_SOURCES) $(awk08_SOURCES) $(awk09_SOURCES) \
$(awk10_SOURCES)
$(awk10_SOURCES) $(awk11_SOURCES)
DIST_SOURCES = $(awk01_SOURCES) $(awk02_SOURCES) $(awk03_SOURCES) \
$(awk04_SOURCES) $(am__awk05_SOURCES_DIST) \
$(am__awk06_SOURCES_DIST) $(am__awk07_SOURCES_DIST) \
$(am__awk08_SOURCES_DIST) $(awk09_SOURCES) $(awk10_SOURCES)
$(am__awk08_SOURCES_DIST) $(awk09_SOURCES) $(awk10_SOURCES) \
$(awk11_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@ -295,6 +301,7 @@ awk03_SOURCES = awk03.c
awk04_SOURCES = awk04.c
awk09_SOURCES = awk09.c
awk10_SOURCES = awk10.c
awk11_SOURCES = awk11.c
@ENABLE_CXX_TRUE@CXXLIB = -lqseawkxx -lqsecmnxx
@ENABLE_CXX_TRUE@awk05_SOURCES = awk05.cpp
@ENABLE_CXX_TRUE@awk06_SOURCES = awk06.cpp
@ -411,6 +418,9 @@ awk09$(EXEEXT): $(awk09_OBJECTS) $(awk09_DEPENDENCIES)
awk10$(EXEEXT): $(awk10_OBJECTS) $(awk10_DEPENDENCIES)
@rm -f awk10$(EXEEXT)
$(LINK) $(awk10_OBJECTS) $(awk10_LDADD) $(LIBS)
awk11$(EXEEXT): $(awk11_OBJECTS) $(awk11_DEPENDENCIES)
@rm -f awk11$(EXEEXT)
$(LINK) $(awk11_OBJECTS) $(awk11_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@ -428,6 +438,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk08.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk09.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk10.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk11.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<

128
qse/samples/awk/awk11.c Normal file
View File

@ -0,0 +1,128 @@
/*
* $Id: awk01.c 441 2011-04-22 14:28:43Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
QSE is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
QSE 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
*/
#include <qse/awk/std.h>
#include <qse/cmn/stdio.h>
const qse_char_t* src = QSE_T("BEGIN { print \"hello, world\" | \"dir\"; }");
struct rtx_xtn_t
{
qse_awk_rio_fun_t old_pipe_handler;
};
static qse_ssize_t new_pipe_handler (
qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_rio_arg_t* riod,
qse_char_t* data, qse_size_t size)
{
struct rtx_xtn_t* xtn;
xtn = qse_awk_rtx_getxtnstd (rtx);
if (cmd == QSE_AWK_RIO_OPEN)
qse_fprintf (QSE_STDERR, QSE_T("LOG: Executing [%s] for piping\n"), riod->name);
return xtn->old_pipe_handler (rtx, cmd, riod, data, size);
}
static void extend_pipe_handler (qse_awk_rtx_t* rtx)
{
/* this function simply demonstrates how to extend
* runtime I/O handlers provided by qse_awk_rtx_openstd() */
struct rtx_xtn_t* xtn;
qse_awk_rio_t rio;
xtn = qse_awk_rtx_getxtnstd (rtx);
/* get the previous handler functions */
qse_awk_rtx_getrio (rtx, &rio);
/* remember the old pipe handler function */
xtn->old_pipe_handler = rio.pipe;
/* change the pipe handler to a new one */
rio.pipe = new_pipe_handler;
/* changes the handlers with a new set */
qse_awk_rtx_setrio (rtx, &rio);
}
int main ()
{
qse_awk_t* awk = QSE_NULL;
qse_awk_rtx_t* rtx = QSE_NULL;
qse_awk_val_t* retv;
qse_awk_parsestd_t psin;
int ret = -1;
awk = qse_awk_openstd (0);
if (awk == QSE_NULL)
{
qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open awk\n"));
goto oops;
}
//qse_awk_setoption (awk, qse_awk_getoption(awk) | QSE_AWK_RWPIPE);
psin.type = QSE_AWK_PARSESTD_STR;
psin.u.str.ptr = src;
psin.u.str.len = qse_strlen(src);
if (qse_awk_parsestd (awk, &psin, QSE_NULL) <= -1)
{
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"),
qse_awk_geterrmsg(awk));
goto oops;
}
rtx = qse_awk_rtx_openstd (
awk,
QSE_SIZEOF(struct rtx_xtn_t),
QSE_T("awk11"),
QSE_NULL, /* stdin */
QSE_NULL, /* stdout */
QSE_NULL /* default cmgr */
);
if (rtx == QSE_NULL)
{
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"),
qse_awk_geterrmsg(awk));
goto oops;
}
extend_pipe_handler (rtx);
retv = qse_awk_rtx_loop (rtx);
if (retv == QSE_NULL)
{
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"),
qse_awk_rtx_geterrmsg(rtx));
goto oops;
}
qse_awk_rtx_refdownval (rtx, retv);
ret = 0;
oops:
if (rtx != QSE_NULL) qse_awk_rtx_close (rtx);
if (awk != QSE_NULL) qse_awk_close (awk);
return ret;
}