fixed a few bugs in sed
This commit is contained in:
parent
acab50e08a
commit
37bdcd4fb2
19
qse/README
19
qse/README
@ -1,15 +1,28 @@
|
||||
/** @mainpage
|
||||
|
||||
@section INTRODUCTION
|
||||
|
||||
QSE provides a script engine for various scripting languages and utility programs. It aims to produce a flexible script engine framework that can be embedded into an application. A hosting application can access various aspects of the embedded script engine and vice versa.
|
||||
|
||||
<< INSTALL >>
|
||||
The library is licended under the Apache License, Version 2.0.
|
||||
|
||||
The project webpage: http://qse.googlecode.com/
|
||||
|
||||
For furthur information, contact: Chung, Hyung-Hwan <b a c o n e v i @ g m a i l . c o m>
|
||||
|
||||
@section INSTALLATION
|
||||
Cross compiling for WIN32 with MINGW32
|
||||
|
||||
./configure --host=i586-mingw32msvc --target=i586-mingw32msvc --enable-syscall
|
||||
make
|
||||
|
||||
<< DOCUMENTATION >>
|
||||
|
||||
@section DOCUMENTATION
|
||||
Generate the API documents with robodoc.
|
||||
|
||||
robodoc --rc doc/robodoc.rc --css doc/robodoc.css --src . --doc ./doc/qse
|
||||
|
||||
@section MODULES
|
||||
QSE includes various modules:
|
||||
- AWK: awk.h
|
||||
- SED: sed.h
|
||||
*/
|
||||
|
1510
qse/doc/Doxyfile
Normal file
1510
qse/doc/Doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: str.h 138 2009-05-17 09:35:16Z hyunghwan.chung $
|
||||
* $Id: str.h 140 2009-05-18 12:55:01Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
|
||||
@ -22,16 +22,14 @@
|
||||
#include <qse/types.h>
|
||||
#include <qse/macros.h>
|
||||
|
||||
/****o* Common/String
|
||||
* DESCRIPTION
|
||||
/** @file
|
||||
* <qse/cmn/str.h> defines various functions, types, macros to manipulate
|
||||
* strings.
|
||||
* a string.
|
||||
*
|
||||
* The qse_cstr_t type and the qse_xstr_t defined in ase/types.h helps you
|
||||
* The qse_cstr_t type and the qse_xstr_t defined in <qse/types.h> helps you
|
||||
* dealing with a string pointer and length.
|
||||
*
|
||||
* #include <qse/cmn/str.h>
|
||||
******
|
||||
* @example str.c
|
||||
*/
|
||||
|
||||
#define QSE_STR_LEN(s) ((s)->len)
|
||||
@ -43,21 +41,17 @@
|
||||
typedef struct qse_str_t qse_str_t;
|
||||
typedef qse_size_t (*qse_str_sizer_t) (qse_str_t* data, qse_size_t hint);
|
||||
|
||||
/****s* Common/qse_str_t
|
||||
* NAME
|
||||
* qse_str_t - define a dynamically resizable string
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_str_t type defines a dynamically resizable string.
|
||||
*/
|
||||
struct qse_str_t
|
||||
{
|
||||
QSE_DEFINE_COMMON_FIELDS (str)
|
||||
|
||||
qse_str_sizer_t sizer;
|
||||
qse_char_t* ptr;
|
||||
qse_size_t len;
|
||||
qse_size_t capa;
|
||||
};
|
||||
/******/
|
||||
|
||||
/* int qse_chartonum (qse_char_t c, int base) */
|
||||
#define QSE_CHARTONUM(c,base) \
|
||||
@ -109,10 +103,13 @@ struct qse_str_t
|
||||
if (__ston_f > 0) value *= -1; \
|
||||
}
|
||||
|
||||
enum qse_strtrm_opt_t
|
||||
/**
|
||||
* The qse_strtrm_op_t defines a string trimming operation.
|
||||
*/
|
||||
enum qse_strtrm_op_t
|
||||
{
|
||||
QSE_STRTRM_LEFT = (1 << 0),
|
||||
QSE_STRTRM_RIGHT = (1 << 1)
|
||||
QSE_STRTRM_LEFT = (1 << 0), /**< trim leading spaces */
|
||||
QSE_STRTRM_RIGHT = (1 << 1) /**< trim trailing spaces */
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -246,25 +243,25 @@ int qse_strxncmp (
|
||||
|
||||
int qse_strcasecmp (const qse_char_t* s1, const qse_char_t* s2);
|
||||
|
||||
/****f* Common/qse_strxncasecmp
|
||||
* NAME
|
||||
* qse_strxncasecmp - compare strings ignoring case
|
||||
* DESCRIPTION
|
||||
* The qse_strxncasecmp() function compares characters at the same position
|
||||
* in each string after converting them to the same case temporarily.
|
||||
* It accepts two strings and a character class handler. A string is
|
||||
* represented by its beginning pointer and length.
|
||||
/**
|
||||
* The qse_strxncasecmp() function compares characters at the same position
|
||||
* in each string after converting them to the same case temporarily.
|
||||
* It accepts two strings and a character class handler. A string is
|
||||
* represented by its beginning pointer and length.
|
||||
*
|
||||
* For two strings to be equal, they need to have the same length and all
|
||||
* characters in the first string should be equal to their counterpart in the
|
||||
* second string.
|
||||
*
|
||||
* The following code snippet compares "foo" and "FoO" case-insenstively.
|
||||
* @code
|
||||
* qse_strxncasecmp (QSE_T("foo"), 3, QSE_T("FoO"), 3);
|
||||
* @endcode
|
||||
*
|
||||
* @return
|
||||
* The qse_strxncasecmp() returns 0 if two strings are equal, a positive
|
||||
* number if the first string is larger, -1 if the second string is larger.
|
||||
*
|
||||
* For two strings to be equal, they need to have the same length and all
|
||||
* characters in the first string should be equal to their counterpart in the
|
||||
* second string.
|
||||
* RETURN
|
||||
* The qse_strxncasecmp() returns 0 if two strings are equal, a positive
|
||||
* number if the first string is larger, -1 if the second string is larger.
|
||||
* EXAMPLES
|
||||
* The example compares "foo" and "FoO" case-insenstively.
|
||||
* qse_strxncasecmp (QSE_T("foo"), 3, QSE_T("FoO"), 3);
|
||||
* SYNOPSIS
|
||||
*/
|
||||
int qse_strxncasecmp (
|
||||
const qse_char_t* s1 /* the pointer to the first string */,
|
||||
@ -272,7 +269,6 @@ int qse_strxncasecmp (
|
||||
const qse_char_t* s2 /* the pointer to the second string */,
|
||||
qse_size_t len2 /* the length of the second string */
|
||||
);
|
||||
/******/
|
||||
|
||||
qse_char_t* qse_strdup (const qse_char_t* str, qse_mmgr_t* mmgr);
|
||||
qse_char_t* qse_strxdup (
|
||||
@ -303,15 +299,49 @@ qse_char_t* qse_strxnbeg (
|
||||
const qse_char_t* str, qse_size_t len1,
|
||||
const qse_char_t* sub, qse_size_t len2);
|
||||
|
||||
/* Checks if a string ends with a substring */
|
||||
qse_char_t* qse_strend (const qse_char_t* str, const qse_char_t* sub);
|
||||
/**
|
||||
* The qse_strend() function checks if the a string ends with a substring.
|
||||
* @return the pointer to a beginning of a matching end,
|
||||
* QSE_NULL if no match is found.
|
||||
*/
|
||||
qse_char_t* qse_strend (
|
||||
const qse_char_t* str, /**< a string */
|
||||
const qse_char_t* sub /**< a substring */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_strxend function checks if the a string ends with a substring.
|
||||
* @return the pointer to a beginning of a matching end,
|
||||
* QSE_NULL if no match is found.
|
||||
*/
|
||||
qse_char_t* qse_strxend (
|
||||
const qse_char_t* str, qse_size_t len, const qse_char_t* sub);
|
||||
const qse_char_t* str,
|
||||
qse_size_t len,
|
||||
const qse_char_t* sub
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_strnend() function checks if the a string ends with a substring.
|
||||
* @return the pointer to a beginning of a matching end,
|
||||
* QSE_NULL if no match is found.
|
||||
*/
|
||||
qse_char_t* qse_strnend (
|
||||
const qse_char_t* str, const qse_char_t* sub, qse_size_t len);
|
||||
const qse_char_t* str,
|
||||
const qse_char_t* sub,
|
||||
qse_size_t len
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_strxnend() function checks if the a string ends with a substring.
|
||||
* @return the pointer to a beginning of a matching end,
|
||||
* QSE_NULL if no match is found.
|
||||
*/
|
||||
qse_char_t* qse_strxnend (
|
||||
const qse_char_t* str, qse_size_t len1,
|
||||
const qse_char_t* sub, qse_size_t len2);
|
||||
const qse_char_t* str,
|
||||
qse_size_t len1,
|
||||
const qse_char_t* sub,
|
||||
qse_size_t len2
|
||||
);
|
||||
|
||||
/*
|
||||
* string conversion
|
||||
@ -336,6 +366,191 @@ qse_long_t qse_strxtolong (const qse_char_t* str, qse_size_t len);
|
||||
qse_uint_t qse_strxtouint (const qse_char_t* str, qse_size_t len);
|
||||
qse_ulong_t qse_strxtoulong (const qse_char_t* str, qse_size_t len);
|
||||
|
||||
/****f* Common/qse_strspl
|
||||
* NAME
|
||||
* qse_strspl - split a string into fields
|
||||
* SEE ALSO
|
||||
* qse_strspltrn
|
||||
* SYNOPSIS
|
||||
*/
|
||||
int qse_strspl (
|
||||
qse_char_t* str,
|
||||
const qse_char_t* delim,
|
||||
qse_char_t lquote,
|
||||
qse_char_t rquote,
|
||||
qse_char_t escape
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_strspltrn
|
||||
* NAME
|
||||
* qse_strspltrn - split a string translating special escape sequences
|
||||
* DESCRIPTION
|
||||
* The argument trset is a translation character set which is composed
|
||||
* of multiple character pairs. An escape character followed by the
|
||||
* first character in a pair is translated into the second character
|
||||
* in the pair. If trset is QSE_NULL, no translation is performed.
|
||||
* EXAMPLES
|
||||
* Let's translate a sequence of '\n' and '\r' to a new line and a carriage
|
||||
* return respectively.
|
||||
* qse_strspltrn (str, QSE_T(':'), QSE_T('['), QSE_T(']'), QSE_T('\\'), QSE_T("n\nr\r"), &nfields);
|
||||
* Given [xxx]:[\rabc\ndef]:[] as an input, the example breaks the second
|
||||
* fields to <CR>abc<NL>def where <CR> is a carriage return and <NL> is a
|
||||
* new line.
|
||||
* SEE ALSO
|
||||
* If you don't need any translation, you may call qse_strspl() alternatively.
|
||||
* SYNOPSIS
|
||||
*/
|
||||
int qse_strspltrn (
|
||||
qse_char_t* str,
|
||||
const qse_char_t* delim,
|
||||
qse_char_t lquote,
|
||||
qse_char_t rquote,
|
||||
qse_char_t escape,
|
||||
const qse_char_t* trset
|
||||
);
|
||||
/******/
|
||||
|
||||
/**
|
||||
* The qse_strtrm() function removes leading spaces and/or trailing
|
||||
* spaces from a string depending on the opt parameter. You can form
|
||||
* the op parameter by bitwise-OR'ing one or more of the following
|
||||
* values:
|
||||
*
|
||||
* - QSE_STRTRM_LEFT - trim leading spaces
|
||||
* - QSE_STRTRM_RIGHT - trim trailing spaces
|
||||
*
|
||||
* Should it remove leading spaces, it just returns the pointer to
|
||||
* the first non-space character in the string. Should it remove trailing
|
||||
* spaces, it inserts a QSE_T('\0') character after the last non-space
|
||||
* characters. Take note of this behavior.
|
||||
*
|
||||
* @code
|
||||
* qse_char_t a[] = QSE_T(" this is a test string ");
|
||||
* qse_printf (QSE_T("[%s]\n"), qse_strtrm(a,QSE_STRTRM_LEFT|QSE_STRTRM_RIGHT));
|
||||
* @endcode
|
||||
*
|
||||
* @return the pointer to a trimmed string.
|
||||
*/
|
||||
qse_char_t* qse_strtrm (
|
||||
qse_char_t* str, /**< a string */
|
||||
int op /**< operation code XOR'ed of qse_strtrm_op_t values */
|
||||
);
|
||||
|
||||
|
||||
/****f* Common/qse_mbstowcs
|
||||
* NAME
|
||||
* qse_mbstowcs - convert a multibyte string to a wide character string
|
||||
* SYNOPSIS
|
||||
*/
|
||||
qse_size_t qse_mbstowcs (
|
||||
const qse_mchar_t* mbs,
|
||||
qse_wchar_t* wcs,
|
||||
qse_size_t* wcslen
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_mbsntowcsn
|
||||
* NAME
|
||||
* qse_mbsntowcsn - convert a multibyte string to a wide character string
|
||||
* RETURN
|
||||
* The qse_mbstowcs() function returns the number of bytes handled.
|
||||
* SYNOPSIS
|
||||
*/
|
||||
qse_size_t qse_mbsntowcsn (
|
||||
const qse_mchar_t* mbs,
|
||||
qse_size_t mbslen,
|
||||
qse_wchar_t* wcs,
|
||||
qse_size_t* wcslen
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_wcstombslen
|
||||
* NAME
|
||||
* qse_wcstombslen - get the length
|
||||
* DESCRIPTION
|
||||
* The qse_wcstombslen() function scans a null-terminated wide character
|
||||
* string to get the total number of multibyte characters that it can be
|
||||
* converted to. The resulting number of characters is stored into memory
|
||||
* pointed to by mbslen.
|
||||
* RETURN
|
||||
* The qse_wcstombslen() function returns the number of wide characters
|
||||
* handled.
|
||||
* SYNOPSIS
|
||||
*/
|
||||
qse_size_t qse_wcstombslen (
|
||||
const qse_wchar_t* wcs,
|
||||
qse_size_t* mbslen
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_wcsntombsnlen
|
||||
* NAME
|
||||
* qse_wcsntombsnlen - get the length
|
||||
* DESCRIPTION
|
||||
* The qse_wcsntombsnlen() function scans a wide character wcs as long as
|
||||
* wcslen characters to get the get the total number of multibyte characters
|
||||
* that it can be converted to. The resulting number of characters is stored
|
||||
* into memory pointed to by mbslen.
|
||||
* RETURN
|
||||
* The qse_wcsntombsnlen() function returns the number of wide characters
|
||||
* handled.
|
||||
* SYNOPSIS
|
||||
*/
|
||||
qse_size_t qse_wcsntombsnlen (
|
||||
const qse_wchar_t* wcs,
|
||||
qse_size_t wcslen,
|
||||
qse_size_t* mbslen
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_wcstombs
|
||||
* NAME
|
||||
* qse_wcstombs - convert a wide character string to a multibyte string.
|
||||
* DESCRIPTION
|
||||
* The qse_wcstombs() function converts a null-terminated wide character
|
||||
* string to a multibyte string and stores it into the buffer pointed to
|
||||
* by mbs. The pointer to a variable holding the buffer length should be
|
||||
* passed to the function as the third parameter. After conversion, it holds
|
||||
* the length of the multibyte string excluding the terminating-null.
|
||||
* It may not null-terminate the resulting multibyte string if the buffer
|
||||
* is not large enough. You can check if the resulting mbslen is equal to
|
||||
* the input mbslen to know it.
|
||||
* RETURN
|
||||
* The qse_wcstombs() function returns the number of wide characters handled.
|
||||
* SYNOPSIS
|
||||
*/
|
||||
qse_size_t qse_wcstombs (
|
||||
const qse_wchar_t* wcs,
|
||||
qse_mchar_t* mbs,
|
||||
qse_size_t* mbslen
|
||||
);
|
||||
/******/
|
||||
|
||||
/**
|
||||
* The qse_wcsntombsn() function converts a wide character string to a
|
||||
* multibyte string.
|
||||
* @return the number of wide characters
|
||||
*/
|
||||
qse_size_t qse_wcsntombsn (
|
||||
const qse_wchar_t* wcs, /**< a wide string */
|
||||
qse_size_t wcslen, /**< wide string length */
|
||||
qse_mchar_t* mbs, /**< a multibyte string buffer */
|
||||
qse_size_t* mbslen /**< the buffer size */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_wcstombs_strict() function performs the same as the qse_wcsmbs()
|
||||
* function except that it returns an error if it can't fully convert the
|
||||
* input string and/or the buffer is not large enough.
|
||||
* @return 0 on success, -1 on failure.
|
||||
*/
|
||||
int qse_wcstombs_strict (
|
||||
const qse_wchar_t* wcs,
|
||||
qse_mchar_t* mbs,
|
||||
qse_size_t mbslen
|
||||
);
|
||||
|
||||
QSE_DEFINE_COMMON_FUNCTIONS (str)
|
||||
|
||||
qse_str_t* qse_str_open (
|
||||
@ -545,201 +760,6 @@ qse_size_t qse_str_del (
|
||||
qse_size_t size
|
||||
);
|
||||
|
||||
/****f* Common/qse_strspl
|
||||
* NAME
|
||||
* qse_strspl - split a string into fields
|
||||
* SEE ALSO
|
||||
* qse_strspltrn
|
||||
* SYNOPSIS
|
||||
*/
|
||||
int qse_strspl (
|
||||
qse_char_t* str,
|
||||
const qse_char_t* delim,
|
||||
qse_char_t lquote,
|
||||
qse_char_t rquote,
|
||||
qse_char_t escape
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_strspltrn
|
||||
* NAME
|
||||
* qse_strspltrn - split a string translating special escape sequences
|
||||
* DESCRIPTION
|
||||
* The argument trset is a translation character set which is composed
|
||||
* of multiple character pairs. An escape character followed by the
|
||||
* first character in a pair is translated into the second character
|
||||
* in the pair. If trset is QSE_NULL, no translation is performed.
|
||||
* EXAMPLES
|
||||
* Let's translate a sequence of '\n' and '\r' to a new line and a carriage
|
||||
* return respectively.
|
||||
* qse_strspltrn (str, QSE_T(':'), QSE_T('['), QSE_T(']'), QSE_T('\\'), QSE_T("n\nr\r"), &nfields);
|
||||
* Given [xxx]:[\rabc\ndef]:[] as an input, the example breaks the second
|
||||
* fields to <CR>abc<NL>def where <CR> is a carriage return and <NL> is a
|
||||
* new line.
|
||||
* SEE ALSO
|
||||
* If you don't need any translation, you may call qse_strspl() alternatively.
|
||||
* SYNOPSIS
|
||||
*/
|
||||
int qse_strspltrn (
|
||||
qse_char_t* str,
|
||||
const qse_char_t* delim,
|
||||
qse_char_t lquote,
|
||||
qse_char_t rquote,
|
||||
qse_char_t escape,
|
||||
const qse_char_t* trset
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_strtrm
|
||||
* NAME
|
||||
* qse_strtrm - remove leading and/or trailing spaces from a string
|
||||
* DESCRIPTION
|
||||
* The qse_strtrm() function removes leading spaces and/or trailing
|
||||
* spaces from a string depending on the opt parameter. You can form
|
||||
* the opt parameter by bitwise-OR'ing one or more of the following
|
||||
* values.
|
||||
* * QSE_STRTRM_LEFT - remove leading spaces
|
||||
* * QSE_STRTRM_RIGHT - remove trailing spaces
|
||||
* It returns the pointer to the trimmed string.
|
||||
* NOTE
|
||||
* Should it remove leading spaces, it just returns the pointer to
|
||||
* the first non-space character in the string. Should it remove trailing
|
||||
* spaces, it inserts a QSE_T('\0') character after the last non-space
|
||||
* characters.
|
||||
* EXAMPLES
|
||||
* The example removes leading and trailing spaces from the string a.
|
||||
* qse_char_t a[] = QSE_T(" this is a test string ");
|
||||
* qse_printf (QSE_T("[%s]\n"), a);
|
||||
* qse_printf (QSE_T("[%s]\n"), qse_strtrm (a, QSE_STRTRM_LEFT|QSE_STRTRM_RIGHT));
|
||||
* SYNOPSIS
|
||||
*/
|
||||
qse_char_t* qse_strtrm (
|
||||
qse_char_t* str,
|
||||
int opt
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_mbstowcs
|
||||
* NAME
|
||||
* qse_mbstowcs - convert a multibyte string to a wide character string
|
||||
* SYNOPSIS
|
||||
*/
|
||||
qse_size_t qse_mbstowcs (
|
||||
const qse_mchar_t* mbs,
|
||||
qse_wchar_t* wcs,
|
||||
qse_size_t* wcslen
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_mbsntowcsn
|
||||
* NAME
|
||||
* qse_mbsntowcsn - convert a multibyte string to a wide character string
|
||||
* RETURN
|
||||
* The qse_mbstowcs() function returns the number of bytes handled.
|
||||
* SYNOPSIS
|
||||
*/
|
||||
qse_size_t qse_mbsntowcsn (
|
||||
const qse_mchar_t* mbs,
|
||||
qse_size_t mbslen,
|
||||
qse_wchar_t* wcs,
|
||||
qse_size_t* wcslen
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_wcstombslen
|
||||
* NAME
|
||||
* qse_wcstombslen - get the length
|
||||
* DESCRIPTION
|
||||
* The qse_wcstombslen() function scans a null-terminated wide character
|
||||
* string to get the total number of multibyte characters that it can be
|
||||
* converted to. The resulting number of characters is stored into memory
|
||||
* pointed to by mbslen.
|
||||
* RETURN
|
||||
* The qse_wcstombslen() function returns the number of wide characters
|
||||
* handled.
|
||||
* SYNOPSIS
|
||||
*/
|
||||
qse_size_t qse_wcstombslen (
|
||||
const qse_wchar_t* wcs,
|
||||
qse_size_t* mbslen
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_wcsntombsnlen
|
||||
* NAME
|
||||
* qse_wcsntombsnlen - get the length
|
||||
* DESCRIPTION
|
||||
* The qse_wcsntombsnlen() function scans a wide character wcs as long as
|
||||
* wcslen characters to get the get the total number of multibyte characters
|
||||
* that it can be converted to. The resulting number of characters is stored
|
||||
* into memory pointed to by mbslen.
|
||||
* RETURN
|
||||
* The qse_wcsntombsnlen() function returns the number of wide characters
|
||||
* handled.
|
||||
* SYNOPSIS
|
||||
*/
|
||||
qse_size_t qse_wcsntombsnlen (
|
||||
const qse_wchar_t* wcs,
|
||||
qse_size_t wcslen,
|
||||
qse_size_t* mbslen
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_wcstombs
|
||||
* NAME
|
||||
* qse_wcstombs - convert a wide character string to a multibyte string.
|
||||
* DESCRIPTION
|
||||
* The qse_wcstombs() function converts a null-terminated wide character
|
||||
* string to a multibyte string and stores it into the buffer pointed to
|
||||
* by mbs. The pointer to a variable holding the buffer length should be
|
||||
* passed to the function as the third parameter. After conversion, it holds
|
||||
* the length of the multibyte string excluding the terminating-null.
|
||||
* It may not null-terminate the resulting multibyte string if the buffer
|
||||
* is not large enough. You can check if the resulting mbslen is equal to
|
||||
* the input mbslen to know it.
|
||||
* RETURN
|
||||
* The qse_wcstombs() function returns the number of wide characters handled.
|
||||
* SYNOPSIS
|
||||
*/
|
||||
qse_size_t qse_wcstombs (
|
||||
const qse_wchar_t* wcs,
|
||||
qse_mchar_t* mbs,
|
||||
qse_size_t* mbslen
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_wcsntombsn
|
||||
* NAME
|
||||
* qse_wcstombs - convert a wide character string to a multibyte string
|
||||
* RETURN
|
||||
* The qse_wcstombs() function returns the number of wide characters handled.
|
||||
* SYNOPSIS
|
||||
*/
|
||||
qse_size_t qse_wcsntombsn (
|
||||
const qse_wchar_t* wcs,
|
||||
qse_size_t wcslen,
|
||||
qse_mchar_t* mbs,
|
||||
qse_size_t* mbslen
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_wcstombs_strict
|
||||
* NAME
|
||||
* qse_wcstombs_strict - convert a wide character string to a multibyte string.
|
||||
* DESCRIPTION
|
||||
* The qse_wcstombs_strict() function performs the same as the qse_wcsmbs()
|
||||
* function except that it returns an error if it can't fully convert the
|
||||
* input string and/or the buffer is not large enough.
|
||||
* RETURN
|
||||
* The qse_wcstombs_strict() function returns 0 on success and -1 on failure.
|
||||
* SYNOPSIS
|
||||
*/
|
||||
int qse_wcstombs_strict (
|
||||
const qse_wchar_t* wcs,
|
||||
qse_mchar_t* mbs,
|
||||
qse_size_t mbslen
|
||||
);
|
||||
/******/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: macros.h 119 2009-04-02 07:09:10Z hyunghwan.chung $
|
||||
* $Id: macros.h 140 2009-05-18 12:55:01Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
|
||||
@ -19,6 +19,10 @@
|
||||
#ifndef _QSE_MACROS_H_
|
||||
#define _QSE_MACROS_H_
|
||||
|
||||
/** @file
|
||||
* <qse/macros.h> contains various useful macro definitions.
|
||||
*/
|
||||
|
||||
#include <qse/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -39,25 +43,48 @@
|
||||
#define QSE_WCHAR_EOF ((qse_wcint_t)-1)
|
||||
#define QSE_CHAR_EOF ((qse_cint_t)-1)
|
||||
|
||||
/****m* Base/QSE_SIZEOF
|
||||
* NAME
|
||||
* QSE_SIZEOF - get data size in bytes
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The QSE_SIZEOF() macro gets data size in bytes. It is equivalent to the
|
||||
* sizeof operator. The following code snippet should print sizeof(int)*128.
|
||||
* @code
|
||||
* int x[128];
|
||||
* printf ("%d\n", (int)QSE_SIZEOF(x));
|
||||
* @endcode
|
||||
*/
|
||||
#define QSE_SIZEOF(n) (sizeof(n))
|
||||
/******/
|
||||
|
||||
/****m* Base/QSE_COUNTOF
|
||||
* NAME
|
||||
* QSE_COUNTOF - get the number elements in a array
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The QSE_COUNTOF() macro gets the number elements in a array.
|
||||
* The following code snippet should print 128.
|
||||
* @code
|
||||
* int x[128];
|
||||
* printf ("%d\n", (int)QSE_COUNTOF(x));
|
||||
* @endcode
|
||||
*/
|
||||
#define QSE_COUNTOF(n) (sizeof(n)/sizeof(n[0]))
|
||||
/******/
|
||||
|
||||
/**
|
||||
* The QSE_OFFSETOF() macro get the offset of a fields from the beginning
|
||||
* of a structure.
|
||||
*/
|
||||
#define QSE_OFFSETOF(type,member) ((qse_size_t)&((type*)0)->member)
|
||||
|
||||
/**
|
||||
* The QSE_TYPE_IS_SIGNED() macro determines if a type is signed.
|
||||
* @code
|
||||
* printf ("%d\n", QSE_TYPE_IS_SIGNED(int));
|
||||
* printf ("%d\n", QSE_TYPE_IS_SIGNED(unsigned int));
|
||||
* @endcode
|
||||
*/
|
||||
#define QSE_TYPE_IS_SIGNED(type) (((type)0) > ((type)-1))
|
||||
|
||||
/**
|
||||
* The QSE_TYPE_IS_SIGNED() macro determines if a type is unsigned.
|
||||
* @code
|
||||
* printf ("%d\n", QSE_TYPE_IS_UNSIGNED(int));
|
||||
* printf ("%d\n", QSE_TYPE_IS_UNSIGNED(unsigned int));
|
||||
* @endcode
|
||||
*/
|
||||
#define QSE_TYPE_IS_UNSIGNED(type) (((type)0) < ((type)-1))
|
||||
|
||||
#define QSE_TYPE_SIGNED_MAX(type) \
|
||||
@ -168,50 +195,35 @@
|
||||
# define QSE_END_NAMESPACE2(y,x) }}
|
||||
#endif
|
||||
|
||||
/****m* Base/QSE_DEFINE_COMMON_FIELDS
|
||||
* NAME
|
||||
* QSE_DEFINE_COMMON_FIELDS - define common fields
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The QSE_DEFINE_COMMON_FIELDS() macro defines common object fields.
|
||||
*/
|
||||
#define QSE_DEFINE_COMMON_FIELDS(name) \
|
||||
qse_mmgr_t* mmgr;
|
||||
/******/
|
||||
|
||||
/****m* Base/QSE_DEFINE_COMMON_FUNCTIONS
|
||||
* NAME
|
||||
* QSE_DEFINE_COMMON_FUNCTIONS - define common functions
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The QSE_DEFINE_COMMON_FUNcTIONS() macro defines common object functions.
|
||||
*/
|
||||
#define QSE_DEFINE_COMMON_FUNCTIONS(name) \
|
||||
void qse_##name##_setmmgr (qse_##name##_t* name, qse_mmgr_t* mmgr); \
|
||||
qse_mmgr_t* qse_##name##_getmmgr (qse_##name##_t* name); \
|
||||
void* qse_##name##_getxtn (qse_##name##_t* name);
|
||||
/******/
|
||||
|
||||
/****m* Base/QSE_MMGR
|
||||
* NAME
|
||||
* QSE_MMGR - get the memory manager field
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The QSE_MMGR() macro gets the memory manager field from an object.
|
||||
*/
|
||||
#define QSE_MMGR(obj) (obj->mmgr)
|
||||
/******/
|
||||
#define QSE_MMGR(obj) ((obj)->mmgr)
|
||||
|
||||
/****m* Base/QSE_XTN
|
||||
* NAME
|
||||
* QSE_XTN - get a pointer to extension space
|
||||
* DESCRIPTION
|
||||
* The QSE_XTN() macro is a convenience macro to retrieve the pointer to
|
||||
* extension space located at the end of an object. The type of the object
|
||||
* should be known in advance for it to work properly.
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The QSE_XTN() macro is a convenience macro to retrieve the pointer to
|
||||
* extension space located at the end of an object. The type of the object
|
||||
* should be known in advance for it to work properly.
|
||||
*/
|
||||
#define QSE_XTN(obj) ((void*)(obj + 1))
|
||||
/******/
|
||||
|
||||
/****m* Base/QSE_IMPLEMENT_COMMON_FUNCTIONS
|
||||
* NAME
|
||||
* QSE_IMPLEMENT_COMMON_FUNCTIONS - implement common functions
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The QSE_IMPLEMENT_COMMON_FUNCTIONS() implement common functions for
|
||||
* an object.
|
||||
*/
|
||||
#define QSE_IMPLEMENT_COMMON_FUNCTIONS(name) \
|
||||
void qse_##name##_setmmgr (qse_##name##_t* name, qse_mmgr_t* mmgr) \
|
||||
@ -226,7 +238,5 @@ void* qse_##name##_getxtn (qse_##name##_t* name) \
|
||||
{ \
|
||||
return QSE_XTN(name); \
|
||||
}
|
||||
/******/
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -25,52 +25,74 @@
|
||||
#include <qse/cmn/lda.h>
|
||||
#include <qse/cmn/map.h>
|
||||
|
||||
/** @file
|
||||
* A stream editor performs text transformation on a text stream.
|
||||
*
|
||||
* @code
|
||||
* sed = qse_sed_open ();
|
||||
* qse_sed_comp (sed);
|
||||
* qse_sed_exec (sed);
|
||||
* qse_sed_close (sed);
|
||||
* @endcode
|
||||
*
|
||||
* @example sed01.c
|
||||
* This example shows how to embed a basic stream editor.
|
||||
*/
|
||||
|
||||
/**
|
||||
* defines error numbers
|
||||
*/
|
||||
enum qse_sed_errnum_t
|
||||
{
|
||||
QSE_SED_ENOERR, /* no error */
|
||||
QSE_SED_ENOMEM, /* no memory */
|
||||
QSE_SED_ETMTXT, /* too much text */
|
||||
QSE_SED_ECMDNR, /* command not recognized */
|
||||
QSE_SED_ECMDMS, /* command missing */
|
||||
QSE_SED_ECMDGB, /* command garbled */
|
||||
QSE_SED_EREXBL, /* regular expression build error */
|
||||
QSE_SED_EREXMA, /* regular expression match error */
|
||||
QSE_SED_EA1PHB, /* address 1 prohibited */
|
||||
QSE_SED_EA2PHB, /* address 2 prohibited */
|
||||
QSE_SED_ENEWLN, /* a new line is expected */
|
||||
QSE_SED_EBSEXP, /* \ is expected */
|
||||
QSE_SED_EBSDEL, /* \ used a delimiter */
|
||||
QSE_SED_EGBABS, /* garbage after \ */
|
||||
QSE_SED_ESCEXP, /* ; is expected */
|
||||
QSE_SED_ELABTL, /* label too long */
|
||||
QSE_SED_ELABEM, /* label name is empty */
|
||||
QSE_SED_ELABDU, /* duplicate label name */
|
||||
QSE_SED_ELABNF, /* label not found */
|
||||
QSE_SED_EFILEM, /* file name is empty */
|
||||
QSE_SED_EFILIL, /* illegal file name */
|
||||
QSE_SED_ENOTRM, /* not terminated properly */
|
||||
QSE_SED_ETSNSL, /* translation set not the same length*/
|
||||
QSE_SED_EGRNBA, /* group brackets not balanced */
|
||||
QSE_SED_EGRNTD, /* group nested too deeply */
|
||||
QSE_SED_EOCSDU, /* multiple occurrence specifiers */
|
||||
QSE_SED_EOCSZE, /* occurrence specifier to s is zero */
|
||||
QSE_SED_EOCSTL, /* occurrence specifier too large */
|
||||
QSE_SED_EIOUSR /* user io error */
|
||||
QSE_SED_ENOERR, /**< no error occurred */
|
||||
QSE_SED_ENOMEM, /**< insufficient memory is available */
|
||||
QSE_SED_ETMTXT, /**< too much text */
|
||||
QSE_SED_ECMDNR, /**< a command is not recognized */
|
||||
QSE_SED_ECMDMS, /**< a command is missing */
|
||||
QSE_SED_ECMDGB, /**< command garbled */
|
||||
QSE_SED_EREXBL, /**< regular expression build error */
|
||||
QSE_SED_EREXMA, /**< regular expression match error */
|
||||
QSE_SED_EA1PHB, /**< address 1 prohibited */
|
||||
QSE_SED_EA2PHB, /**< address 2 prohibited */
|
||||
QSE_SED_ENEWLN, /**< a new line is expected */
|
||||
QSE_SED_EBSEXP, /**< \ is expected */
|
||||
QSE_SED_EBSDEL, /**< \ used a delimiter */
|
||||
QSE_SED_EGBABS, /**< garbage after \ */
|
||||
QSE_SED_ESCEXP, /**< ; is expected */
|
||||
QSE_SED_ELABTL, /**< label too long */
|
||||
QSE_SED_ELABEM, /**< label name is empty */
|
||||
QSE_SED_ELABDU, /**< duplicate label name */
|
||||
QSE_SED_ELABNF, /**< label not found */
|
||||
QSE_SED_EFILEM, /**< file name is empty */
|
||||
QSE_SED_EFILIL, /**< illegal file name */
|
||||
QSE_SED_ENOTRM, /**< not terminated properly */
|
||||
QSE_SED_ETSNSL, /**< translation set not the same length*/
|
||||
QSE_SED_EGRNBA, /**< group brackets not balanced */
|
||||
QSE_SED_EGRNTD, /**< group nested too deeply */
|
||||
QSE_SED_EOCSDU, /**< multiple occurrence specifiers */
|
||||
QSE_SED_EOCSZE, /**< occurrence specifier to s is zero */
|
||||
QSE_SED_EOCSTL, /**< occurrence specifier too large */
|
||||
QSE_SED_EIOUSR /**< user io error */
|
||||
};
|
||||
typedef enum qse_sed_errnum_t qse_sed_errnum_t;
|
||||
|
||||
/**
|
||||
* The qse_sed_option_t type defines various option codes for a stream editor.
|
||||
* Options can be XOR'ed with each other and be passed to a stream editor with
|
||||
* the qse_sed_setoption() function.
|
||||
*/
|
||||
enum qse_sed_option_t
|
||||
{
|
||||
QSE_SED_STRIPLS = (1 << 0), /* strip leading spaces from text*/
|
||||
QSE_SED_KEEPTBS = (1 << 1), /* keep an trailing backslash */
|
||||
QSE_SED_ENSURENL = (1 << 2), /* ensure NL at the text end */
|
||||
QSE_SED_QUIET = (1 << 3), /* do not print pattern space */
|
||||
QSE_SED_CLASSIC = (1 << 4)
|
||||
QSE_SED_STRIPLS = (1 << 0), /**< strip leading spaces from text */
|
||||
QSE_SED_KEEPTBS = (1 << 1), /**< keep an trailing backslash */
|
||||
QSE_SED_ENSURENL = (1 << 2), /**< ensure NL at the text end */
|
||||
QSE_SED_QUIET = (1 << 3), /**< do not print pattern space */
|
||||
QSE_SED_CLASSIC = (1 << 4) /**< disable extended features */
|
||||
};
|
||||
|
||||
/****e* AWK/qse_sed_io_cmd_t
|
||||
* NAME
|
||||
* qse_sed_io_cmd_t - define IO commands
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_sed_io_cmd_t type defines IO command codes. The code indicates
|
||||
* the action to take in an IO handler.
|
||||
*/
|
||||
enum qse_sed_io_cmd_t
|
||||
{
|
||||
@ -80,8 +102,10 @@ enum qse_sed_io_cmd_t
|
||||
QSE_SED_IO_WRITE = 3
|
||||
};
|
||||
typedef enum qse_sed_io_cmd_t qse_sed_io_cmd_t;
|
||||
/******/
|
||||
|
||||
/**
|
||||
* The qse_sed_io_arg_t type defines a data structure required by an IO handler.
|
||||
*/
|
||||
union qse_sed_io_arg_t
|
||||
{
|
||||
struct
|
||||
@ -113,34 +137,43 @@ typedef union qse_sed_io_arg_t qse_sed_io_arg_t;
|
||||
|
||||
typedef struct qse_sed_t qse_sed_t;
|
||||
|
||||
/**
|
||||
* The qse_sed_cmd_t type represents a compiled form of a stream editor
|
||||
* command. The details are hidden.
|
||||
*/
|
||||
typedef struct qse_sed_cmd_t qse_sed_cmd_t;
|
||||
|
||||
/**
|
||||
* The qse_sed_iof_t type defines an IO handler. An IO handler is called by
|
||||
* qse_sed_execute().
|
||||
*/
|
||||
typedef qse_ssize_t (*qse_sed_iof_t) (
|
||||
qse_sed_t* sed,
|
||||
qse_sed_io_cmd_t cmd,
|
||||
qse_sed_io_arg_t* arg
|
||||
);
|
||||
|
||||
typedef struct qse_sed_cmd_t qse_sed_cmd_t; /* command */
|
||||
typedef enum qse_sed_errnum_t qse_sed_errnum_t;
|
||||
|
||||
/**
|
||||
* The qse_sed_t type defines a stream editor
|
||||
*/
|
||||
struct qse_sed_t
|
||||
{
|
||||
QSE_DEFINE_COMMON_FIELDS (sed)
|
||||
qse_sed_errnum_t errnum;
|
||||
int option;
|
||||
|
||||
/* source code pointers */
|
||||
qse_sed_errnum_t errnum; /**< stores an error number */
|
||||
int option; /**< stores options */
|
||||
|
||||
/** source text pointers */
|
||||
struct
|
||||
{
|
||||
const qse_char_t* ptr;
|
||||
const qse_char_t* end;
|
||||
const qse_char_t* cur;
|
||||
const qse_char_t* ptr; /**< beginning of the source text */
|
||||
const qse_char_t* end; /**< end of the source text */
|
||||
const qse_char_t* cur; /**< current source text pointer */
|
||||
} src;
|
||||
|
||||
void* lastrex;
|
||||
qse_str_t rexbuf; /* temporary regular expression buffer */
|
||||
qse_str_t rexbuf; /**< temporary regular expression buffer */
|
||||
|
||||
/* command array */
|
||||
/*qse_lda_t cmds;*/
|
||||
struct
|
||||
{
|
||||
qse_sed_cmd_t* buf;
|
||||
@ -148,23 +181,25 @@ struct qse_sed_t
|
||||
qse_sed_cmd_t* cur;
|
||||
} cmd;
|
||||
|
||||
qse_map_t labs; /* label map */
|
||||
/** a table storing labels seen */
|
||||
qse_map_t labs;
|
||||
|
||||
struct
|
||||
{
|
||||
/* current level of command group nesting */
|
||||
/** current level of command group nesting */
|
||||
int level;
|
||||
/* temporary storage to keep track of the begining of a command group */
|
||||
/** keeps track of the begining of a command group */
|
||||
qse_sed_cmd_t* cmd[128];
|
||||
} grp;
|
||||
|
||||
/* data for execution */
|
||||
/** data for execution */
|
||||
struct
|
||||
{
|
||||
/** data needed for output streams and files */
|
||||
struct
|
||||
{
|
||||
qse_sed_iof_t f;
|
||||
qse_sed_io_arg_t arg;
|
||||
qse_sed_iof_t f; /**< an output handler */
|
||||
qse_sed_io_arg_t arg; /**< output handling data */
|
||||
|
||||
qse_char_t buf[2048];
|
||||
qse_size_t len;
|
||||
@ -178,23 +213,25 @@ struct qse_sed_t
|
||||
/*****************************************************/
|
||||
} out;
|
||||
|
||||
/** data needed for input streams */
|
||||
struct
|
||||
{
|
||||
qse_sed_iof_t f;
|
||||
qse_sed_io_arg_t arg;
|
||||
qse_sed_iof_t f; /**< an input handler */
|
||||
qse_sed_io_arg_t arg; /**< input handling data */
|
||||
|
||||
qse_char_t xbuf[1];
|
||||
int xbuf_len;
|
||||
qse_char_t xbuf[1]; /**< a read-ahead buffer */
|
||||
int xbuf_len; /**< data length in the buffer */
|
||||
|
||||
qse_char_t buf[2048];
|
||||
qse_size_t len;
|
||||
qse_size_t pos;
|
||||
int eof;
|
||||
qse_char_t buf[2048]; /**< input buffer */
|
||||
qse_size_t len; /**< data length in the buffer */
|
||||
qse_size_t pos; /**< current position in the buffer */
|
||||
int eof; /**< EOF indicator */
|
||||
|
||||
qse_str_t line;
|
||||
qse_size_t num;
|
||||
qse_str_t line; /**< pattern space */
|
||||
qse_size_t num; /**< current line number */
|
||||
} in;
|
||||
|
||||
/** text buffers */
|
||||
struct
|
||||
{
|
||||
qse_lda_t appended;
|
||||
@ -203,100 +240,94 @@ struct qse_sed_t
|
||||
qse_str_t subst;
|
||||
} txt;
|
||||
|
||||
/** indicates if a successful substitution has been made
|
||||
* since the last read on the input stream.
|
||||
*/
|
||||
int subst_done;
|
||||
} e;
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
QSE_DEFINE_COMMON_FUNCTIONS (sed)
|
||||
|
||||
/****f* Text Processor/qse_sed_open
|
||||
* NAME
|
||||
* qse_sed_open - create a stream editor
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_sed_open() function creates a stream editor.
|
||||
* @return A pointer to a stream editor on success, QSE_NULL on a failure
|
||||
*/
|
||||
qse_sed_t* qse_sed_open (
|
||||
qse_mmgr_t* mmgr,
|
||||
qse_size_t xtn
|
||||
qse_mmgr_t* mmgr, /**< a memory manager */
|
||||
qse_size_t xtn /**< the size of extension in bytes */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Text Processor/qse_sed_close
|
||||
* NAME
|
||||
* qse_sed_close - destroy a stream editor
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_sed_close() function destroyes a stream editor.
|
||||
*/
|
||||
void qse_sed_close (
|
||||
qse_sed_t* sed
|
||||
qse_sed_t* sed /**< a stream editor */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Text Processor/qse_sed_init
|
||||
* NAME
|
||||
* qse_sed_init - initialize a stream editor
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_sed_init() function initializes a stream editor.
|
||||
*/
|
||||
qse_sed_t* qse_sed_init (
|
||||
qse_sed_t* sed,
|
||||
qse_mmgr_t* mmgr
|
||||
qse_sed_t* sed, /**< a stream editor */
|
||||
qse_mmgr_t* mmgr /**< a memory manager */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Text Processor/qse_sed_fini
|
||||
* NAME
|
||||
* qse_sed_fini - finalize a stream editor
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_sed_init() function finalizes a stream editor.
|
||||
*/
|
||||
void qse_sed_fini (
|
||||
qse_sed_t* sed
|
||||
qse_sed_t* sed /**< a stream editor */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Text Processor/qse_sed_getoption
|
||||
* NAME
|
||||
* qse_sed_getoption - get option
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_sed_getoption() function retrieves the current options set in
|
||||
* a stream editor.
|
||||
* @return 0 or a number XOR'ed of qse_sed_option_t values
|
||||
*/
|
||||
int qse_sed_getoption (
|
||||
qse_sed_t* sed
|
||||
qse_sed_t* sed /**< a stream editor */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Text Processor/qse_sed_setoption
|
||||
* NAME
|
||||
* qse_sed_setoption - set option
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_sed_setoption() function sets the option code.
|
||||
*/
|
||||
void qse_sed_setoption (
|
||||
qse_sed_t* sed,
|
||||
int option
|
||||
qse_sed_t* sed, /**< a stream editor */
|
||||
int opt /**< 0 or a number XOR'ed of qse_sed_option_t values */
|
||||
);
|
||||
/*****/
|
||||
|
||||
/****f* Text Processor/qse_sed_geterrmsg
|
||||
* NAME
|
||||
* qse_sed_geterrmsg - get an error message
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_sed_geterrmsg() function retrieves an error message
|
||||
* @return a pointer to a string describing an error occurred
|
||||
*/
|
||||
const qse_char_t* qse_sed_geterrmsg (
|
||||
qse_sed_t* sed
|
||||
);
|
||||
/******/
|
||||
|
||||
int qse_sed_compile (
|
||||
qse_sed_t* sed,
|
||||
const qse_char_t* sptr,
|
||||
qse_size_t slen
|
||||
qse_sed_t* sed /**< a stream editor */
|
||||
);
|
||||
|
||||
int qse_sed_execute (
|
||||
qse_sed_t* sed,
|
||||
qse_sed_iof_t inf,
|
||||
qse_sed_iof_t outf
|
||||
/**
|
||||
* The qse_sed_comp() function compiles stream editor commands into an
|
||||
* internal form.
|
||||
* @return 0 on success, -1 on error
|
||||
*/
|
||||
int qse_sed_comp (
|
||||
qse_sed_t* sed, /**< a stream editor */
|
||||
const qse_char_t* ptr, /**< a pointer to a string containing commands */
|
||||
qse_size_t len /**< the number of characters in the string */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_sed_exec() function executes the compiled commands.
|
||||
* @return 0 on success, -1 on error
|
||||
*/
|
||||
int qse_sed_exec (
|
||||
qse_sed_t* sed, /**< a stream editor */
|
||||
qse_sed_iof_t in, /**< stream reader */
|
||||
qse_sed_iof_t out /**< stream writer */
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -1268,7 +1268,7 @@ static int compile_source (
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qse_sed_compile (qse_sed_t* sed, const qse_char_t* sptr, qse_size_t slen)
|
||||
int qse_sed_comp (qse_sed_t* sed, const qse_char_t* sptr, qse_size_t slen)
|
||||
{
|
||||
return compile_source (sed, sptr, slen);
|
||||
}
|
||||
@ -1392,11 +1392,13 @@ static int read_line (qse_sed_t* sed, int append)
|
||||
if (!append) qse_str_clear (&sed->e.in.line);
|
||||
if (sed->e.in.eof)
|
||||
{
|
||||
#if 0
|
||||
/* no more input detected in the previous read.
|
||||
* set eof back to 0 here so that read_char() is called
|
||||
* if read_line() is called again. that way, the result
|
||||
* of subsequent calls counts on read_char(). */
|
||||
sed->e.in.eof = 0;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1406,8 +1408,9 @@ static int read_line (qse_sed_t* sed, int append)
|
||||
if (n <= -1) return -1;
|
||||
if (n == 0)
|
||||
{
|
||||
if (len == 0) return 0;
|
||||
sed->e.in.eof = 1;
|
||||
if (len == 0) return 0;
|
||||
/*sed->e.in.eof = 1;*/
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2052,18 +2055,15 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
||||
sed->errnum = QSE_SED_ENOMEM;
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
/* move past the last command so as to start
|
||||
* the next cycle */
|
||||
jumpto = sed->cmd.cur;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* TODO: prearrange for CHANGE to be executed on the lastline wihtout
|
||||
matchng the second address */
|
||||
qse_str_clear (&sed->e.in.line);
|
||||
}
|
||||
|
||||
/* move past the last command so as to start
|
||||
* the next cycle */
|
||||
jumpto = sed->cmd.cur;
|
||||
break;
|
||||
|
||||
case QSE_SED_CMD_DELETE_FIRSTLN:
|
||||
@ -2077,12 +2077,22 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
||||
QSE_T('\n'));
|
||||
if (nl != QSE_NULL)
|
||||
{
|
||||
/* if a new line is found */
|
||||
/* if a new line is found. delete up to it */
|
||||
qse_str_del (&sed->e.in.line, 0,
|
||||
nl - QSE_STR_PTR(&sed->e.in.line) + 1);
|
||||
|
||||
/* arrange to start the the next cycle */
|
||||
jumpto = sed->cmd.cur;
|
||||
if (QSE_STR_LEN(&sed->e.in.line) > 0)
|
||||
{
|
||||
/* if the pattern space is not empty,
|
||||
* arrange to execute from the first
|
||||
* command */
|
||||
jumpto = sed->cmd.cur + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* arrange to start the the next cycle */
|
||||
jumpto = sed->cmd.cur;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2191,8 +2201,9 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
||||
if (n <= -1) return QSE_NULL;
|
||||
if (n == 0)
|
||||
{
|
||||
/* eof is reached. quit */
|
||||
jumpto = sed->cmd.cur + 1;
|
||||
/* EOF is reached. */
|
||||
/*jumpto = sed->cmd.cur + 1;*/
|
||||
jumpto = sed->cmd.cur;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2202,8 +2213,9 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
||||
if (n <= -1) return QSE_NULL;
|
||||
if (n == 0)
|
||||
{
|
||||
/* eof is reached. quit */
|
||||
jumpto = sed->cmd.cur + 1;
|
||||
/* EOF is reached. */
|
||||
/*jumpto = sed->cmd.cur + 1;*/
|
||||
jumpto = sed->cmd.cur;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2333,7 +2345,7 @@ static void close_outfile (qse_map_t* map, void* dptr, qse_size_t dlen)
|
||||
}
|
||||
}
|
||||
|
||||
int qse_sed_execute (qse_sed_t* sed, qse_sed_iof_t inf, qse_sed_iof_t outf)
|
||||
int qse_sed_exec (qse_sed_t* sed, qse_sed_iof_t inf, qse_sed_iof_t outf)
|
||||
{
|
||||
qse_sed_cmd_t* c, * j;
|
||||
qse_ssize_t n;
|
||||
@ -2455,6 +2467,7 @@ int qse_sed_execute (qse_sed_t* sed, qse_sed_iof_t inf, qse_sed_iof_t outf)
|
||||
qse_lda_clear (&sed->e.txt.appended);
|
||||
qse_str_clear (&sed->e.txt.read);
|
||||
|
||||
again:
|
||||
c = sed->cmd.buf;
|
||||
while (c < sed->cmd.cur)
|
||||
{
|
||||
@ -2470,25 +2483,24 @@ int qse_sed_execute (qse_sed_t* sed, qse_sed_iof_t inf, qse_sed_iof_t outf)
|
||||
|
||||
j = exec_cmd (sed, c);
|
||||
if (j == QSE_NULL) { ret = -1; goto done; }
|
||||
if (j > sed->cmd.cur)
|
||||
{
|
||||
/* finish the current cycle */
|
||||
QSE_ASSERT (j == sed->cmd.cur + 1);
|
||||
goto done;
|
||||
}
|
||||
if (j == sed->cmd.cur + 1) goto done;
|
||||
if (j == sed->cmd.cur + 2) goto again;
|
||||
|
||||
QSE_ASSERT (j <= sed->cmd.cur);
|
||||
/* go to the next command */
|
||||
c = j;
|
||||
}
|
||||
|
||||
if (!(sed->option & QSE_SED_QUIET))
|
||||
{
|
||||
/* write the pattern space */
|
||||
n = write_str (sed,
|
||||
QSE_STR_PTR(&sed->e.in.line),
|
||||
QSE_STR_LEN(&sed->e.in.line));
|
||||
if (n <= -1) { ret = -1; goto done; }
|
||||
}
|
||||
|
||||
/* write text read in by the r command */
|
||||
n = write_str (
|
||||
sed,
|
||||
QSE_STR_PTR(&sed->e.txt.read),
|
||||
@ -2496,6 +2508,7 @@ int qse_sed_execute (qse_sed_t* sed, qse_sed_iof_t inf, qse_sed_iof_t outf)
|
||||
);
|
||||
if (n <= -1) { ret = -1; goto done; }
|
||||
|
||||
/* write appeneded text by the a command */
|
||||
for (i = 0; i < QSE_LDA_SIZE(&sed->e.txt.appended); i++)
|
||||
{
|
||||
qse_xstr_t* t = QSE_LDA_DPTR(&sed->e.txt.appended, i);
|
||||
|
@ -16,10 +16,6 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/****S* SED/Simple Example
|
||||
* SOURCE
|
||||
*/
|
||||
|
||||
#include <qse/utl/sed.h>
|
||||
#include <qse/utl/stdio.h>
|
||||
#include <qse/utl/main.h>
|
||||
@ -119,7 +115,7 @@ int sed_main (int argc, qse_char_t* argv[])
|
||||
|
||||
if (argc == 3) qse_sed_setoption (sed, qse_strtoi(argv[2]));
|
||||
|
||||
if (qse_sed_compile (sed, argv[1], qse_strlen(argv[1])) == -1)
|
||||
if (qse_sed_comp (sed, argv[1], qse_strlen(argv[1])) == -1)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR,
|
||||
QSE_T("cannot compile - %s\n"),
|
||||
@ -128,7 +124,7 @@ int sed_main (int argc, qse_char_t* argv[])
|
||||
goto oops;
|
||||
}
|
||||
|
||||
if (qse_sed_execute (sed, in, out) == -1)
|
||||
if (qse_sed_exec (sed, in, out) == -1)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR,
|
||||
QSE_T("cannot execute - %s\n"),
|
||||
@ -148,5 +144,3 @@ int qse_main (int argc, char* argv[])
|
||||
{
|
||||
return qse_runmain (argc, argv, sed_main);
|
||||
}
|
||||
|
||||
/******/
|
||||
|
Loading…
Reference in New Issue
Block a user