enhanced lda with binary heap functions
added more wide character handling functions
This commit is contained in:
parent
aaa1097128
commit
2a045b7ff0
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: chr.h 287 2009-09-15 10:01:02Z hyunghwan.chung $
|
||||
* $Id: chr.h 323 2010-04-05 12:50:01Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -110,42 +110,42 @@ qse_cint_t qse_ccls_to (
|
||||
qse_ccls_id_t type
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_mblen() function scans a multibyte sequence to get the number of
|
||||
* bytes needed to form a wide character. It does not scan more than @a mblen
|
||||
* bytes.
|
||||
* @return number of bytes processed on success,
|
||||
* 0 for invalid sequences,
|
||||
* mblen + 1 for incomplete sequences
|
||||
*/
|
||||
qse_size_t qse_mblen (
|
||||
const qse_mchar_t* mb,
|
||||
qse_size_t mblen
|
||||
);
|
||||
|
||||
/****f* Common/qse_mbtowc
|
||||
* NAME
|
||||
* qse_mbtowc - convert a multibyte sequence to a wide character.
|
||||
* RETURN
|
||||
* The qse_mbtowc() function returns 0 if an invalid multibyte sequence is
|
||||
* detected, mblen + 1 if the sequence is incomplete. It returns the number
|
||||
* of bytes processed to form a wide character.
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_mbtowc() function converts a multibyte sequence to a wide character.
|
||||
* It returns 0 if an invalid multibyte sequence is detected, mblen + 1 if the
|
||||
* sequence is incomplete. It returns the number of bytes processed to form a
|
||||
* wide character.
|
||||
*/
|
||||
qse_size_t qse_mbtowc (
|
||||
const qse_mchar_t* mb,
|
||||
qse_size_t mblen,
|
||||
qse_wchar_t* wc
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_wctomb
|
||||
* NAME
|
||||
* qse_wctomb - convert a wide character to a multibyte sequence
|
||||
* RETURN
|
||||
* The qse_wctomb() functions returns 0 if the wide character is illegal,
|
||||
* mblen + 1 if mblen is not large enough to hold the multibyte sequence.
|
||||
* On successful conversion, it returns the number of bytes in the sequence.
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_wctomb() function converts a wide character to a multibyte sequence.
|
||||
* It returns 0 if the wide character is illegal, mblen + 1 if mblen is not
|
||||
* large enough to hold the multibyte sequence. On successful conversion, it
|
||||
* returns the number of bytes in the sequence.
|
||||
*/
|
||||
qse_size_t qse_wctomb (
|
||||
qse_wchar_t wc,
|
||||
qse_mchar_t* mb,
|
||||
qse_size_t mblen
|
||||
);
|
||||
/******/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: lda.h 311 2009-12-09 11:35:54Z hyunghwan.chung $
|
||||
* $Id: lda.h 323 2010-04-05 12:50:01Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -24,13 +24,9 @@
|
||||
#include <qse/types.h>
|
||||
#include <qse/macros.h>
|
||||
|
||||
/****o* Common/linear dynamic array
|
||||
* DESCRIPTION
|
||||
* <Common.h> provides a linear dynamic array. It grows as more items
|
||||
/** @file
|
||||
* This file provides a linear dynamic array. It grows dynamically as items
|
||||
* are added.
|
||||
*
|
||||
* #include <Common.h>
|
||||
******
|
||||
*/
|
||||
|
||||
enum qse_lda_walk_t
|
||||
@ -62,14 +58,8 @@ typedef enum qse_lda_walk_t qse_lda_walk_t;
|
||||
#define QSE_LDA_KEEPER(lda) ((lda)->keeper)
|
||||
#define QSE_LDA_SIZER(lda) ((lda)->sizer)
|
||||
|
||||
|
||||
|
||||
/****t* Common/qse_lda_copier_t
|
||||
* NAME
|
||||
* qse_lda_copier_t - define a node contruction callback
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The qse_lda_copier_t defines a callback function for node construction.
|
||||
/**
|
||||
* The qse_lda_copier_t type defines a callback function for node construction.
|
||||
* A node is contructed when a user adds data to a list. The user can
|
||||
* define how the data to add can be maintained in the list. A singly
|
||||
* linked list not specified with any copiers stores the data pointer and
|
||||
@ -80,36 +70,23 @@ typedef enum qse_lda_walk_t qse_lda_walk_t;
|
||||
* A copier should return the pointer to the copied data. If it fails to copy
|
||||
* data, it may return QSE_NULL. You need to set a proper freeer to free up
|
||||
* memory allocated for copy.
|
||||
*
|
||||
* SEE ALSO
|
||||
* qse_lda_setcopier, qse_lda_getcopier, QSE_LDA_COPIER
|
||||
*
|
||||
* SYNOPSIS
|
||||
*/
|
||||
typedef void* (*qse_lda_copier_t) (
|
||||
qse_lda_t* lda /* lda */,
|
||||
void* dptr /* the pointer to data to copy */,
|
||||
qse_size_t dlen /* the length of data to copy */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****t* Common/qse_lda_freeer_t
|
||||
* NAME
|
||||
* qse_lda_freeer_t - define a node destruction callback
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_lda_freeer_t type defines a node destruction callback.
|
||||
*/
|
||||
typedef void (*qse_lda_freeer_t) (
|
||||
qse_lda_t* lda /* lda */,
|
||||
void* dptr /* the pointer to data to free */,
|
||||
qse_size_t dlen /* the length of data to free */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****t* Common/qse_lda_comper_t
|
||||
* NAME
|
||||
* qse_lda_comper_t - define a data comparator
|
||||
*
|
||||
* DESCRIPTION
|
||||
/**
|
||||
* The qse_lda_comper_t type defines a key comparator that is called when
|
||||
* the list needs to compare data. A linear dynamic array is created with a
|
||||
* default comparator that performs bitwise comparison.
|
||||
@ -117,7 +94,6 @@ typedef void (*qse_lda_freeer_t) (
|
||||
* The comparator should return 0 if the data are the same and a non-zero
|
||||
* integer otherwise.
|
||||
*
|
||||
* SYNOPSIS
|
||||
*/
|
||||
typedef int (*qse_lda_comper_t) (
|
||||
qse_lda_t* lda /* a linear dynamic array */,
|
||||
@ -126,42 +102,27 @@ typedef int (*qse_lda_comper_t) (
|
||||
const void* dptr2 /* a data pointer */,
|
||||
qse_size_t dlen2 /* a data length */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****t* Common/qse_lda_keeper_t
|
||||
* NAME
|
||||
* qse_lda_keeper_t - define a value keeper
|
||||
*
|
||||
* DESCRIPTION
|
||||
/**
|
||||
* The qse_lda_keeper_t type defines a value keeper that is called when
|
||||
* a value is retained in the context that it should be destroyed because
|
||||
* it is identical to a new value. Two values are identical if their beginning
|
||||
* pointers and their lengths are equal.
|
||||
*
|
||||
* SYNOPSIS
|
||||
*/
|
||||
typedef void (*qse_lda_keeper_t) (
|
||||
qse_lda_t* lda /* lda */,
|
||||
void* vptr /* the pointer to a value */,
|
||||
qse_size_t vlen /* the length of a value */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****t* Common/qse_lda_sizer_t
|
||||
* NAME
|
||||
* qse_lda_sizer_t - define an array size calculator
|
||||
*
|
||||
* DESCRIPTION
|
||||
/**
|
||||
* The qse_lda_sizer_t type defines an array size claculator that is called
|
||||
* when the array needs to be resized.
|
||||
*
|
||||
* SYNOPSIS
|
||||
*/
|
||||
typedef qse_size_t (*qse_lda_sizer_t) (
|
||||
qse_lda_t* lda, /* a linear dynamic array */
|
||||
qse_size_t hint /* a sizing hint */
|
||||
);
|
||||
/******/
|
||||
|
||||
typedef qse_lda_walk_t (*qse_lda_walker_t) (
|
||||
qse_lda_t* lda /* a linear dynamic array */,
|
||||
@ -169,11 +130,8 @@ typedef qse_lda_walk_t (*qse_lda_walker_t) (
|
||||
void* arg /* user-defined data */
|
||||
);
|
||||
|
||||
/****s* Common/qse_lda_t
|
||||
* NAME
|
||||
* qse_lda_t - define a linear dynamic array
|
||||
*
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_lda_t type defines a linear dynamic array.
|
||||
*/
|
||||
struct qse_lda_t
|
||||
{
|
||||
@ -185,24 +143,19 @@ struct qse_lda_t
|
||||
qse_lda_keeper_t keeper; /* data keeper */
|
||||
qse_lda_sizer_t sizer; /* size calculator */
|
||||
qse_byte_t scale; /* scale factor */
|
||||
qse_size_t size; /* the number of items */
|
||||
qse_size_t size; /* number of items */
|
||||
qse_size_t capa; /* capacity */
|
||||
qse_lda_node_t** node;
|
||||
};
|
||||
/******/
|
||||
|
||||
/****s*
|
||||
* NAME
|
||||
* qse_lda_node_t - define a linear dynamic array node
|
||||
*
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_lda_node_t type defines a linear dynamic array node
|
||||
*/
|
||||
struct qse_lda_node_t
|
||||
{
|
||||
void* dptr;
|
||||
qse_size_t dlen;
|
||||
};
|
||||
/******/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -210,53 +163,37 @@ extern "C" {
|
||||
|
||||
QSE_DEFINE_COMMON_FUNCTIONS (lda)
|
||||
|
||||
/****f* Common/qse_lda_open
|
||||
* NAME
|
||||
* qse_lda_open - create a linear dynamic array
|
||||
*
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_lda_open() function creates a linear dynamic array.
|
||||
*/
|
||||
qse_lda_t* qse_lda_open (
|
||||
qse_mmgr_t* lda,
|
||||
qse_size_t ext,
|
||||
qse_size_t capa
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_lda_close
|
||||
* NAME
|
||||
* qse_lda_close - destroy a linear dynamic array
|
||||
*
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_lda_close() function destroys a linear dynamic array.
|
||||
*/
|
||||
void qse_lda_close (
|
||||
qse_lda_t* lda
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_lda_init
|
||||
* NAME
|
||||
* qse_lda_init - initialize a linear dynamic array
|
||||
*
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_lda_init() function initializes a linear dynamic array.
|
||||
*/
|
||||
qse_lda_t* qse_lda_init (
|
||||
qse_lda_t* lda,
|
||||
qse_mmgr_t* mmgr,
|
||||
qse_size_t capa
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_lda_fini
|
||||
* NAME
|
||||
* qse_lda_fini - deinitialize a linear dynamic array
|
||||
*
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_lda_fini() function finalizes a linear dynamic array.
|
||||
*/
|
||||
void qse_lda_fini (
|
||||
qse_lda_t* lda
|
||||
);
|
||||
/******/
|
||||
|
||||
int qse_lda_getscale (
|
||||
qse_lda_t* lda /* lda */
|
||||
@ -383,43 +320,25 @@ qse_size_t qse_lda_update (
|
||||
qse_size_t dlen
|
||||
);
|
||||
|
||||
/****f* Common/qse_lda_delete
|
||||
* NAME
|
||||
* qse_lda_delete - delete data
|
||||
*
|
||||
* DESCRIPTION
|
||||
/**
|
||||
* The qse_lda_delete() function deletes the as many data as the count
|
||||
* from the index.
|
||||
*
|
||||
* RETURN
|
||||
* The qse_lda_delete() function returns the number of data deleted.
|
||||
*
|
||||
* SYNOPSIS
|
||||
* from the index. It returns the number of data deleted.
|
||||
*/
|
||||
qse_size_t qse_lda_delete (
|
||||
qse_lda_t* lda,
|
||||
qse_size_t index,
|
||||
qse_size_t count
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_lda_uplete
|
||||
* NAME
|
||||
* qse_lda_uplete - delete data node
|
||||
*
|
||||
* DESCRIPTION
|
||||
/**
|
||||
* The qse_lda_uplete() function deletes data node without compaction.
|
||||
*
|
||||
* RETURN
|
||||
* The qse_lda_uplete() function returns the number of data affected.
|
||||
*
|
||||
* It returns the number of data affected.
|
||||
*/
|
||||
qse_size_t qse_lda_uplete (
|
||||
qse_lda_t* lda,
|
||||
qse_size_t index,
|
||||
qse_size_t count
|
||||
);
|
||||
/******/
|
||||
|
||||
void qse_lda_clear (
|
||||
qse_lda_t* lda
|
||||
@ -437,6 +356,52 @@ void qse_lda_rwalk (
|
||||
void* arg
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_lda_pushstack() function appends data to the array. It is a utility
|
||||
* function to allow stack-like operations over an array. To do so, you should
|
||||
* not play with other non-stack related functions.
|
||||
*/
|
||||
qse_size_t qse_lda_pushstack (
|
||||
qse_lda_t* lda,
|
||||
void* dptr,
|
||||
qse_size_t dlen
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_lda_popstack() function deletes the last array data. It is a utility
|
||||
* function to allow stack-like operations over an array. To do so, you should
|
||||
* not play with other non-stack related functions.
|
||||
* @note You must not call this function if @a lda is empty.
|
||||
*/
|
||||
void qse_lda_popstack (
|
||||
qse_lda_t* lda
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_lda_pushheap() function inserts data to an array while keeping the
|
||||
* largest data at position 0. It is a utiltiy funtion to implement a binary
|
||||
* max-heap over an array. Inverse the comparator to implement a min-heap.
|
||||
* @return number of array elements
|
||||
* @note You must not mess up the array with other non-heap related functions
|
||||
* to keep the heap property.
|
||||
*/
|
||||
qse_size_t qse_lda_pushheap (
|
||||
qse_lda_t* lda,
|
||||
void* dptr,
|
||||
qse_size_t dlen
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_lda_popheap() function deletes data at position 0 while keeping
|
||||
* the largest data at positon 0. It is a utiltiy funtion to implement a binary
|
||||
* max-heap over an array.
|
||||
* @note You must not mess up the array with other non-heap related functions
|
||||
* to keep the heap property.
|
||||
*/
|
||||
void qse_lda_popheap (
|
||||
qse_lda_t* lda
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: str.h 320 2009-12-21 12:29:52Z hyunghwan.chung $
|
||||
* $Id: str.h 323 2010-04-05 12:50:01Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -120,31 +120,29 @@ extern "C" {
|
||||
* basic string functions
|
||||
*/
|
||||
|
||||
/****f* Common/qse_strlen
|
||||
* NAME
|
||||
* qse_strlen - get the number of characters
|
||||
* DESCRIPTION
|
||||
/**
|
||||
* The qse_strlen() function returns the number of characters in a
|
||||
* null-terminated string. The length returned excludes a terminating null.
|
||||
* SYNOPSIS
|
||||
*/
|
||||
qse_size_t qse_strlen (
|
||||
const qse_char_t* str
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_strbytes
|
||||
* NAME
|
||||
* qse_strbytes - get the length of a string in bytes
|
||||
* DESCRIPTOIN
|
||||
/**
|
||||
* The qse_strbytes() function returns the number of bytes a null-terminated
|
||||
* string is holding excluding a terminating null.
|
||||
* SYNOPSIS
|
||||
*/
|
||||
qse_size_t qse_strbytes (
|
||||
const qse_char_t* str
|
||||
);
|
||||
/******/
|
||||
|
||||
qse_size_t qse_mbslen (
|
||||
const qse_mchar_t* mbs
|
||||
);
|
||||
|
||||
qse_size_t qse_wcslen (
|
||||
const qse_wchar_t* wcs
|
||||
);
|
||||
|
||||
qse_size_t qse_strcpy (
|
||||
qse_char_t* buf,
|
||||
@ -170,36 +168,32 @@ qse_size_t qse_strxncpy (
|
||||
qse_size_t len
|
||||
);
|
||||
|
||||
/****f* Common/qse_strfcpy
|
||||
* NAME
|
||||
* qse_strfcpy - copy a string
|
||||
* DESCRIPTION
|
||||
* "format ${1} ${3} ${2} \\${1} string"
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_strfcpy() function formats a string by position.
|
||||
* The position specifier is a number enclosed in ${ and }.
|
||||
* When ${ is preceeded by a backslash, it is treated literally.
|
||||
* A sameple format string containing the position specifiers are shown below:
|
||||
* @code
|
||||
* "${1} ${3} ${2} \\${1} string"
|
||||
* @endcode
|
||||
*/
|
||||
qse_size_t qse_strfcpy (
|
||||
qse_char_t* buf,
|
||||
const qse_char_t* fmt,
|
||||
const qse_char_t* str[]
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_strfncpy
|
||||
* NAME
|
||||
* qse_strfncpy - copy a string
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_strfncpy() function formats a string by position.
|
||||
*/
|
||||
qse_size_t qse_strfncpy (
|
||||
qse_char_t* buf,
|
||||
const qse_char_t* fmt,
|
||||
const qse_cstr_t str[]
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_strxfcpy
|
||||
* NAME
|
||||
* qse_strxfcpy - copy a string
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_strxfcpy() function formats a string by position.
|
||||
*/
|
||||
qse_size_t qse_strxfcpy (
|
||||
qse_char_t* buf,
|
||||
@ -207,12 +201,9 @@ qse_size_t qse_strxfcpy (
|
||||
const qse_char_t* fmt,
|
||||
const qse_char_t* str[]
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_strxfncpy
|
||||
* NAME
|
||||
* qse_strxfncpy - copy a string
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_strxfncpy() function formats a string by position.
|
||||
*/
|
||||
qse_size_t qse_strxfncpy (
|
||||
qse_char_t* buf,
|
||||
@ -220,7 +211,6 @@ qse_size_t qse_strxfncpy (
|
||||
const qse_char_t* fmt,
|
||||
const qse_cstr_t str[]
|
||||
);
|
||||
/******/
|
||||
|
||||
qse_size_t qse_strxcat (
|
||||
qse_char_t* buf,
|
||||
@ -235,11 +225,23 @@ qse_size_t qse_strxncat (
|
||||
qse_size_t len
|
||||
);
|
||||
|
||||
int qse_strcmp (const qse_char_t* s1, const qse_char_t* s2);
|
||||
int qse_strxcmp (const qse_char_t* s1, qse_size_t len1, const qse_char_t* s2);
|
||||
int qse_strcmp (
|
||||
const qse_char_t* s1,
|
||||
const qse_char_t* s2
|
||||
);
|
||||
|
||||
int qse_strxcmp (
|
||||
const qse_char_t* s1,
|
||||
qse_size_t len1,
|
||||
const qse_char_t* s2
|
||||
);
|
||||
|
||||
int qse_strxncmp (
|
||||
const qse_char_t* s1, qse_size_t len1,
|
||||
const qse_char_t* s2, qse_size_t len2);
|
||||
const qse_char_t* s1,
|
||||
qse_size_t len1,
|
||||
const qse_char_t* s2,
|
||||
qse_size_t len2
|
||||
);
|
||||
|
||||
int qse_strcasecmp (const qse_char_t* s1, const qse_char_t* s2);
|
||||
|
||||
@ -361,20 +363,56 @@ qse_char_t* qse_strxnrstr (
|
||||
qse_size_t subsz
|
||||
);
|
||||
|
||||
qse_char_t* qse_strchr (const qse_char_t* str, qse_cint_t c);
|
||||
qse_char_t* qse_strxchr (const qse_char_t* str, qse_size_t len, qse_cint_t c);
|
||||
qse_char_t* qse_strrchr (const qse_char_t* str, qse_cint_t c);
|
||||
qse_char_t* qse_strxrchr (const qse_char_t* str, qse_size_t len, qse_cint_t c);
|
||||
qse_char_t* qse_strchr (
|
||||
const qse_char_t* str,
|
||||
qse_cint_t c
|
||||
);
|
||||
|
||||
qse_char_t* qse_strxchr (
|
||||
const qse_char_t* str,
|
||||
qse_size_t len,
|
||||
qse_cint_t c
|
||||
);
|
||||
|
||||
qse_char_t* qse_strrchr (
|
||||
const qse_char_t* str,
|
||||
qse_cint_t c
|
||||
);
|
||||
|
||||
qse_char_t* qse_strxrchr (
|
||||
const qse_char_t* str,
|
||||
qse_size_t len,
|
||||
qse_cint_t c
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_strbeg() function checks if the a string begins with a substring.
|
||||
* @return the pointer to a beginning of a matching beginning,
|
||||
* QSE_NULL if no match is found.
|
||||
*/
|
||||
qse_char_t* qse_strbeg (
|
||||
const qse_char_t* str,
|
||||
const qse_char_t* sub
|
||||
);
|
||||
|
||||
/* Checks if a string begins with a substring */
|
||||
qse_char_t* qse_strbeg (const qse_char_t* str, const qse_char_t* sub);
|
||||
qse_char_t* qse_strxbeg (
|
||||
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)
|
||||
;
|
||||
|
||||
qse_char_t* qse_strnbeg (
|
||||
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
|
||||
);
|
||||
|
||||
qse_char_t* qse_strxnbeg (
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_strend() function checks if the a string ends with a substring.
|
||||
@ -443,12 +481,8 @@ 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
|
||||
/**
|
||||
* The qse_strspl() function splits a string into fields.
|
||||
*/
|
||||
int qse_strspl (
|
||||
qse_char_t* str,
|
||||
@ -459,24 +493,24 @@ int qse_strspl (
|
||||
);
|
||||
/******/
|
||||
|
||||
/****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
|
||||
/**
|
||||
* The qse_strspltrn() function splits a string translating special
|
||||
* escape sequences.
|
||||
* The argument @a 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.
|
||||
* @code
|
||||
* qse_strspltrn (str, QSE_T(':'), QSE_T('['), QSE_T(']'), QSE_T('\\'), QSE_T("n\nr\r"), &nfields);
|
||||
* @endcode
|
||||
* 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,
|
||||
@ -486,7 +520,6 @@ int qse_strspltrn (
|
||||
qse_char_t escape,
|
||||
const qse_char_t* trset
|
||||
);
|
||||
/******/
|
||||
|
||||
/**
|
||||
* The qse_strtrmx() function strips leading spaces and/or trailing
|
||||
@ -556,9 +589,50 @@ qse_size_t qse_strxpac (
|
||||
qse_size_t len /**< length */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_mbstowcslen() function scans a null-terminated multibyte string
|
||||
* to calculate the number of wide characters it can be converted to.
|
||||
* The number of wide characters is returned via @a wcslen if it is not
|
||||
* #QSE_NULL. The function may be aborted if it has encountered invalid
|
||||
* or incomplete multibyte sequences. The return value, in this case,
|
||||
* is less than qse_strlen(mcs).
|
||||
* @return number of bytes scanned
|
||||
*/
|
||||
qse_size_t qse_mbstowcslen (
|
||||
const qse_mchar_t* mcs,
|
||||
qse_size_t* wcslen
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_mbsntowcsnlen() function scans a multibyte string of @a mcslen bytes
|
||||
* to get the number of wide characters it can be converted to.
|
||||
* The number of wide characters is returned via @a wcslen if it is not
|
||||
* #QSE_NULL. The function may be aborted if it has encountered invalid
|
||||
* or incomplete multibyte sequences. The return value, in this case,
|
||||
* is less than @a mcslen.
|
||||
* @return number of bytes scanned
|
||||
*/
|
||||
qse_size_t qse_mbsntowcsnlen (
|
||||
const qse_mchar_t* mcs,
|
||||
qse_size_t mcslen,
|
||||
qse_size_t* wcslen
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_mbstowcs() function converts a multibyte string to a wide
|
||||
* character string.
|
||||
*
|
||||
* @code
|
||||
* const qse_mchar_t* mbs = "a multibyte string";
|
||||
* qse_wchar_t buf[100];
|
||||
* qse_size_t bufsz = QSE_COUNTOF(buf), n;
|
||||
* n = qse_mbstowcs (mbs, buf, bufsz);
|
||||
* if (bufsz >= QSE_COUNTOF(buf)) { buffer too small }
|
||||
* if (mbs[n] != '\0') { incomplete processing }
|
||||
* //if (n != strlen(mbs)) { incomplete processing }
|
||||
* @endcode
|
||||
*
|
||||
* @return number of multibyte characters processed.
|
||||
*/
|
||||
qse_size_t qse_mbstowcs (
|
||||
const qse_mchar_t* mbs,
|
||||
@ -569,7 +643,7 @@ qse_size_t qse_mbstowcs (
|
||||
/**
|
||||
* The qse_mbsntowcsn() function converts a multibyte string to a
|
||||
* wide character string.
|
||||
* @return number of bytes handled.
|
||||
* @return number of multibyte characters processed.
|
||||
*/
|
||||
qse_size_t qse_mbsntowcsn (
|
||||
const qse_mchar_t* mbs,
|
||||
@ -578,11 +652,15 @@ qse_size_t qse_mbsntowcsn (
|
||||
qse_size_t* wcslen
|
||||
);
|
||||
|
||||
/****f* Common/qse_wcstombslen
|
||||
/**
|
||||
* The qse_wcstombslen() function scans a null-terminated wide character
|
||||
* string @a wcs 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 @a mbslen.
|
||||
* string @a wcs 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 @a mbslen.
|
||||
* Complete scanning is indicated by the following condition:
|
||||
* @code
|
||||
* qse_wcstombslen(wcs,&xx) == qse_strlen(wcs)
|
||||
* @endcode
|
||||
* @return number of wide characters handled
|
||||
*/
|
||||
qse_size_t qse_wcstombslen (
|
||||
@ -592,9 +670,13 @@ qse_size_t qse_wcstombslen (
|
||||
|
||||
/**
|
||||
* The qse_wcsntombsnlen() function scans a wide character wcs as long as
|
||||
* wcslen characters to get the get the total number of multibyte characters
|
||||
* @a wcslen characters 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 @a mbslen.
|
||||
* Complete scanning is indicated by the following condition:
|
||||
* @code
|
||||
* qse_wcstombslen(wcs,&xx) == wcslen
|
||||
* @endcode
|
||||
* @return number of wide characters handled
|
||||
*/
|
||||
qse_size_t qse_wcsntombsnlen (
|
||||
@ -608,12 +690,11 @@ qse_size_t qse_wcsntombsnlen (
|
||||
* 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.
|
||||
* the length of the multibyte string excluding the terminating-null character.
|
||||
* 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 number of wide characters handled
|
||||
* SYNOPSIS
|
||||
* @return number of wide characters processed
|
||||
*/
|
||||
qse_size_t qse_wcstombs (
|
||||
const qse_wchar_t* wcs,
|
||||
@ -627,14 +708,26 @@ qse_size_t qse_wcstombs (
|
||||
* @return the number of wide characters
|
||||
*/
|
||||
qse_size_t qse_wcsntombsn (
|
||||
const qse_wchar_t* wcs, /**< a wide string */
|
||||
const qse_wchar_t* wcs, /**< wide string */
|
||||
qse_size_t wcslen, /**< wide string length */
|
||||
qse_mchar_t* mbs, /**< a multibyte string buffer */
|
||||
qse_size_t* mbslen /**< the buffer size */
|
||||
qse_mchar_t* mbs, /**< multibyte string buffer */
|
||||
qse_size_t* mbslen /**< buffer size */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_wcstombs_strict() function performs the same as the qse_wcsmbs()
|
||||
* The qse_mbstowcs_strict() function performs the same as the qse_mbstowcs()
|
||||
* 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_mbstowcs_strict (
|
||||
const qse_mchar_t* mbs,
|
||||
qse_wchar_t* wcs,
|
||||
qse_size_t wcslen
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_wcstombs_strict() function performs the same as the qse_wcstombs()
|
||||
* 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.
|
||||
@ -657,75 +750,51 @@ void qse_str_close (
|
||||
qse_str_t* str
|
||||
);
|
||||
|
||||
/****f* Common/qse_str_init
|
||||
* NAME
|
||||
* qse_str_init - initialize a dynamically resizable string
|
||||
* NOTE
|
||||
/**
|
||||
* The qse_str_init() function initializes a dynamically resizable string
|
||||
* If the parameter capa is 0, it doesn't allocate the internal buffer
|
||||
* in advance.
|
||||
* SYNOPSIS
|
||||
*/
|
||||
qse_str_t* qse_str_init (
|
||||
qse_str_t* str,
|
||||
qse_mmgr_t* mmgr,
|
||||
qse_size_t capa
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_str_fini
|
||||
* NAME
|
||||
* qse_str_fini - finialize a dynamically resizable string
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_str_fini() function finalizes a dynamically resizable string.
|
||||
*/
|
||||
void qse_str_fini (
|
||||
qse_str_t* str
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_str_yield
|
||||
* NAME
|
||||
* qse_str_yield - yield the buffer
|
||||
*
|
||||
* DESCRIPTION
|
||||
/**
|
||||
* The qse_str_yield() function assigns the buffer to an variable of the
|
||||
* qse_xstr_t type and recreate a new buffer of the new_capa capacity.
|
||||
* qse_xstr_t type and recreate a new buffer of the @a new_capa capacity.
|
||||
* The function fails if it fails to allocate a new buffer.
|
||||
*
|
||||
* RETURN
|
||||
* The qse_str_yield() function returns 0 on success, and -1 on failure.
|
||||
*
|
||||
* SYNOPSIS
|
||||
* @return 0 on success, and -1 on failure.
|
||||
*/
|
||||
int qse_str_yield (
|
||||
qse_str_t* str /* a dynamic string */,
|
||||
qse_xstr_t* buf /* the pointer to a qse_xstr_t variable */,
|
||||
int new_capa /* new capacity in number of characters */
|
||||
qse_str_t* str, /**< string */
|
||||
qse_xstr_t* buf, /**< buffer pointer */
|
||||
int new_capa /**< new capacity */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_str_getsizer
|
||||
* NAME
|
||||
* qse_str_getsizer - get the sizer
|
||||
* RETURN
|
||||
* a sizer function set or QSE_NULL if no sizer is set.
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_str_getsizer() function gets the sizer.
|
||||
* @return sizer function set or QSE_NULL if no sizer is set.
|
||||
*/
|
||||
qse_str_sizer_t qse_str_getsizer (
|
||||
qse_str_t* str
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_str_setsizer
|
||||
* NAME
|
||||
* qse_str_setsizer - specify a sizer
|
||||
* DESCRIPTION
|
||||
/**
|
||||
* The qse_str_setsizer() function specify a new sizer for a dynamic string.
|
||||
* With no sizer specified, the dynamic string doubles the current buffer
|
||||
* when it needs to increase its size. The sizer function is passed a dynamic
|
||||
* string and the minimum capacity required to hold data after resizing.
|
||||
* The string is truncated if the sizer function returns a smaller number
|
||||
* than the hint passed.
|
||||
* SYNOPSIS
|
||||
*/
|
||||
void qse_str_setsizer (
|
||||
qse_str_t* str,
|
||||
@ -733,87 +802,58 @@ void qse_str_setsizer (
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_str_getcapa
|
||||
* NAME
|
||||
* qse_str_getcapa - get capacity
|
||||
* DESCRIPTION
|
||||
/**
|
||||
* The qse_str_getcapa() function returns the current capacity.
|
||||
* You may use QSE_STR_CAPA(str) macro for performance sake.
|
||||
* RETURNS
|
||||
* current capacity in number of characters.
|
||||
* SYNOPSIS
|
||||
* @return current capacity in number of characters.
|
||||
*/
|
||||
qse_size_t qse_str_getcapa (
|
||||
qse_str_t* str
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_str_setcapa
|
||||
* NAME
|
||||
* qse_str_setcapa - set new capacity
|
||||
* DESCRIPTION
|
||||
/**
|
||||
* The qse_str_setcapa() function sets the new capacity. If the new capacity
|
||||
* is smaller than the old, the overflowing characters are removed from
|
||||
* from the buffer.
|
||||
* RETURNS
|
||||
* (qse_size_t)-1 on failure, new capacity on success
|
||||
* SYNOPSIS
|
||||
* @return (qse_size_t)-1 on failure, new capacity on success
|
||||
*/
|
||||
qse_size_t qse_str_setcapa (
|
||||
qse_str_t* str,
|
||||
qse_size_t capa
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_str_getlen
|
||||
* NAME
|
||||
* qse_str_getlen - get length
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_str_getlen() function return the string length.
|
||||
*/
|
||||
qse_size_t qse_str_getlen (
|
||||
qse_str_t* str
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_str_setlen
|
||||
* NAME
|
||||
* qse_str_setlen - change length
|
||||
* RETURNS
|
||||
* (qse_size_t)-1 on failure, new length on success
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_str_setlen() function changes the string length.
|
||||
* @return (qse_size_t)-1 on failure, new length on success
|
||||
*/
|
||||
qse_size_t qse_str_setlen (
|
||||
qse_str_t* str,
|
||||
qse_size_t len
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_str_clear
|
||||
* NAME
|
||||
* qse_str_clear - clear a string
|
||||
* DESCRIPTION
|
||||
/**
|
||||
* The qse_str_clear() funtion deletes all characters in a string and sets
|
||||
* the length to 0. It doesn't resize the internal buffer.
|
||||
* SYNOPSIS
|
||||
*/
|
||||
void qse_str_clear (
|
||||
qse_str_t* str
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_str_swap
|
||||
* NAME
|
||||
* qse_str_swap - swap buffers of two dynamic string
|
||||
* DESCRIPTION
|
||||
/**
|
||||
* The qse_str_swap() function exchanges the pointers to a buffer between
|
||||
* two strings. It updates the length and the capacity accordingly.
|
||||
* SYNOPSIS
|
||||
*/
|
||||
void qse_str_swap (
|
||||
qse_str_t* str1,
|
||||
qse_str_t* str2
|
||||
);
|
||||
/******/
|
||||
|
||||
qse_size_t qse_str_cpy (
|
||||
qse_str_t* str,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: macros.h 289 2009-09-16 06:35:29Z hyunghwan.chung $
|
||||
* $Id: macros.h 323 2010-04-05 12:50:01Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -27,6 +27,14 @@
|
||||
* <qse/macros.h> contains various useful macro definitions.
|
||||
*/
|
||||
|
||||
#if defined(__STDC_VERSION__) && (__STDC_VERSION__>=199901L)
|
||||
# define QSE_INLINE inline
|
||||
#elif defined(__GNUC__) && defined(__GNUC_GNU_INLINE__)
|
||||
# define QSE_INLINE /*extern*/ inline
|
||||
#else
|
||||
# define QSE_INLINE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The #QSE_NULL macro defines a special pointer value to indicate an error or
|
||||
* that it does not point to anything.
|
||||
@ -128,13 +136,13 @@
|
||||
|
||||
#define QSE_ABS(x) ((x) < 0? -(x): (x))
|
||||
|
||||
#define QSE_ERR_THROW(id) goto __err_ ## id
|
||||
#define QSE_ERR_CATCH(id) while(0) __err_ ## id:
|
||||
#define QSE_THROW_ERR(id) goto __err_ ## id
|
||||
#define QSE_CATCH_ERR(id) while(0) __err_ ## id:
|
||||
|
||||
#define QSE_LOOP_CONTINUE(id) goto __loop_ ## id ## _begin__
|
||||
#define QSE_LOOP_BREAK(id) goto __loop_ ## id ## _end__
|
||||
#define QSE_LOOP_BEGIN(id) __loop_ ## id ## _begin__: {
|
||||
#define QSE_LOOP_END(id) QSE_LOOP_CONTINUE(id) } __loop_ ## id ## _end__:
|
||||
#define QSE_CONTINUE_LOOP(id) goto __loop_ ## id ## _begin__
|
||||
#define QSE_BREAK_LOOP(id) goto __loop_ ## id ## _end__
|
||||
#define QSE_BEGIN_LOOP(id) __loop_ ## id ## _begin__: {
|
||||
#define QSE_END_LOOP(id) QSE_LOOP_CONTINUE(id) } __loop_ ## id ## _end__:
|
||||
|
||||
#define QSE_REPEAT(n,blk) \
|
||||
do { \
|
||||
@ -196,6 +204,16 @@
|
||||
# define QSE_END_PACKED_STRUCT() };
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The QSE_STRUCT_FIELD() macro provides a neutral way to specify
|
||||
* a field ID for initialzing a structure in both C9X and C89
|
||||
*/
|
||||
#if (defined(__STDC_VERSION__) && (__STDC_VERSION__>=199901L)) || defined(__GNUC__)
|
||||
# define QSE_STRUCT_FIELD(id) .id =
|
||||
#else
|
||||
# define QSE_STRUCT_FIELD(id)
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
# define QSE_ASSERT(expr) ((void)0)
|
||||
# define QSE_ASSERTX(expr,desc) ((void)0)
|
||||
@ -229,6 +247,15 @@
|
||||
#define QSE_DEFINE_COMMON_FIELDS(name) \
|
||||
qse_mmgr_t* mmgr;
|
||||
|
||||
|
||||
#define QSE_BEGIN_CLASS(name) \
|
||||
typedef struct name name; \
|
||||
struct name \
|
||||
{ \
|
||||
qse_mmgr_t* mmgr; \
|
||||
|
||||
#define QSE_END_CLASS(name) };
|
||||
|
||||
/**
|
||||
* The QSE_DEFINE_COMMON_FUNCTIONS() macro defines common object functions.
|
||||
* - @code void qse_xxx_setmmgr (qse_xxx_t* xxx, qse_mmgr_t* mmgr); @endcode
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: parse.c 312 2009-12-10 13:03:54Z hyunghwan.chung $
|
||||
* $Id: parse.c 323 2010-04-05 12:50:01Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -226,8 +226,6 @@ static int skip_spaces (qse_awk_t* awk);
|
||||
static int skip_comment (qse_awk_t* awk);
|
||||
static int classify_ident (
|
||||
qse_awk_t* awk, const qse_char_t* name, qse_size_t len);
|
||||
static int is_plain_var (qse_awk_nde_t* nde);
|
||||
static int is_var (qse_awk_nde_t* nde);
|
||||
|
||||
static int deparse (qse_awk_t* awk);
|
||||
static qse_map_walk_t deparse_func (
|
||||
@ -400,6 +398,26 @@ static global_t gtab[] =
|
||||
|
||||
#define SETERR_ARG(awk,code,ep,el) SETERR_ARG_LOC(awk,code,ep,el,QSE_NULL)
|
||||
|
||||
static QSE_INLINE int is_plain_var (qse_awk_nde_t* nde)
|
||||
{
|
||||
return nde->type == QSE_AWK_NDE_GBL ||
|
||||
nde->type == QSE_AWK_NDE_LCL ||
|
||||
nde->type == QSE_AWK_NDE_ARG ||
|
||||
nde->type == QSE_AWK_NDE_NAMED;
|
||||
}
|
||||
|
||||
static QSE_INLINE int is_var (qse_awk_nde_t* nde)
|
||||
{
|
||||
return nde->type == QSE_AWK_NDE_GBL ||
|
||||
nde->type == QSE_AWK_NDE_LCL ||
|
||||
nde->type == QSE_AWK_NDE_ARG ||
|
||||
nde->type == QSE_AWK_NDE_NAMED ||
|
||||
nde->type == QSE_AWK_NDE_GBLIDX ||
|
||||
nde->type == QSE_AWK_NDE_LCLIDX ||
|
||||
nde->type == QSE_AWK_NDE_ARGIDX ||
|
||||
nde->type == QSE_AWK_NDE_NAMEDIDX;
|
||||
}
|
||||
|
||||
static int get_char (qse_awk_t* awk)
|
||||
{
|
||||
qse_ssize_t n;
|
||||
@ -5762,26 +5780,6 @@ static int classify_ident (
|
||||
return TOK_IDENT;
|
||||
}
|
||||
|
||||
static int is_plain_var (qse_awk_nde_t* nde)
|
||||
{
|
||||
return nde->type == QSE_AWK_NDE_GBL ||
|
||||
nde->type == QSE_AWK_NDE_LCL ||
|
||||
nde->type == QSE_AWK_NDE_ARG ||
|
||||
nde->type == QSE_AWK_NDE_NAMED;
|
||||
}
|
||||
|
||||
static int is_var (qse_awk_nde_t* nde)
|
||||
{
|
||||
return nde->type == QSE_AWK_NDE_GBL ||
|
||||
nde->type == QSE_AWK_NDE_LCL ||
|
||||
nde->type == QSE_AWK_NDE_ARG ||
|
||||
nde->type == QSE_AWK_NDE_NAMED ||
|
||||
nde->type == QSE_AWK_NDE_GBLIDX ||
|
||||
nde->type == QSE_AWK_NDE_LCLIDX ||
|
||||
nde->type == QSE_AWK_NDE_ARGIDX ||
|
||||
nde->type == QSE_AWK_NDE_NAMEDIDX;
|
||||
}
|
||||
|
||||
struct deparse_func_t
|
||||
{
|
||||
qse_awk_t* awk;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: run.c 312 2009-12-10 13:03:54Z hyunghwan.chung $
|
||||
* $Id: run.c 323 2010-04-05 12:50:01Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -273,17 +273,17 @@ static qse_cstr_t* xstr_to_cstr (qse_xstr_t* xstr)
|
||||
}
|
||||
#endif
|
||||
|
||||
qse_size_t qse_awk_rtx_getnargs (qse_awk_rtx_t* run)
|
||||
QSE_INLINE qse_size_t qse_awk_rtx_getnargs (qse_awk_rtx_t* run)
|
||||
{
|
||||
return (qse_size_t) STACK_NARGS (run);
|
||||
}
|
||||
|
||||
qse_awk_val_t* qse_awk_rtx_getarg (qse_awk_rtx_t* run, qse_size_t idx)
|
||||
QSE_INLINE qse_awk_val_t* qse_awk_rtx_getarg (qse_awk_rtx_t* run, qse_size_t idx)
|
||||
{
|
||||
return STACK_ARG (run, idx);
|
||||
}
|
||||
|
||||
qse_awk_val_t* qse_awk_rtx_getgbl (qse_awk_rtx_t* run, int id)
|
||||
QSE_INLINE qse_awk_val_t* qse_awk_rtx_getgbl (qse_awk_rtx_t* run, int id)
|
||||
{
|
||||
QSE_ASSERT (id >= 0 && id < (int)QSE_LDA_SIZE(run->awk->parse.gbls));
|
||||
return STACK_GBL (run, id);
|
||||
@ -618,7 +618,7 @@ static int set_global (
|
||||
return 0;
|
||||
}
|
||||
|
||||
void qse_awk_rtx_setretval (qse_awk_rtx_t* rtx, qse_awk_val_t* val)
|
||||
QSE_INLINE void qse_awk_rtx_setretval (qse_awk_rtx_t* rtx, qse_awk_val_t* val)
|
||||
{
|
||||
qse_awk_rtx_refdownval (rtx, STACK_RETVAL(rtx));
|
||||
STACK_RETVAL(rtx) = val;
|
||||
@ -626,7 +626,7 @@ void qse_awk_rtx_setretval (qse_awk_rtx_t* rtx, qse_awk_val_t* val)
|
||||
qse_awk_rtx_refupval (rtx, val);
|
||||
}
|
||||
|
||||
int qse_awk_rtx_setgbl (qse_awk_rtx_t* rtx, int id, qse_awk_val_t* val)
|
||||
QSE_INLINE int qse_awk_rtx_setgbl (qse_awk_rtx_t* rtx, int id, qse_awk_val_t* val)
|
||||
{
|
||||
QSE_ASSERT (id >= 0 && id < (int)QSE_LDA_SIZE(rtx->awk->parse.gbls));
|
||||
return set_global (rtx, (qse_size_t)id, QSE_NULL, val);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: chr_cnv.c 287 2009-09-15 10:01:02Z hyunghwan.chung $
|
||||
* $Id: chr_cnv.c 323 2010-04-05 12:50:01Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -41,6 +41,13 @@ qse_size_t qse_mblen (const qse_mchar_t* mb, qse_size_t mblen)
|
||||
if (n == (size_t)-2) return mblen + 1; /* incomplete sequence */
|
||||
|
||||
return (qse_size_t)n;
|
||||
|
||||
#if 0
|
||||
n = mblen (mb, mblen, &mbs);
|
||||
if (n == 0) return 1; /* a null character */
|
||||
if (n == (size_t)-1) return 0; /* invalid or incomplete sequence */
|
||||
return (qse_size_t)n;
|
||||
#endif
|
||||
#else
|
||||
#error #### NOT SUPPORTED ####
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: fio.c 287 2009-09-15 10:01:02Z hyunghwan.chung $
|
||||
* $Id: fio.c 323 2010-04-05 12:50:01Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -213,16 +213,16 @@ qse_fio_t* qse_fio_init (
|
||||
qse_tio_t* tio;
|
||||
|
||||
tio = qse_tio_open (fio->mmgr, 0);
|
||||
if (tio == QSE_NULL) QSE_ERR_THROW (tio);
|
||||
if (tio == QSE_NULL) QSE_THROW_ERR (tio);
|
||||
|
||||
if (qse_tio_attachin (tio, fio_input, fio) == -1 ||
|
||||
qse_tio_attachout (tio, fio_output, fio) == -1)
|
||||
{
|
||||
qse_tio_close (tio);
|
||||
QSE_ERR_THROW (tio);
|
||||
QSE_THROW_ERR (tio);
|
||||
}
|
||||
|
||||
QSE_ERR_CATCH (tio)
|
||||
QSE_CATCH_ERR (tio)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
CloseHandle (handle);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: lda.c 287 2009-09-15 10:01:02Z hyunghwan.chung $
|
||||
* $Id: lda.c 323 2010-04-05 12:50:01Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -39,7 +39,7 @@ QSE_IMPLEMENT_COMMON_FUNCTIONS (lda)
|
||||
#define DPTR(node) ((node)->dptr)
|
||||
#define DLEN(node) ((node)->dlen)
|
||||
|
||||
static int comp_data (lda_t* lda,
|
||||
static int default_comparator (lda_t* lda,
|
||||
const void* dptr1, size_t dlen1,
|
||||
const void* dptr2, size_t dlen2)
|
||||
{
|
||||
@ -58,7 +58,7 @@ static int comp_data (lda_t* lda,
|
||||
return n;
|
||||
}
|
||||
|
||||
static node_t* alloc_node (lda_t* lda, void* dptr, size_t dlen)
|
||||
static QSE_INLINE node_t* alloc_node (lda_t* lda, void* dptr, size_t dlen)
|
||||
{
|
||||
node_t* n;
|
||||
|
||||
@ -136,7 +136,7 @@ lda_t* qse_lda_init (lda_t* lda, mmgr_t* mmgr, size_t capa)
|
||||
lda->node = QSE_NULL;
|
||||
|
||||
lda->copier = QSE_LDA_COPIER_SIMPLE;
|
||||
lda->comper = comp_data;
|
||||
lda->comper = default_comparator;
|
||||
|
||||
if (qse_lda_setcapa (lda, capa) == QSE_NULL) return QSE_NULL;
|
||||
return lda;
|
||||
@ -162,7 +162,8 @@ int qse_lda_getscale (lda_t* lda)
|
||||
void qse_lda_setscale (lda_t* lda, int scale)
|
||||
{
|
||||
QSE_ASSERTX (scale > 0 && scale <= QSE_TYPE_MAX(qse_byte_t),
|
||||
"The scale should be larger than 0 and less than or equal to the maximum value that the qse_byte_t type can hold");
|
||||
"The scale should be larger than 0 and less than or "
|
||||
"equal to the maximum value that the qse_byte_t type can hold");
|
||||
|
||||
if (scale <= 0) scale = 1;
|
||||
if (scale > QSE_TYPE_MAX(qse_byte_t)) scale = QSE_TYPE_MAX(qse_byte_t);
|
||||
@ -198,7 +199,7 @@ comper_t qse_lda_getcomper (lda_t* lda)
|
||||
|
||||
void qse_lda_setcomper (lda_t* lda, comper_t comper)
|
||||
{
|
||||
if (comper == QSE_NULL) comper = comp_data;
|
||||
if (comper == QSE_NULL) comper = default_comparator;
|
||||
lda->comper = comper;
|
||||
}
|
||||
|
||||
@ -236,8 +237,11 @@ lda_t* qse_lda_setcapa (lda_t* lda, size_t capa)
|
||||
{
|
||||
void* tmp;
|
||||
|
||||
if (capa == lda->capa) return lda;
|
||||
|
||||
if (lda->size > capa)
|
||||
{
|
||||
/* to trigger freeers on the items truncated */
|
||||
qse_lda_delete (lda, capa, lda->size - capa);
|
||||
QSE_ASSERT (lda->size <= capa);
|
||||
}
|
||||
@ -246,13 +250,14 @@ lda_t* qse_lda_setcapa (lda_t* lda, size_t capa)
|
||||
{
|
||||
if (lda->mmgr->realloc != QSE_NULL && lda->node != QSE_NULL)
|
||||
{
|
||||
tmp = (qse_lda_node_t**)QSE_MMGR_REALLOC (
|
||||
lda->mmgr, lda->node, QSE_SIZEOF(*lda->node)*capa);
|
||||
tmp = (node_t**) QSE_MMGR_REALLOC (
|
||||
lda->mmgr, lda->node,
|
||||
QSE_SIZEOF(*lda->node)*capa);
|
||||
if (tmp == QSE_NULL) return QSE_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = (qse_lda_node_t**) QSE_MMGR_ALLOC (
|
||||
tmp = (node_t**) QSE_MMGR_ALLOC (
|
||||
lda->mmgr, QSE_SIZEOF(*lda->node)*capa);
|
||||
if (tmp == QSE_NULL) return QSE_NULL;
|
||||
|
||||
@ -514,6 +519,8 @@ void qse_lda_walk (lda_t* lda, walker_t walker, void* arg)
|
||||
qse_lda_walk_t w = QSE_LDA_WALK_FORWARD;
|
||||
size_t i = 0;
|
||||
|
||||
if (lda->size <= 0) return;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (lda->node[i] != QSE_NULL)
|
||||
@ -562,3 +569,108 @@ void qse_lda_rwalk (lda_t* lda, walker_t walker, void* arg)
|
||||
}
|
||||
}
|
||||
|
||||
size_t qse_lda_pushstack (lda_t* lda, void* dptr, size_t dlen)
|
||||
{
|
||||
return qse_lda_insert (lda, lda->size, dptr, dlen);
|
||||
}
|
||||
|
||||
void qse_lda_popstack (lda_t* lda)
|
||||
{
|
||||
QSE_ASSERT (lda->size > 0);
|
||||
qse_lda_delete (lda, lda->size - 1, 1);
|
||||
}
|
||||
|
||||
#define HEAP_PARENT(x) (((x)-1) / 2)
|
||||
#define HEAP_LEFT(x) ((x)*2 + 1)
|
||||
#define HEAP_RIGHT(x) ((x)*2 + 2)
|
||||
|
||||
size_t qse_lda_pushheap (lda_t* lda, void* dptr, size_t dlen)
|
||||
{
|
||||
size_t cur, par;
|
||||
int n;
|
||||
|
||||
/* add a value to the bottom */
|
||||
cur = lda->size;
|
||||
if (qse_lda_insert (lda, cur, dptr, dlen) == QSE_LDA_NIL)
|
||||
return QSE_LDA_NIL;
|
||||
|
||||
while (cur != 0)
|
||||
{
|
||||
node_t* tmp;
|
||||
|
||||
/* compare with the parent */
|
||||
par = HEAP_PARENT(cur);
|
||||
n = lda->comper (lda,
|
||||
DPTR(lda->node[cur]), DLEN(lda->node[cur]),
|
||||
DPTR(lda->node[par]), DLEN(lda->node[par]));
|
||||
if (n <= 0) break; /* ok */
|
||||
|
||||
/* swap the current with the parent */
|
||||
tmp = lda->node[cur];
|
||||
lda->node[cur] = lda->node[par];
|
||||
lda->node[par] = tmp;
|
||||
|
||||
cur = par;
|
||||
}
|
||||
|
||||
return lda->size;
|
||||
}
|
||||
|
||||
void qse_lda_popheap (lda_t* lda)
|
||||
{
|
||||
size_t cur, child;
|
||||
node_t* tmp;
|
||||
|
||||
QSE_ASSERT (lda->size > 0);
|
||||
|
||||
/* destroy the top */
|
||||
tmp = lda->node[0];
|
||||
if (lda->freeer) lda->freeer (lda, DPTR(tmp), DLEN(tmp));
|
||||
QSE_MMGR_FREE (lda->mmgr, tmp);
|
||||
|
||||
/* move the last item to the top position also shrink the size */
|
||||
lda->node[0] = lda->node[--lda->size];
|
||||
|
||||
if (lda->size <= 1) return; /* only 1 element. nothing further to do */
|
||||
|
||||
for (cur = 0; cur < lda->size; cur = child)
|
||||
{
|
||||
size_t left, right;
|
||||
int n;
|
||||
|
||||
left = HEAP_LEFT(cur);
|
||||
right = HEAP_RIGHT(cur);
|
||||
|
||||
if (left >= lda->size)
|
||||
{
|
||||
/* the left child does not exist.
|
||||
* reached the bottom. abort exchange */
|
||||
break;
|
||||
}
|
||||
|
||||
if (right >= lda->size)
|
||||
{
|
||||
/* the right child does not exist. only the left */
|
||||
child = left;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* get the larger child of the two */
|
||||
n = lda->comper (lda,
|
||||
DPTR(lda->node[left]), DLEN(lda->node[left]),
|
||||
DPTR(lda->node[right]), DLEN(lda->node[right]));
|
||||
child = (n > 0)? left: right;
|
||||
}
|
||||
|
||||
/* compare the current one with the child */
|
||||
n = lda->comper (lda,
|
||||
DPTR(lda->node[cur]), DLEN(lda->node[cur]),
|
||||
DPTR(lda->node[child]), DLEN(lda->node[child]));
|
||||
if (n > 0) break; /* current one is larger. stop exchange */
|
||||
|
||||
/* swap the current with the child */
|
||||
tmp = lda->node[cur];
|
||||
lda->node[cur] = lda->node[child];
|
||||
lda->node[child] = tmp;
|
||||
}
|
||||
}
|
||||
|
@ -19,10 +19,9 @@
|
||||
*/
|
||||
|
||||
#include <qse/cmn/main.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <qse/cmn/str.h>
|
||||
#include <locale.h>
|
||||
#include "mem.h"
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||
|
||||
@ -37,62 +36,62 @@ int qse_runmain (int argc, qse_achar_t* argv[], int(*mf) (int,qse_char_t*[]))
|
||||
{
|
||||
int i, ret;
|
||||
qse_char_t** v;
|
||||
qse_mmgr_t* mmgr = QSE_MMGR_GETDFL ();
|
||||
|
||||
setlocale (LC_ALL, "");
|
||||
|
||||
v = (qse_char_t**) malloc (argc * QSE_SIZEOF(qse_char_t*));
|
||||
if (v == NULL) return -1;
|
||||
v = (qse_char_t**) QSE_MMGR_ALLOC (
|
||||
mmgr, argc * QSE_SIZEOF(qse_char_t*));
|
||||
if (v == QSE_NULL) return -1;
|
||||
|
||||
for (i = 0; i < argc; i++) v[i] = QSE_NULL;
|
||||
|
||||
for (i = 0; i < argc; i++) v[i] = NULL;
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
qse_size_t n, len, rem;
|
||||
char* p = argv[i];
|
||||
qse_size_t n, len, nlen;
|
||||
qse_size_t mbslen;
|
||||
|
||||
len = 0; rem = strlen (p);
|
||||
while (*p != '\0')
|
||||
mbslen = qse_mbslen (argv[i]);
|
||||
|
||||
n = qse_mbstowcslen (argv[i], &len);
|
||||
if (n < mbslen)
|
||||
{
|
||||
int x = mblen (p, rem);
|
||||
if (x == -1)
|
||||
{
|
||||
ret = -1;
|
||||
goto exit_main;
|
||||
}
|
||||
if (x == 0) break;
|
||||
p += x; rem -= x; len++;
|
||||
ret = -1; goto oops;
|
||||
}
|
||||
|
||||
#if (defined(vms) || defined(__vms)) && (QSE_SIZEOF_VOID_P >= 8)
|
||||
v[i] = (qse_char_t*) _malloc32 ((len+1)*QSE_SIZEOF(qse_char_t));
|
||||
#else
|
||||
v[i] = (qse_char_t*) malloc ((len+1)*QSE_SIZEOF(qse_char_t));
|
||||
#endif
|
||||
if (v[i] == NULL)
|
||||
len++; /* include the terminating null */
|
||||
|
||||
v[i] = (qse_char_t*) QSE_MMGR_ALLOC (
|
||||
mmgr, len*QSE_SIZEOF(qse_char_t));
|
||||
if (v[i] == QSE_NULL)
|
||||
{
|
||||
ret = -1;
|
||||
goto exit_main;
|
||||
ret = -1; goto oops;
|
||||
}
|
||||
|
||||
n = mbstowcs (v[i], argv[i], len);
|
||||
if (n == (size_t)-1)
|
||||
nlen = len;
|
||||
n = qse_mbstowcs (argv[i], v[i], &nlen);
|
||||
if (nlen >= len)
|
||||
{
|
||||
/* error */
|
||||
return -1;
|
||||
/* no null-termination */
|
||||
ret = -1; goto oops;
|
||||
}
|
||||
if (argv[i][n] != '\0')
|
||||
{
|
||||
/* partial processing */
|
||||
ret = -1; goto oops;
|
||||
}
|
||||
|
||||
if (n == len) v[i][len] = QSE_T('\0');
|
||||
}
|
||||
|
||||
/* TODO: envp... */
|
||||
//ret = mf (argc, v, NULL);
|
||||
//ret = mf (argc, v, QSE_NULL);
|
||||
ret = mf (argc, v);
|
||||
|
||||
exit_main:
|
||||
oops:
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
if (v[i] != NULL) free (v[i]);
|
||||
if (v[i] != QSE_NULL) QSE_MMGR_FREE (mmgr, v[i]);
|
||||
}
|
||||
free (v);
|
||||
QSE_MMGR_FREE (mmgr, v);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: str_bas.c 320 2009-12-21 12:29:52Z hyunghwan.chung $
|
||||
* $Id: str_bas.c 323 2010-04-05 12:50:01Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -36,6 +36,20 @@ qse_size_t qse_strbytes (const qse_char_t* str)
|
||||
return (p - str) * QSE_SIZEOF(qse_char_t);
|
||||
}
|
||||
|
||||
qse_size_t qse_mbslen (const qse_mchar_t* mbs)
|
||||
{
|
||||
const qse_mchar_t* p = mbs;
|
||||
while (*p != QSE_T('\0')) p++;
|
||||
return p - mbs;
|
||||
}
|
||||
|
||||
qse_size_t qse_wcslen (const qse_wchar_t* wcs)
|
||||
{
|
||||
const qse_wchar_t* p = wcs;
|
||||
while (*p != QSE_T('\0')) p++;
|
||||
return p - wcs;
|
||||
}
|
||||
|
||||
qse_size_t qse_strcpy (qse_char_t* buf, const qse_char_t* str)
|
||||
{
|
||||
qse_char_t* org = buf;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: str_cnv.c 287 2009-09-15 10:01:02Z hyunghwan.chung $
|
||||
* $Id: str_cnv.c 323 2010-04-05 12:50:01Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -133,6 +133,45 @@ qse_ulong_t qse_strxtoulong (const qse_char_t* str, qse_size_t len)
|
||||
return v;
|
||||
}
|
||||
|
||||
qse_size_t qse_mbstowcslen (const qse_mchar_t* mcs, qse_size_t* wcslen)
|
||||
{
|
||||
qse_wchar_t wc;
|
||||
qse_size_t n, ml, wl = 0;
|
||||
const qse_mchar_t* p = mcs;
|
||||
|
||||
while (*p != '\0') p++;
|
||||
ml = p - mcs;
|
||||
|
||||
for (p = mcs; ml > 0; p += n, ml -= n)
|
||||
{
|
||||
n = qse_mbtowc (p, ml, &wc);
|
||||
/* insufficient input or wrong sequence */
|
||||
if (n == 0 || n > ml) break;
|
||||
wl++;
|
||||
}
|
||||
|
||||
if (wcslen) *wcslen = wl;
|
||||
return p - mcs;
|
||||
}
|
||||
|
||||
qse_size_t qse_mbsntowcsnlen (const qse_mchar_t* mcs, qse_size_t mcslen, qse_size_t* wcslen)
|
||||
{
|
||||
qse_wchar_t wc;
|
||||
qse_size_t n, ml = mcslen, wl = 0;
|
||||
const qse_mchar_t* p = mcs;
|
||||
|
||||
for (p = mcs; ml > 0; p += n, ml -= n)
|
||||
{
|
||||
n = qse_mbtowc (p, ml, &wc);
|
||||
/* insufficient or invalid sequence */
|
||||
if (n == 0 || n > ml) break;
|
||||
wl++;
|
||||
}
|
||||
|
||||
if (wcslen) *wcslen = wl;
|
||||
return mcslen - ml;
|
||||
}
|
||||
|
||||
qse_size_t qse_mbstowcs (
|
||||
const qse_mchar_t* mbs, qse_wchar_t* wcs, qse_size_t* wcslen)
|
||||
{
|
||||
@ -141,23 +180,25 @@ qse_size_t qse_mbstowcs (
|
||||
|
||||
/* get the length of mbs and pass it to qse_mbsntowcsn as
|
||||
* qse_mbtowc called by qse_mbsntowcsn needs it. */
|
||||
wlen = *wcslen;
|
||||
if (wlen <= 0)
|
||||
{
|
||||
/* buffer too small. also cannot null-terminate it */
|
||||
*wcslen = 0;
|
||||
return 0; /* 0 byte processed */
|
||||
}
|
||||
|
||||
for (mp = mbs; *mp != '\0'; mp++);
|
||||
|
||||
if (*wcslen <= 0)
|
||||
{
|
||||
/* buffer too small. cannot null-terminate it */
|
||||
return 0;
|
||||
}
|
||||
if (*wcslen == 1)
|
||||
{
|
||||
wcs[0] = L'\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
wlen = *wcslen - 1;
|
||||
mlen = qse_mbsntowcsn (mbs, mp - mbs, wcs, &wlen);
|
||||
|
||||
if (wlen < *wcslen)
|
||||
{
|
||||
/* null-terminate wcs if it is large enough. */
|
||||
wcs[wlen] = L'\0';
|
||||
}
|
||||
|
||||
/* if null-terminated properly, the input wcslen must be less than
|
||||
* the output wcslen. (input length includs the terminating null
|
||||
* while the output length excludes the terminating null) */
|
||||
*wcslen = wlen;
|
||||
|
||||
return mlen;
|
||||
@ -305,6 +346,29 @@ qse_size_t qse_wcsntombsn (
|
||||
return p - wcs;
|
||||
}
|
||||
|
||||
int qse_mbstowcs_strict (
|
||||
const qse_mchar_t* mbs, qse_wchar_t* wcs, qse_size_t wcslen)
|
||||
{
|
||||
qse_size_t n;
|
||||
qse_size_t wn = wcslen;
|
||||
|
||||
n = qse_mbstowcs (mbs, wcs, &wn);
|
||||
if (wn >= wcslen)
|
||||
{
|
||||
/* wcs not big enough to be null-terminated.
|
||||
* if it has been null-terminated properly,
|
||||
* wn should be less than wcslen. */
|
||||
return -1;
|
||||
}
|
||||
if (mbs[n] != QSE_MT('\0'))
|
||||
{
|
||||
/* incomplete sequence or invalid sequence */
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qse_wcstombs_strict (
|
||||
const qse_wchar_t* wcs, qse_mchar_t* mbs, qse_size_t mbslen)
|
||||
{
|
||||
@ -312,13 +376,6 @@ int qse_wcstombs_strict (
|
||||
qse_size_t mn = mbslen;
|
||||
|
||||
n = qse_wcstombs (wcs, mbs, &mn);
|
||||
if (wcs[n] != QSE_WT('\0'))
|
||||
{
|
||||
/* if qse_wcstombs() processed all wide characters,
|
||||
* the character at position 'n' should be a null character
|
||||
* as 'n' is the number of wide characters processed. */
|
||||
return -1;
|
||||
}
|
||||
if (mn >= mbslen)
|
||||
{
|
||||
/* mbs not big enough to be null-terminated.
|
||||
@ -326,6 +383,14 @@ int qse_wcstombs_strict (
|
||||
* mn should be less than mbslen. */
|
||||
return -1;
|
||||
}
|
||||
if (wcs[n] != QSE_WT('\0'))
|
||||
{
|
||||
/* if qse_wcstombs() processed all wide characters,
|
||||
* the character at position 'n' should be a null character
|
||||
* as 'n' is the number of wide characters processed. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
38
qse/regress/awk/passwd.dat
Normal file
38
qse/regress/awk/passwd.dat
Normal file
@ -0,0 +1,38 @@
|
||||
root:x:0:0:root:/root:/bin/bash
|
||||
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
|
||||
bin:x:2:2:bin:/bin:/bin/sh
|
||||
sys:x:3:3:sys:/dev:/bin/sh
|
||||
sync:x:4:65534:sync:/bin:/bin/sync
|
||||
games:x:5:60:games:/usr/games:/bin/sh
|
||||
man:x:6:12:man:/var/cache/man:/bin/sh
|
||||
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
|
||||
mail:x:8:8:mail:/var/mail:/bin/sh
|
||||
news:x:9:9:news:/var/spool/news:/bin/sh
|
||||
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
|
||||
proxy:x:13:13:proxy:/bin:/bin/sh
|
||||
www-data:x:33:33:www-data:/var/www:/bin/sh
|
||||
backup:x:34:34:backup:/var/backups:/bin/sh
|
||||
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
|
||||
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
|
||||
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
|
||||
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
|
||||
libuuid:x:100:101::/var/lib/libuuid:/bin/sh
|
||||
syslog:x:101:102::/home/syslog:/bin/false
|
||||
klog:x:102:103::/home/klog:/bin/false
|
||||
hplip:x:103:7:HPLIP system user,,,:/var/run/hplip:/bin/false
|
||||
avahi-autoipd:x:104:110:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/bin/false
|
||||
gdm:x:105:111:Gnome Display Manager:/var/lib/gdm:/bin/false
|
||||
saned:x:106:113::/home/saned:/bin/false
|
||||
pulse:x:107:114:PulseAudio daemon,,,:/var/run/pulse:/bin/false
|
||||
messagebus:x:108:117::/var/run/dbus:/bin/false
|
||||
polkituser:x:109:118:PolicyKit,,,:/var/run/PolicyKit:/bin/false
|
||||
avahi:x:110:119:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/bin/false
|
||||
haldaemon:x:111:120:Hardware abstraction layer,,,:/var/run/hald:/bin/false
|
||||
statd:x:112:65534::/var/lib/nfs:/bin/false
|
||||
sshd:x:113:65534::/var/run/sshd:/usr/sbin/nologin
|
||||
speech-dispatcher:x:114:29:Speech Dispatcher,,,:/var/run/speech-dispatcher:/bin/sh
|
||||
couchdb:x:115:116:CouchDB Administrator,,,:/var/lib/couchdb:/bin/bash
|
||||
kernoops:x:116:65534:Kernel Oops Tracking Daemon,,,:/:/bin/false
|
||||
mysql:x:117:124:MySQL Server,,,:/var/lib/mysql:/bin/false
|
||||
openldap:x:118:125:OpenLDAP Server Account,,,:/nonexistent:/bin/false
|
||||
postfix:x:119:126::/var/spool/postfix:/bin/false
|
@ -2087,7 +2087,7 @@ IGNORECASE= 1
|
||||
1
|
||||
1
|
||||
--------------------------------------------------------------------------------
|
||||
../../cmd/awk/.libs/qseawk --newline=on -F: -f columnate.awk /etc/passwd </dev/stdin 2>&1
|
||||
../../cmd/awk/.libs/qseawk --newline=on -F: -f columnate.awk ./passwd.dat </dev/stdin 2>&1
|
||||
--------------------------------------------------------------------------------
|
||||
root x 0 0 root /root /bin/bash
|
||||
daemon x 1 1 daemon /usr/sbin /bin/sh
|
||||
@ -2119,12 +2119,14 @@ messagebus x 108 117 /var/run
|
||||
polkituser x 109 118 PolicyKit,,, /var/run/PolicyKit /bin/false
|
||||
avahi x 110 119 Avahi mDNS daemon,,, /var/run/avahi-daemon /bin/false
|
||||
haldaemon x 111 120 Hardware abstraction layer,,, /var/run/hald /bin/false
|
||||
hyung-hwan x 1000 1000 hyung-hwan chung,,, /home/hyung-hwan /bin/bash
|
||||
statd x 112 65534 /var/lib/nfs /bin/false
|
||||
sshd x 113 65534 /var/run/sshd /usr/sbin/nologin
|
||||
speech-dispatcher x 114 29 Speech Dispatcher,,, /var/run/speech-dispatcher /bin/sh
|
||||
couchdb x 115 116 CouchDB Administrator,,, /var/lib/couchdb /bin/bash
|
||||
kernoops x 116 65534 Kernel Oops Tracking Daemon,,, / /bin/false
|
||||
mysql x 117 124 MySQL Server,,, /var/lib/mysql /bin/false
|
||||
openldap x 118 125 OpenLDAP Server Account,,, /nonexistent /bin/false
|
||||
postfix x 119 126 /var/spool/postfix /bin/false
|
||||
--------------------------------------------------------------------------------
|
||||
../../cmd/awk/.libs/qseawk --newline=on --include=on -f levenshtein-utests.awk </dev/stdin 2>&1
|
||||
--------------------------------------------------------------------------------
|
||||
|
@ -154,7 +154,7 @@ PROGS="
|
||||
lang-041.awk!!!--newline=on -o-
|
||||
lang-042.awk!!!--newline=on -o-
|
||||
|
||||
columnate.awk!/etc/passwd!!--newline=on -F:
|
||||
columnate.awk!./passwd.dat!!--newline=on -F:
|
||||
levenshtein-utests.awk!!!--newline=on --include=on
|
||||
rcalc.awk!!!--newline=on -v target=89000
|
||||
quicksort.awk!quicksort.dat!!
|
||||
|
@ -1,6 +1,6 @@
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include -DNDEBUG
|
||||
|
||||
bin_PROGRAMS = chr str sll map lda fio pio sio time rex01
|
||||
bin_PROGRAMS = chr str sll map lda fio pio sio time main rex01
|
||||
|
||||
LDFLAGS = -L../../lib/cmn
|
||||
LDADD = -lqsecmn
|
||||
@ -14,6 +14,7 @@ fio_SOURCES = fio.c
|
||||
pio_SOURCES = pio.c
|
||||
sio_SOURCES = sio.c
|
||||
time_SOURCES = time.c
|
||||
main_SOURCES = main.c
|
||||
rex01_SOURCES = rex01.c
|
||||
|
||||
if ENABLE_CXX
|
||||
|
@ -36,7 +36,7 @@ build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
bin_PROGRAMS = chr$(EXEEXT) str$(EXEEXT) sll$(EXEEXT) map$(EXEEXT) \
|
||||
lda$(EXEEXT) fio$(EXEEXT) pio$(EXEEXT) sio$(EXEEXT) \
|
||||
time$(EXEEXT) rex01$(EXEEXT)
|
||||
time$(EXEEXT) main$(EXEEXT) rex01$(EXEEXT)
|
||||
subdir = samples/cmn
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
@ -65,6 +65,10 @@ am_lda_OBJECTS = lda.$(OBJEXT)
|
||||
lda_OBJECTS = $(am_lda_OBJECTS)
|
||||
lda_LDADD = $(LDADD)
|
||||
lda_DEPENDENCIES =
|
||||
am_main_OBJECTS = main.$(OBJEXT)
|
||||
main_OBJECTS = $(am_main_OBJECTS)
|
||||
main_LDADD = $(LDADD)
|
||||
main_DEPENDENCIES =
|
||||
am_map_OBJECTS = map.$(OBJEXT)
|
||||
map_OBJECTS = $(am_map_OBJECTS)
|
||||
map_LDADD = $(LDADD)
|
||||
@ -106,12 +110,12 @@ CCLD = $(CC)
|
||||
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
|
||||
$(LDFLAGS) -o $@
|
||||
SOURCES = $(chr_SOURCES) $(fio_SOURCES) $(lda_SOURCES) $(map_SOURCES) \
|
||||
$(pio_SOURCES) $(rex01_SOURCES) $(sio_SOURCES) $(sll_SOURCES) \
|
||||
$(str_SOURCES) $(time_SOURCES)
|
||||
DIST_SOURCES = $(chr_SOURCES) $(fio_SOURCES) $(lda_SOURCES) \
|
||||
SOURCES = $(chr_SOURCES) $(fio_SOURCES) $(lda_SOURCES) $(main_SOURCES) \
|
||||
$(map_SOURCES) $(pio_SOURCES) $(rex01_SOURCES) $(sio_SOURCES) \
|
||||
$(sll_SOURCES) $(str_SOURCES) $(time_SOURCES)
|
||||
DIST_SOURCES = $(chr_SOURCES) $(fio_SOURCES) $(lda_SOURCES) \
|
||||
$(main_SOURCES) $(map_SOURCES) $(pio_SOURCES) $(rex01_SOURCES) \
|
||||
$(sio_SOURCES) $(sll_SOURCES) $(str_SOURCES) $(time_SOURCES)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
@ -265,6 +269,7 @@ fio_SOURCES = fio.c
|
||||
pio_SOURCES = pio.c
|
||||
sio_SOURCES = sio.c
|
||||
time_SOURCES = time.c
|
||||
main_SOURCES = main.c
|
||||
rex01_SOURCES = rex01.c
|
||||
all: all-am
|
||||
|
||||
@ -352,6 +357,9 @@ fio$(EXEEXT): $(fio_OBJECTS) $(fio_DEPENDENCIES)
|
||||
lda$(EXEEXT): $(lda_OBJECTS) $(lda_DEPENDENCIES)
|
||||
@rm -f lda$(EXEEXT)
|
||||
$(LINK) $(lda_OBJECTS) $(lda_LDADD) $(LIBS)
|
||||
main$(EXEEXT): $(main_OBJECTS) $(main_DEPENDENCIES)
|
||||
@rm -f main$(EXEEXT)
|
||||
$(LINK) $(main_OBJECTS) $(main_LDADD) $(LIBS)
|
||||
map$(EXEEXT): $(map_OBJECTS) $(map_DEPENDENCIES)
|
||||
@rm -f map$(EXEEXT)
|
||||
$(LINK) $(map_OBJECTS) $(map_LDADD) $(LIBS)
|
||||
@ -383,6 +391,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chr.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fio.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lda.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pio.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rex01.Po@am__quote@
|
||||
|
@ -37,7 +37,7 @@ static int test2 (void)
|
||||
|
||||
for (i = 0; i < QSE_COUNTOF(x); i++)
|
||||
{
|
||||
qse_size_t k = strlen(x[i]);
|
||||
qse_size_t k = qse_mbslen(x[i]);
|
||||
qse_size_t j = 0;
|
||||
qse_wchar_t wc;
|
||||
|
||||
@ -102,7 +102,7 @@ static int test3 (void)
|
||||
|
||||
for (i = 0; i < QSE_COUNTOF(x); i++)
|
||||
{
|
||||
int len = wcslen (x[i]);
|
||||
int len = qse_wcslen (x[i]);
|
||||
if (len == 0) len++; /* for x[0] */
|
||||
|
||||
qse_printf (QSE_T("["));
|
||||
|
@ -32,7 +32,7 @@ static int test1 (void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
n = qse_fio_write (fio, x, strlen(x));
|
||||
n = qse_fio_write (fio, x, qse_mbslen(x));
|
||||
qse_printf (QSE_T("written %d bytes\n"), (int)n);
|
||||
|
||||
|
||||
@ -77,7 +77,7 @@ static int test1 (void)
|
||||
qse_printf (QSE_T("moved file offset to %lld\n"), (long long)off);
|
||||
}
|
||||
|
||||
n = qse_fio_write (fio, x2, strlen(x2));
|
||||
n = qse_fio_write (fio, x2, qse_mbslen(x2));
|
||||
qse_printf (QSE_T("written %d bytes\n"), (int)n);
|
||||
|
||||
qse_fio_close (fio);
|
||||
@ -110,7 +110,7 @@ static int test2 (void)
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
n = qse_fio_write (fio, x, strlen(x));
|
||||
n = qse_fio_write (fio, x, qse_mbslen(x));
|
||||
qse_printf (QSE_T("written %d bytes\n"), (int)n);
|
||||
|
||||
off = qse_fio_seek (fio, 0, QSE_FIO_CURRENT);
|
||||
@ -156,7 +156,7 @@ static int test2 (void)
|
||||
qse_printf (QSE_T("moved file offset to %lld\n"), (long long)off);
|
||||
}
|
||||
|
||||
n = qse_fio_write (fio, x2, strlen(x2));
|
||||
n = qse_fio_write (fio, x2, qse_mbslen(x2));
|
||||
qse_printf (QSE_T("written %d bytes\n"), (int)n);
|
||||
|
||||
off = qse_fio_seek (fio, 0, QSE_FIO_CURRENT);
|
||||
@ -174,7 +174,7 @@ static int test2 (void)
|
||||
qse_printf (QSE_T("failed to truncate the file\n"));
|
||||
}
|
||||
|
||||
n = qse_fio_write (fio, x2, strlen(x2));
|
||||
n = qse_fio_write (fio, x2, qse_mbslen(x2));
|
||||
qse_printf (QSE_T("written %d bytes\n"), (int)n);
|
||||
|
||||
off = qse_fio_seek (fio, 0, QSE_FIO_CURRENT);
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <qse/cmn/str.h>
|
||||
#include <qse/cmn/lda.h>
|
||||
#include <qse/cmn/stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#define R(f) \
|
||||
@ -28,6 +29,13 @@ qse_lda_walk_t rwalker1 (qse_lda_t* lda, qse_size_t index, void* arg)
|
||||
return QSE_LDA_WALK_BACKWARD;
|
||||
}
|
||||
|
||||
qse_lda_walk_t walker3 (qse_lda_t* lda, qse_size_t index, void* arg)
|
||||
{
|
||||
qse_printf (QSE_T("%d => [%d]\n"),
|
||||
index, *(int*)QSE_LDA_DPTR(lda,index));
|
||||
return QSE_LDA_WALK_FORWARD;
|
||||
}
|
||||
|
||||
static int test1 ()
|
||||
{
|
||||
qse_lda_t* s1;
|
||||
@ -102,6 +110,8 @@ static int test1 ()
|
||||
qse_printf (QSE_T("lda size => %lu\n"), QSE_LDA_SIZE(s1));
|
||||
qse_lda_rwalk (s1, rwalker1, QSE_NULL);
|
||||
|
||||
qse_lda_setcapa (s1, 3);
|
||||
|
||||
qse_lda_close (s1);
|
||||
return 0;
|
||||
}
|
||||
@ -328,7 +338,7 @@ static int test4 ()
|
||||
s1 = qse_lda_open (QSE_MMGR_GETDFL(), 0, 3);
|
||||
if (s1 == QSE_NULL)
|
||||
{
|
||||
qse_printf (QSE_T("cannot open a string\n"));
|
||||
qse_printf (QSE_T("cannot open an array\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -359,11 +369,92 @@ static int test4 ()
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
qse_lda_comper_t default_comparator;
|
||||
|
||||
static int inverse_comparator (qse_lda_t* lda,
|
||||
const void* dptr1, size_t dlen1,
|
||||
const void* dptr2, size_t dlen2)
|
||||
{
|
||||
return -default_comparator (lda, dptr1, dlen1, dptr2, dlen2);
|
||||
}
|
||||
|
||||
static int test5 ()
|
||||
{
|
||||
qse_lda_t* s1;
|
||||
int i, j;
|
||||
|
||||
s1 = qse_lda_open (QSE_MMGR_GETDFL(), 0, 3);
|
||||
if (s1 == QSE_NULL)
|
||||
{
|
||||
qse_printf (QSE_T("cannot open an array\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
qse_lda_setcopier (s1, QSE_LDA_COPIER_INLINE);
|
||||
qse_lda_setscale (s1, QSE_SIZEOF(i));
|
||||
|
||||
/* inverse the comparator to implement min-heap */
|
||||
default_comparator = qse_lda_getcomper (s1);
|
||||
qse_lda_setcomper (s1, inverse_comparator);
|
||||
|
||||
for (i = 0; i < 25; i++)
|
||||
{
|
||||
j = random () % 100;
|
||||
qse_lda_pushheap (s1, &j, 1);
|
||||
}
|
||||
|
||||
qse_printf (QSE_T("lda size => %lu\n"), QSE_LDA_SIZE(s1));
|
||||
qse_lda_walk (s1, walker3, QSE_NULL);
|
||||
|
||||
while (QSE_LDA_SIZE(s1) > 10 )
|
||||
{
|
||||
qse_printf (QSE_T("top => %d\n"), *(int*)QSE_LDA_DPTR(s1,0));
|
||||
qse_lda_popheap (s1);
|
||||
}
|
||||
|
||||
for (i = 0; i < 25; i++)
|
||||
{
|
||||
j = random () % 100;
|
||||
qse_lda_pushheap (s1, &j, 1);
|
||||
}
|
||||
|
||||
qse_printf (QSE_T("lda size => %lu\n"), QSE_LDA_SIZE(s1));
|
||||
qse_lda_walk (s1, walker3, QSE_NULL);
|
||||
|
||||
while (QSE_LDA_SIZE(s1))
|
||||
{
|
||||
qse_printf (QSE_T("top => %d\n"), *(int*)QSE_LDA_DPTR(s1,0));
|
||||
qse_lda_popheap (s1);
|
||||
}
|
||||
|
||||
qse_lda_setcomper (s1, default_comparator);
|
||||
for (i = 0; i < 25; i++)
|
||||
{
|
||||
j = random () % 100;
|
||||
qse_lda_pushheap (s1, &j, 1);
|
||||
}
|
||||
|
||||
qse_printf (QSE_T("lda size => %lu\n"), QSE_LDA_SIZE(s1));
|
||||
qse_lda_walk (s1, walker3, QSE_NULL);
|
||||
|
||||
while (QSE_LDA_SIZE(s1))
|
||||
{
|
||||
qse_printf (QSE_T("top => %d\n"), *(int*)QSE_LDA_DPTR(s1,0));
|
||||
qse_lda_popheap (s1);
|
||||
}
|
||||
|
||||
|
||||
qse_lda_close (s1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
R (test1);
|
||||
R (test2);
|
||||
R (test3);
|
||||
R (test4);
|
||||
R (test5);
|
||||
return 0;
|
||||
}
|
||||
|
20
qse/samples/cmn/main.c
Normal file
20
qse/samples/cmn/main.c
Normal file
@ -0,0 +1,20 @@
|
||||
#include <qse/cmn/main.h>
|
||||
#include <qse/cmn/stdio.h>
|
||||
|
||||
static int test_main (int argc, qse_char_t* argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
qse_printf (QSE_T("%d => [%s]\n"), i, argv[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qse_main (int argc, qse_achar_t* argv[])
|
||||
{
|
||||
return qse_runmain (argc, argv, test_main);
|
||||
}
|
||||
|
@ -168,7 +168,7 @@ static int test5 (void)
|
||||
|
||||
for (i = 0; i < QSE_COUNTOF(x); i++)
|
||||
{
|
||||
qse_size_t k = strlen(x[i]);
|
||||
qse_size_t k = qse_mbslen(x[i]);
|
||||
qse_size_t j = 0;
|
||||
qse_wchar_t wc;
|
||||
qse_wchar_t buf[10];
|
||||
|
Loading…
Reference in New Issue
Block a user