-added Awk::Value::getFirstIndex() & Awk::Value::getNextIndex()

-fixed a few bugs in the Awk::Value class
This commit is contained in:
hyung-hwan 2009-07-14 02:51:23 +00:00
parent 814ed89e53
commit 9b6eb94664
11 changed files with 1077 additions and 730 deletions

View File

@ -1,5 +1,5 @@
/* /*
* $Id: Awk.hpp 229 2009-07-12 13:06:01Z hyunghwan.chung $ * $Id: Awk.hpp 230 2009-07-13 08:51:23Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -239,6 +239,69 @@ public:
void operator delete (void* p) throw (); void operator delete (void* p) throw ();
void operator delete[] (void* p) throw (); void operator delete[] (void* p) throw ();
class Index
{
public:
friend class Value;
Index (): ptr (EMPTY_STRING), len (0) {}
Index (const char_t* ptr, size_t len):
ptr (ptr), len (len) {}
const char_t* ptr;
size_t len;
};
class IntIndex: public Index
{
public:
IntIndex (long_t num);
protected:
// 2^32: 4294967296
// 2^64: 18446744073709551616
// 2^128: 340282366920938463463374607431768211456
// -(2^32/2): -2147483648
// -(2^64/2): -9223372036854775808
// -(2^128/2): -170141183460469231731687303715884105728
#if QSE_SIZEOF_LONG_T > 16
# error SIZEOF(qse_long_t) TOO LARGE.
# error INCREASE THE BUFFER SIZE TO SUPPORT IT.
#elif QSE_SIZEOF_LONG_T == 16
char_t buf[41];
#elif QSE_SIZEOF_LONG_T == 8
char_t buf[21];
#else
char_t buf[12];
#endif
};
class IndexIterator
{
public:
friend class Value;
static IndexIterator END;
IndexIterator (): pair (QSE_NULL), buckno (0) {}
IndexIterator (pair_t* pair, size_t buckno):
pair (pair), buckno (buckno) {}
bool operator== (const IndexIterator& ii) const
{
return pair == ii.pair && buckno == ii.buckno;
}
bool operator!= (const IndexIterator& ii) const
{
return !operator== (ii);
}
protected:
pair_t* pair;
size_t buckno;
};
Value (); Value ();
Value (Run& run); Value (Run& run);
Value (Run* run); Value (Run* run);
@ -302,62 +365,75 @@ public:
int setStr (Run* r, const char_t* str); int setStr (Run* r, const char_t* str);
int setIndexedVal ( int setIndexedVal (
const char_t* idx, size_t isz, val_t* v); const Index& idx,
val_t* v
);
int setIndexedVal ( int setIndexedVal (
Run* r, const char_t* idx, size_t isz, val_t* v); Run* r,
const Index& idx,
val_t* v
);
int setIndexedInt ( int setIndexedInt (
const char_t* idx, size_t isz, long_t v); const Index& idx,
long_t v
);
int setIndexedInt ( int setIndexedInt (
Run* r, const char_t* idx, size_t isz, long_t v); Run* r,
const Index& idx,
long_t v);
int setIndexedReal ( int setIndexedReal (
const char_t* idx, const Index& idx,
size_t isz,
real_t v real_t v
); );
int setIndexedReal ( int setIndexedReal (
Run* r, Run* r,
const char_t* idx, const Index& idx,
size_t isz,
real_t v real_t v
); );
int setIndexedStr ( int setIndexedStr (
const char_t* idx, const Index& idx,
size_t isz,
const char_t* str, const char_t* str,
size_t len size_t len
); );
int setIndexedStr ( int setIndexedStr (
Run* r, Run* r,
const char_t* idx, const Index& idx,
size_t isz,
const char_t* str, const char_t* str,
size_t len size_t len
); );
int setIndexedStr ( int setIndexedStr (
const char_t* idx, const Index& idx,
size_t isz,
const char_t* str const char_t* str
); );
int setIndexedStr ( int setIndexedStr (
Run* r, Run* r,
const char_t* idx, const Index& idx,
size_t isz,
const char_t* str const char_t* str
); );
bool isIndexed () const; bool isIndexed () const;
int getIndexed ( int getIndexed (
const char_t* idx, const Index& idx,
size_t isz, Value* val
Value& val ) const;
IndexIterator getFirstIndex (
Index* idx
) const;
IndexIterator getNextIndex (
Index* idx,
const IndexIterator& iter
) const; ) const;
protected: protected:

View File

@ -1,5 +1,5 @@
/* /*
* $Id: StdAwk.hpp 229 2009-07-12 13:06:01Z hyunghwan.chung $ * $Id: StdAwk.hpp 230 2009-07-13 08:51:23Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -23,9 +23,11 @@
/** /**
* @example awk05.cpp * @example awk05.cpp
* This program demonstrates how to embed QSE::StdAwk in C++. * This program demonstrates how to embed QSE::StdAwk::loop().
* @example awk06.cpp * @example awk06.cpp
* This program demonstrates how to embed QSE::StdAwk in C++. * This program demonstrates how to use QSE::StdAwk::call().
* @example awk07.cpp
* This program demonstrates how to handle an indexed value.
*/ */
///////////////////////////////// /////////////////////////////////

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.h 228 2009-07-11 03:01:36Z hyunghwan.chung $ * $Id: awk.h 230 2009-07-13 08:51:23Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -1809,6 +1809,18 @@ void* qse_awk_rtx_alloc (
qse_size_t size /**< block size in bytes */ qse_size_t size /**< block size in bytes */
); );
/**
* The qse_awk_rtx_realloc() function resizes a memory block pointed to
* by @a ptr to @a size bytes using the memory manager associated with
* a runtime context @a rtx.
* @return the pointer to a memory block on success, #QSE_NULL on failure.
*/
void* qse_awk_rtx_realloc (
qse_awk_rtx_t* rtx, /**< runtime context */
void* ptr, /**< memory block */
qse_size_t size /**< block size in bytes */
);
/** /**
* The qse_awk_rtx_free() function frees a memory block pointed to by @a ptr * The qse_awk_rtx_free() function frees a memory block pointed to by @a ptr
* using the memory manager of a runtime ocntext @a rtx. * using the memory manager of a runtime ocntext @a rtx.

View File

@ -1,5 +1,5 @@
/* /*
* $Id: types.h 220 2009-07-01 13:14:39Z hyunghwan.chung $ * $Id: types.h 230 2009-07-13 08:51:23Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -70,24 +70,31 @@ typedef enum qse_tri_t qse_tri_t;
(QSE_SIZEOF_VOID_P == QSE_SIZEOF_LONG) (QSE_SIZEOF_VOID_P == QSE_SIZEOF_LONG)
typedef long qse_int_t; typedef long qse_int_t;
typedef unsigned long qse_uint_t; typedef unsigned long qse_uint_t;
#define QSE_SIZEOF_INT_T QSE_SIZEOF_LONG
#elif defined(__SPU__) && (QSE_SIZEOF_VOID_P == QSE_SIZEOF_LONG) #elif defined(__SPU__) && (QSE_SIZEOF_VOID_P == QSE_SIZEOF_LONG)
typedef long qse_int_t; typedef long qse_int_t;
typedef unsigned long qse_uint_t; typedef unsigned long qse_uint_t;
#define QSE_SIZEOF_INT_T QSE_SIZEOF_LONG
#elif QSE_SIZEOF_VOID_P == QSE_SIZEOF_INT #elif QSE_SIZEOF_VOID_P == QSE_SIZEOF_INT
typedef int qse_int_t; typedef int qse_int_t;
typedef unsigned int qse_uint_t; typedef unsigned int qse_uint_t;
#define QSE_SIZEOF_INT_T QSE_SIZEOF_INT
#elif QSE_SIZEOF_VOID_P == QSE_SIZEOF_LONG #elif QSE_SIZEOF_VOID_P == QSE_SIZEOF_LONG
typedef long qse_int_t; typedef long qse_int_t;
typedef unsigned long qse_uint_t; typedef unsigned long qse_uint_t;
#define QSE_SIZEOF_INT_T QSE_SIZEOF_LONG
#elif QSE_SIZEOF_VOID_P == QSE_SIZEOF_LONG_LONG #elif QSE_SIZEOF_VOID_P == QSE_SIZEOF_LONG_LONG
typedef long long qse_int_t; typedef long long qse_int_t;
typedef unsigned long long qse_uint_t; typedef unsigned long long qse_uint_t;
#define QSE_SIZEOF_INT_T QSE_SIZEOF_LONG_LONG
#elif QSE_SIZEOF_VOID_P == QSE_SIZEOF___INT32 #elif QSE_SIZEOF_VOID_P == QSE_SIZEOF___INT32
typedef __int32 qse_int_t; typedef __int32 qse_int_t;
typedef unsigned __int32 qse_uint_t; typedef unsigned __int32 qse_uint_t;
#define QSE_SIZEOF_INT_T QSE_SIZEOF___INT32
#elif QSE_SIZEOF_VOID_P == QSE_SIZEOF___INT64 #elif QSE_SIZEOF_VOID_P == QSE_SIZEOF___INT64
typedef __int64 qse_int_t; typedef __int64 qse_int_t;
typedef unsigned __int64 qse_uint_t; typedef unsigned __int64 qse_uint_t;
#define QSE_SIZEOF_INT_T QSE_SIZEOF___INT64
#else #else
# error unsupported pointer size # error unsupported pointer size
#endif #endif
@ -101,12 +108,15 @@ typedef enum qse_tri_t qse_tri_t;
#if QSE_SIZEOF_LONG_LONG > 0 #if QSE_SIZEOF_LONG_LONG > 0
typedef long long qse_long_t; typedef long long qse_long_t;
typedef unsigned long long qse_ulong_t; typedef unsigned long long qse_ulong_t;
#define QSE_SIZEOF_LONG_T QSE_SIZEOF_LONG_LONG
#elif QSE_SIZEOF___INT64 > 0 #elif QSE_SIZEOF___INT64 > 0
typedef __int64 qse_long_t; typedef __int64 qse_long_t;
typedef unsigned __int64 qse_ulong_t; typedef unsigned __int64 qse_ulong_t;
#define QSE_SIZEOF_LONG_T QSE_SIZEOF___INT64
#else #else
typedef long qse_long_t; typedef long qse_long_t;
typedef unsigned long qse_ulong_t; typedef unsigned long qse_ulong_t;
#define QSE_SIZEOF_LONG_T QSE_SIZEOF_LONG
#endif #endif
/** @typedef qse_int8_t /** @typedef qse_int8_t

View File

@ -1,5 +1,5 @@
/* /*
* $Id: Awk.cpp 229 2009-07-12 13:06:01Z hyunghwan.chung $ * $Id: Awk.cpp 230 2009-07-13 08:51:23Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -170,6 +170,51 @@ Awk::Console::Mode Awk::Console::getMode () const
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
const Awk::char_t* Awk::Value::EMPTY_STRING = QSE_T(""); const Awk::char_t* Awk::Value::EMPTY_STRING = QSE_T("");
Awk::Value::IndexIterator Awk::Value::IndexIterator::END;
Awk::Value::IntIndex::IntIndex (long_t x)
{
ptr = buf;
len = 0;
#define NTOC(n) ((n) + QSE_T('0'))
int base = 10;
long_t last = x % base;
long_t y = 0;
int dig = 0;
if (x < 0) buf[len++] = QSE_T('-');
x = x / base;
if (x < 0) x = -x;
while (x > 0)
{
y = y * base + (x % base);
x = x / base;
dig++;
}
while (y > 0)
{
buf[len++] = NTOC (y % base);
y = y / base;
dig--;
}
while (dig > 0)
{
dig--;
buf[len++] = QSE_T('0');
}
if (last < 0) last = -last;
buf[len++] = NTOC(last);
buf[len] = QSE_T('\0');
#undef NTOC
}
void* Awk::Value::operator new (size_t n, Run* run) throw () void* Awk::Value::operator new (size_t n, Run* run) throw ()
{ {
@ -326,7 +371,11 @@ int Awk::Value::getInt (long_t* v) const
{ {
real_t rv; real_t rv;
int n = qse_awk_rtx_valtonum (run->rtx, val, &lv, &rv); int n = qse_awk_rtx_valtonum (run->rtx, val, &lv, &rv);
if (n <= -1) return -1; if (n <= -1)
{
run->awk->retrieveError (run->rtx);
return -1;
}
if (n >= 1) lv = rv; if (n >= 1) lv = rv;
} }
@ -346,7 +395,11 @@ int Awk::Value::getReal (real_t* v) const
{ {
long_t lv; long_t lv;
int n = qse_awk_rtx_valtonum (run->rtx, val, &lv, &rv); int n = qse_awk_rtx_valtonum (run->rtx, val, &lv, &rv);
if (n <= -1) return -1; if (n <= -1)
{
run->awk->retrieveError (run->rtx);
return -1;
}
if (n == 0) rv = lv; if (n == 0) rv = lv;
} }
@ -379,6 +432,7 @@ int Awk::Value::getStr (const char_t** str, size_t* len) const
if (qse_awk_rtx_valtostr ( if (qse_awk_rtx_valtostr (
run->rtx, val, &out) == QSE_NULL) run->rtx, val, &out) == QSE_NULL)
{ {
run->awk->retrieveError (run->rtx);
return -1; return -1;
} }
@ -440,7 +494,11 @@ int Awk::Value::setInt (Run* r, long_t v)
{ {
val_t* tmp; val_t* tmp;
tmp = qse_awk_rtx_makeintval (r->rtx, v); tmp = qse_awk_rtx_makeintval (r->rtx, v);
if (tmp == QSE_NULL) return -1; if (tmp == QSE_NULL)
{
r->awk->retrieveError (r->rtx);
return -1;
}
int n = setVal (r, tmp); int n = setVal (r, tmp);
QSE_ASSERT (n == 0); QSE_ASSERT (n == 0);
@ -457,7 +515,11 @@ int Awk::Value::setReal (Run* r, real_t v)
{ {
val_t* tmp; val_t* tmp;
tmp = qse_awk_rtx_makerealval (r->rtx, v); tmp = qse_awk_rtx_makerealval (r->rtx, v);
if (tmp == QSE_NULL) return -1; if (tmp == QSE_NULL)
{
r->awk->retrieveError (r->rtx);
return -1;
}
int n = setVal (r, tmp); int n = setVal (r, tmp);
QSE_ASSERT (n == 0); QSE_ASSERT (n == 0);
@ -474,7 +536,11 @@ int Awk::Value::setStr (Run* r, const char_t* str, size_t len)
{ {
val_t* tmp; val_t* tmp;
tmp = qse_awk_rtx_makestrval (r->rtx, str, len); tmp = qse_awk_rtx_makestrval (r->rtx, str, len);
if (tmp == QSE_NULL) return -1; if (tmp == QSE_NULL)
{
r->awk->retrieveError (r->rtx);
return -1;
}
int n = setVal (r, tmp); int n = setVal (r, tmp);
QSE_ASSERT (n == 0); QSE_ASSERT (n == 0);
@ -491,27 +557,37 @@ int Awk::Value::setStr (Run* r, const char_t* str)
{ {
val_t* tmp; val_t* tmp;
tmp = qse_awk_rtx_makestrval0 (r->rtx, str); tmp = qse_awk_rtx_makestrval0 (r->rtx, str);
if (tmp == QSE_NULL) return -1; if (tmp == QSE_NULL)
{
r->awk->retrieveError (r->rtx);
return -1;
}
int n = setVal (r, tmp); int n = setVal (r, tmp);
QSE_ASSERT (n == 0); QSE_ASSERT (n == 0);
return n; return n;
} }
int Awk::Value::setIndexedVal (const char_t* idx, size_t isz, val_t* v) int Awk::Value::setIndexedVal (const Index& idx, val_t* v)
{ {
if (run == QSE_NULL) return -1; if (run == QSE_NULL) return -1;
return setIndexedVal (run, idx, isz, v); return setIndexedVal (run, idx, v);
} }
int Awk::Value::setIndexedVal (Run* r, const char_t* idx, size_t isz, val_t* v) int Awk::Value::setIndexedVal (Run* r, const Index& idx, val_t* v)
{ {
QSE_ASSERT (r != QSE_NULL);
if (val->type != QSE_AWK_VAL_MAP) if (val->type != QSE_AWK_VAL_MAP)
{ {
/* the previous value is not a map. /* the previous value is not a map.
* a new map value needs to be created first */ * a new map value needs to be created first */
val_t* map = qse_awk_rtx_makemapval (run->rtx); val_t* map = qse_awk_rtx_makemapval (r->rtx);
if (map == QSE_NULL) return -1; if (map == QSE_NULL)
{
r->awk->retrieveError (r->rtx);
return -1;
}
qse_awk_rtx_refupval (r->rtx, map); qse_awk_rtx_refupval (r->rtx, map);
qse_awk_rtx_refupval (r->rtx, v); qse_awk_rtx_refupval (r->rtx, v);
@ -519,12 +595,13 @@ int Awk::Value::setIndexedVal (Run* r, const char_t* idx, size_t isz, val_t* v)
/* update the map with a given value */ /* update the map with a given value */
pair_t* pair = qse_map_upsert ( pair_t* pair = qse_map_upsert (
((qse_awk_val_map_t*)map)->map, ((qse_awk_val_map_t*)map)->map,
(char_t*)idx, isz, v, 0); (char_t*)idx.ptr, idx.len, v, 0);
if (pair == QSE_NULL) if (pair == QSE_NULL)
{ {
qse_awk_rtx_refdownval (r->rtx, v); qse_awk_rtx_refdownval (r->rtx, v);
qse_awk_rtx_refdownval (r->rtx, map); qse_awk_rtx_refdownval (r->rtx, map);
run->setError (ERR_NOMEM, 0, QSE_NULL, 0); r->setError (ERR_NOMEM, 0, QSE_NULL, 0);
r->awk->retrieveError (r->rtx);
return -1; return -1;
} }
@ -545,6 +622,7 @@ int Awk::Value::setIndexedVal (Run* r, const char_t* idx, size_t isz, val_t* v)
{ {
// it can't span across multiple runtime contexts // it can't span across multiple runtime contexts
run->setError (ERR_INVAL); run->setError (ERR_INVAL);
run->awk->retrieveError (run->rtx);
return -1; return -1;
} }
@ -552,11 +630,12 @@ int Awk::Value::setIndexedVal (Run* r, const char_t* idx, size_t isz, val_t* v)
pair_t* pair = qse_map_upsert ( pair_t* pair = qse_map_upsert (
((qse_awk_val_map_t*)val)->map, ((qse_awk_val_map_t*)val)->map,
(char_t*)idx, isz, v, 0); (char_t*)idx.ptr, idx.len, v, 0);
if (pair == QSE_NULL) if (pair == QSE_NULL)
{ {
qse_awk_rtx_refdownval (r->rtx, v); qse_awk_rtx_refdownval (r->rtx, v);
run->setError (ERR_NOMEM); run->setError (ERR_NOMEM);
run->awk->retrieveError (run->rtx);
return -1; return -1;
} }
} }
@ -564,79 +643,94 @@ int Awk::Value::setIndexedVal (Run* r, const char_t* idx, size_t isz, val_t* v)
return 0; return 0;
} }
int Awk::Value::setIndexedInt (const char_t* idx, size_t isz, long_t v) int Awk::Value::setIndexedInt (const Index& idx, long_t v)
{ {
if (run == QSE_NULL) return -1; if (run == QSE_NULL) return -1;
return setIndexedInt (run, idx, isz, v); return setIndexedInt (run, idx, v);
} }
int Awk::Value::setIndexedInt (Run* r, const char_t* idx, size_t isz, long_t v) int Awk::Value::setIndexedInt (Run* r, const Index& idx, long_t v)
{ {
val_t* tmp; val_t* tmp;
tmp = qse_awk_rtx_makeintval (r->rtx, v); tmp = qse_awk_rtx_makeintval (r->rtx, v);
if (tmp == QSE_NULL) return -1; if (tmp == QSE_NULL)
{
r->awk->retrieveError (r->rtx);
return -1;
}
qse_awk_rtx_refupval (r->rtx, tmp); qse_awk_rtx_refupval (r->rtx, tmp);
int n = setIndexedVal (r, idx, isz, tmp); int n = setIndexedVal (r, idx, tmp);
qse_awk_rtx_refdownval (r->rtx, tmp); qse_awk_rtx_refdownval (r->rtx, tmp);
return n; return n;
} }
int Awk::Value::setIndexedReal (const char_t* idx, size_t isz, real_t v) int Awk::Value::setIndexedReal (const Index& idx, real_t v)
{ {
if (run == QSE_NULL) return -1; if (run == QSE_NULL) return -1;
return setIndexedReal (run, idx, isz, v); return setIndexedReal (run, idx, v);
} }
int Awk::Value::setIndexedReal (Run* r, const char_t* idx, size_t isz, real_t v) int Awk::Value::setIndexedReal (Run* r, const Index& idx, real_t v)
{ {
val_t* tmp; val_t* tmp;
tmp = qse_awk_rtx_makerealval (r->rtx, v); tmp = qse_awk_rtx_makerealval (r->rtx, v);
if (tmp == QSE_NULL) return -1; if (tmp == QSE_NULL)
{
r->awk->retrieveError (r->rtx);
return -1;
}
qse_awk_rtx_refupval (r->rtx, tmp); qse_awk_rtx_refupval (r->rtx, tmp);
int n = setIndexedVal (r, idx, isz, tmp); int n = setIndexedVal (r, idx, tmp);
qse_awk_rtx_refdownval (r->rtx, tmp); qse_awk_rtx_refdownval (r->rtx, tmp);
return n; return n;
} }
int Awk::Value::setIndexedStr (const char_t* idx, size_t isz, const char_t* str, size_t len) int Awk::Value::setIndexedStr (const Index& idx, const char_t* str, size_t len)
{ {
if (run == QSE_NULL) return -1; if (run == QSE_NULL) return -1;
return setIndexedStr (run, idx, isz, str, len); return setIndexedStr (run, idx, str, len);
} }
int Awk::Value::setIndexedStr ( int Awk::Value::setIndexedStr (
Run* r, const char_t* idx, size_t isz, const char_t* str, size_t len) Run* r, const Index& idx, const char_t* str, size_t len)
{ {
val_t* tmp; val_t* tmp;
tmp = qse_awk_rtx_makestrval (r->rtx, str, len); tmp = qse_awk_rtx_makestrval (r->rtx, str, len);
if (tmp == QSE_NULL) return -1; if (tmp == QSE_NULL)
{
r->awk->retrieveError (r->rtx);
return -1;
}
qse_awk_rtx_refupval (r->rtx, tmp); qse_awk_rtx_refupval (r->rtx, tmp);
int n = setIndexedVal (r, idx, isz, tmp); int n = setIndexedVal (r, idx, tmp);
qse_awk_rtx_refdownval (r->rtx, tmp); qse_awk_rtx_refdownval (r->rtx, tmp);
return n; return n;
} }
int Awk::Value::setIndexedStr (const char_t* idx, size_t isz, const char_t* str) int Awk::Value::setIndexedStr (const Index& idx, const char_t* str)
{ {
if (run == QSE_NULL) return -1; if (run == QSE_NULL) return -1;
return setIndexedStr (run, idx, isz, str); return setIndexedStr (run, idx, str);
} }
int Awk::Value::setIndexedStr ( int Awk::Value::setIndexedStr (Run* r, const Index& idx, const char_t* str)
Run* r, const char_t* idx, size_t isz, const char_t* str)
{ {
val_t* tmp; val_t* tmp;
tmp = qse_awk_rtx_makestrval0 (r->rtx, str); tmp = qse_awk_rtx_makestrval0 (r->rtx, str);
if (tmp == QSE_NULL) return -1; if (tmp == QSE_NULL)
{
r->awk->retrieveError (r->rtx);
return -1;
}
qse_awk_rtx_refupval (r->rtx, tmp); qse_awk_rtx_refupval (r->rtx, tmp);
int n = setIndexedVal (r, idx, isz, tmp); int n = setIndexedVal (r, idx, tmp);
qse_awk_rtx_refdownval (r->rtx, tmp); qse_awk_rtx_refdownval (r->rtx, tmp);
return n; return n;
@ -649,30 +743,68 @@ bool Awk::Value::isIndexed () const
return val->type == QSE_AWK_VAL_MAP; return val->type == QSE_AWK_VAL_MAP;
} }
int Awk::Value::getIndexed (const char_t* idx, size_t isz, Value& v) const int Awk::Value::getIndexed (const Index& idx, Value* v) const
{ {
QSE_ASSERT (val != QSE_NULL); QSE_ASSERT (val != QSE_NULL);
// not a map. v is just nil. not an error // not a map. v is just nil. not an error
if (val->type != QSE_AWK_VAL_MAP) if (val->type != QSE_AWK_VAL_MAP)
{ {
v.clear (); v->clear ();
return 0; return 0;
} }
// get the value from the map. // get the value from the map.
qse_awk_val_map_t* m = (qse_awk_val_map_t*)val; qse_awk_val_map_t* m = (qse_awk_val_map_t*)val;
pair_t* pair = qse_map_search (m->map, idx, isz); pair_t* pair = qse_map_search (m->map, idx.ptr, idx.len);
// the key is not found. it is not an error. v is just nil // the key is not found. it is not an error. v is just nil
if (pair == QSE_NULL) if (pair == QSE_NULL)
{ {
v.clear (); v->clear ();
return 0; return 0;
} }
// if v.set fails, it should return an error // if v.set fails, it should return an error
return v.setVal (run, (val_t*)QSE_MAP_VPTR(pair)); return v->setVal (run, (val_t*)QSE_MAP_VPTR(pair));
}
Awk::Value::IndexIterator Awk::Value::getFirstIndex (Index* idx) const
{
QSE_ASSERT (val != QSE_NULL);
if (val->type != QSE_AWK_VAL_MAP) return IndexIterator::END;
size_t buckno;
qse_awk_val_map_t* m = (qse_awk_val_map_t*)val;
pair_t* pair = qse_map_getfirstpair (m->map, &buckno);
if (pair == QSE_NULL) return IndexIterator::END; // no more key
idx->ptr = (const char_t*)QSE_MAP_KPTR(pair);
idx->len = QSE_MAP_KLEN(pair);
return IndexIterator (pair, buckno);
}
Awk::Value::IndexIterator Awk::Value::getNextIndex (
Index* idx, const IndexIterator& iter) const
{
QSE_ASSERT (val != QSE_NULL);
if (val->type != QSE_AWK_VAL_MAP) return IndexIterator::END;
qse_awk_val_map_t* m = (qse_awk_val_map_t*)val;
pair_t* pair = (pair_t*)iter.pair;
size_t buckno = iter.buckno;
pair = qse_map_getnextpair (m->map, pair, &buckno);
if (pair == QSE_NULL) return IndexIterator::END;
idx->ptr = (const char_t*)QSE_MAP_KPTR(pair);
idx->len = QSE_MAP_KLEN(pair);
return IndexIterator (pair, buckno);
} }
#if 0 #if 0
@ -724,35 +856,6 @@ int Awk::Argument::getNextIndex (Awk::Argument& val) const
return 1; return 1;
} }
int Awk::Return::setIndexed (long_t idx, real_t v)
{
if (this->run == QSE_NULL) return -1;
char_t ri[128];
int rl = Awk::sprintf (
(awk_t*)this->run->awk, ri, QSE_COUNTOF(ri),
#if QSE_SIZEOF_LONG_LONG > 0
QSE_T("%lld"), (long long)idx
#elif QSE_SIZEOF___INT64 > 0
QSE_T("%I64d"), (__int64)idx
#elif QSE_SIZEOF_LONG > 0
QSE_T("%ld"), (long)idx
#elif QSE_SIZEOF_INT > 0
QSE_T("%d"), (int)idx
#else
#error unsupported size
#endif
);
if (rl < 0)
{
this->run->setError (ERR_INTERN, 0, QSE_NULL, 0);
return -1;
}
return setIndexed (ri, rl, v);
}
#endif #endif
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
@ -1270,6 +1373,7 @@ int Awk::call (const char_t* name, Value* ret, const Value* args, size_t nargs)
if (ptr == QSE_NULL) if (ptr == QSE_NULL)
{ {
runctx.setError (ERR_NOMEM); runctx.setError (ERR_NOMEM);
retrieveError (runctx.rtx);
return -1; return -1;
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* $Id: misc.c 220 2009-07-01 13:14:39Z hyunghwan.chung $ * $Id: misc.c 230 2009-07-13 08:51:23Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -983,6 +983,11 @@ void* qse_awk_rtx_alloc (qse_awk_rtx_t* rtx, qse_size_t size)
return qse_awk_alloc (rtx->awk, size); return qse_awk_alloc (rtx->awk, size);
} }
void* qse_awk_rtx_realloc (qse_awk_rtx_t* rtx, void* ptr, qse_size_t size)
{
return qse_awk_realloc (rtx->awk, ptr, size);
}
void qse_awk_rtx_free (qse_awk_rtx_t* rtx, void* ptr) void qse_awk_rtx_free (qse_awk_rtx_t* rtx, void* ptr)
{ {
qse_awk_free (rtx->awk, ptr); qse_awk_free (rtx->awk, ptr);

View File

@ -1,5 +1,5 @@
/* /*
* $Id: run.c 228 2009-07-11 03:01:36Z hyunghwan.chung $ * $Id: run.c 230 2009-07-13 08:51:23Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -243,6 +243,9 @@ typedef qse_awk_val_t* (*binop_func_t) (
qse_awk_rtx_t* run, qse_awk_val_t* left, qse_awk_val_t* right); qse_awk_rtx_t* run, qse_awk_val_t* left, qse_awk_val_t* right);
typedef qse_awk_val_t* (*eval_expr_t) (qse_awk_rtx_t* run, qse_awk_nde_t* nde); typedef qse_awk_val_t* (*eval_expr_t) (qse_awk_rtx_t* run, qse_awk_nde_t* nde);
#ifdef NDEBUG
#define xstr_to_cstr(x) ((qse_cstr_t*)x)
#else
static qse_cstr_t* xstr_to_cstr (qse_xstr_t* xstr) static qse_cstr_t* xstr_to_cstr (qse_xstr_t* xstr)
{ {
/* i use this function to typecast qse_cstr_t* to /* i use this function to typecast qse_cstr_t* to
@ -252,6 +255,7 @@ static qse_cstr_t* xstr_to_cstr (qse_xstr_t* xstr)
* haved changed to something else. */ * haved changed to something else. */
return (qse_cstr_t*)xstr; return (qse_cstr_t*)xstr;
} }
#endif
qse_size_t qse_awk_rtx_getnargs (qse_awk_rtx_t* run) qse_size_t qse_awk_rtx_getnargs (qse_awk_rtx_t* run)
{ {
@ -3328,7 +3332,6 @@ static qse_awk_val_t* do_assignment (
goto exit_on_error; goto exit_on_error;
} }
ret = do_assignment_pos (run, (qse_awk_nde_pos_t*)var, val); ret = do_assignment_pos (run, (qse_awk_nde_pos_t*)var, val);
} }
else else

View File

@ -11,13 +11,15 @@ awk03_SOURCES = awk03.c
awk04_SOURCES = awk04.c awk04_SOURCES = awk04.c
if ENABLE_CXX if ENABLE_CXX
bin_PROGRAMS += awk05 awk06 awk07 bin_PROGRAMS += awk05 awk06 awk07 awk08
awk05_SOURCES = awk05.cpp awk05_SOURCES = awk05.cpp
awk06_SOURCES = awk06.cpp awk06_SOURCES = awk06.cpp
awk07_SOURCES = awk07.cpp awk07_SOURCES = awk07.cpp
awk08_SOURCES = awk08.cpp
awk05_LDADD = -lqseawk++ $(LDADD) awk05_LDADD = -lqseawk++ $(LDADD)
awk06_LDADD = -lqseawk++ $(LDADD) awk06_LDADD = -lqseawk++ $(LDADD)
awk07_LDADD = -lqseawk++ $(LDADD) awk07_LDADD = -lqseawk++ $(LDADD)
awk08_LDADD = -lqseawk++ $(LDADD)
endif endif

View File

@ -34,7 +34,7 @@ build_triplet = @build@
host_triplet = @host@ host_triplet = @host@
bin_PROGRAMS = awk01$(EXEEXT) awk02$(EXEEXT) awk03$(EXEEXT) \ bin_PROGRAMS = awk01$(EXEEXT) awk02$(EXEEXT) awk03$(EXEEXT) \
awk04$(EXEEXT) $(am__EXEEXT_1) awk04$(EXEEXT) $(am__EXEEXT_1)
@ENABLE_CXX_TRUE@am__append_1 = awk05 awk06 awk07 @ENABLE_CXX_TRUE@am__append_1 = awk05 awk06 awk07 awk08
subdir = samples/awk subdir = samples/awk
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@ -49,7 +49,7 @@ mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/include/qse/config.h CONFIG_HEADER = $(top_builddir)/include/qse/config.h
CONFIG_CLEAN_FILES = CONFIG_CLEAN_FILES =
@ENABLE_CXX_TRUE@am__EXEEXT_1 = awk05$(EXEEXT) awk06$(EXEEXT) \ @ENABLE_CXX_TRUE@am__EXEEXT_1 = awk05$(EXEEXT) awk06$(EXEEXT) \
@ENABLE_CXX_TRUE@ awk07$(EXEEXT) @ENABLE_CXX_TRUE@ awk07$(EXEEXT) awk08$(EXEEXT)
am__installdirs = "$(DESTDIR)$(bindir)" am__installdirs = "$(DESTDIR)$(bindir)"
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(bin_PROGRAMS) PROGRAMS = $(bin_PROGRAMS)
@ -83,6 +83,10 @@ am__awk07_SOURCES_DIST = awk07.cpp
@ENABLE_CXX_TRUE@am_awk07_OBJECTS = awk07.$(OBJEXT) @ENABLE_CXX_TRUE@am_awk07_OBJECTS = awk07.$(OBJEXT)
awk07_OBJECTS = $(am_awk07_OBJECTS) awk07_OBJECTS = $(am_awk07_OBJECTS)
@ENABLE_CXX_TRUE@awk07_DEPENDENCIES = $(am__DEPENDENCIES_2) @ENABLE_CXX_TRUE@awk07_DEPENDENCIES = $(am__DEPENDENCIES_2)
am__awk08_SOURCES_DIST = awk08.cpp
@ENABLE_CXX_TRUE@am_awk08_OBJECTS = awk08.$(OBJEXT)
awk08_OBJECTS = $(am_awk08_OBJECTS)
@ENABLE_CXX_TRUE@awk08_DEPENDENCIES = $(am__DEPENDENCIES_2)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/qse DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/qse
depcomp = $(SHELL) $(top_srcdir)/ac/au/depcomp depcomp = $(SHELL) $(top_srcdir)/ac/au/depcomp
am__depfiles_maybe = depfiles am__depfiles_maybe = depfiles
@ -106,10 +110,11 @@ CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
$(LDFLAGS) -o $@ $(LDFLAGS) -o $@
SOURCES = $(awk01_SOURCES) $(awk02_SOURCES) $(awk03_SOURCES) \ SOURCES = $(awk01_SOURCES) $(awk02_SOURCES) $(awk03_SOURCES) \
$(awk04_SOURCES) $(awk05_SOURCES) $(awk06_SOURCES) \ $(awk04_SOURCES) $(awk05_SOURCES) $(awk06_SOURCES) \
$(awk07_SOURCES) $(awk07_SOURCES) $(awk08_SOURCES)
DIST_SOURCES = $(awk01_SOURCES) $(awk02_SOURCES) $(awk03_SOURCES) \ DIST_SOURCES = $(awk01_SOURCES) $(awk02_SOURCES) $(awk03_SOURCES) \
$(awk04_SOURCES) $(am__awk05_SOURCES_DIST) \ $(awk04_SOURCES) $(am__awk05_SOURCES_DIST) \
$(am__awk06_SOURCES_DIST) $(am__awk07_SOURCES_DIST) $(am__awk06_SOURCES_DIST) $(am__awk07_SOURCES_DIST) \
$(am__awk08_SOURCES_DIST)
ETAGS = etags ETAGS = etags
CTAGS = ctags CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@ -258,9 +263,11 @@ awk04_SOURCES = awk04.c
@ENABLE_CXX_TRUE@awk05_SOURCES = awk05.cpp @ENABLE_CXX_TRUE@awk05_SOURCES = awk05.cpp
@ENABLE_CXX_TRUE@awk06_SOURCES = awk06.cpp @ENABLE_CXX_TRUE@awk06_SOURCES = awk06.cpp
@ENABLE_CXX_TRUE@awk07_SOURCES = awk07.cpp @ENABLE_CXX_TRUE@awk07_SOURCES = awk07.cpp
@ENABLE_CXX_TRUE@awk08_SOURCES = awk08.cpp
@ENABLE_CXX_TRUE@awk05_LDADD = -lqseawk++ $(LDADD) @ENABLE_CXX_TRUE@awk05_LDADD = -lqseawk++ $(LDADD)
@ENABLE_CXX_TRUE@awk06_LDADD = -lqseawk++ $(LDADD) @ENABLE_CXX_TRUE@awk06_LDADD = -lqseawk++ $(LDADD)
@ENABLE_CXX_TRUE@awk07_LDADD = -lqseawk++ $(LDADD) @ENABLE_CXX_TRUE@awk07_LDADD = -lqseawk++ $(LDADD)
@ENABLE_CXX_TRUE@awk08_LDADD = -lqseawk++ $(LDADD)
all: all-am all: all-am
.SUFFIXES: .SUFFIXES:
@ -343,6 +350,9 @@ awk06$(EXEEXT): $(awk06_OBJECTS) $(awk06_DEPENDENCIES)
awk07$(EXEEXT): $(awk07_OBJECTS) $(awk07_DEPENDENCIES) awk07$(EXEEXT): $(awk07_OBJECTS) $(awk07_DEPENDENCIES)
@rm -f awk07$(EXEEXT) @rm -f awk07$(EXEEXT)
$(CXXLINK) $(awk07_OBJECTS) $(awk07_LDADD) $(LIBS) $(CXXLINK) $(awk07_OBJECTS) $(awk07_LDADD) $(LIBS)
awk08$(EXEEXT): $(awk08_OBJECTS) $(awk08_DEPENDENCIES)
@rm -f awk08$(EXEEXT)
$(CXXLINK) $(awk08_OBJECTS) $(awk08_LDADD) $(LIBS)
mostlyclean-compile: mostlyclean-compile:
-rm -f *.$(OBJEXT) -rm -f *.$(OBJEXT)
@ -357,6 +367,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk05.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk05.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk06.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk06.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk07.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk07.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk08.Po@am__quote@
.c.o: .c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<

View File

@ -17,652 +17,103 @@
*/ */
#include <qse/awk/StdAwk.hpp> #include <qse/awk/StdAwk.hpp>
#include <qse/cmn/str.h>
#include <qse/cmn/stdio.h> #include <qse/cmn/stdio.h>
#include <qse/cmn/main.h> #include <qse/cmn/main.h>
#include <stdlib.h> static void print_error (unsigned long line, const qse_char_t* msg)
#include <math.h>
#if defined(_WIN32)
# include <windows.h>
#else
# include <unistd.h>
# include <signal.h>
# include <errno.h>
#endif
class MyAwk;
#ifdef _WIN32
static BOOL WINAPI stop_run (DWORD ctrl_type);
#else
static void stop_run (int sig);
#endif
static void set_intr_run (void);
static void unset_intr_run (void);
MyAwk* app_awk = QSE_NULL;
static bool verbose = false;
class MyAwk: public QSE::StdAwk
{ {
public: if (line > 0)
MyAwk (): srcInName(QSE_NULL), srcOutName(QSE_NULL) qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s at LINE %lu\n"), msg, line);
{
#ifdef _WIN32
heap = QSE_NULL;
#endif
}
~MyAwk ()
{
close ();
}
int open ()
{
#ifdef _WIN32
QSE_ASSERT (heap == QSE_NULL);
heap = ::HeapCreate (0, 1000000, 1000000);
if (heap == QSE_NULL) return -1;
#endif
int n = StdAwk::open ();
if (n <= -1)
{
#ifdef _WIN32
HeapDestroy (heap);
heap = QSE_NULL;
#endif
return -1;
}
idLastSleep = addGlobal (QSE_T("LAST_SLEEP"));
if (idLastSleep <= -1) goto failure;
if (addFunction (QSE_T("sleep"), 1, 1,
(FunctionHandler)&MyAwk::sleep) <= -1) goto failure;
if (addFunction (QSE_T("sumintarray"), 1, 1,
(FunctionHandler)&MyAwk::sumintarray) <= -1) goto failure;
if (addFunction (QSE_T("arrayindices"), 1, 1,
(FunctionHandler)&MyAwk::arrayindices) <= -1) goto failure;
return 0;
failure:
StdAwk::close ();
#ifdef _WIN32
HeapDestroy (heap);
heap = QSE_NULL;
#endif
return -1;
}
void close ()
{
StdAwk::close ();
#ifdef _WIN32
if (heap != QSE_NULL)
{
HeapDestroy (heap);
heap = QSE_NULL;
}
#endif
}
int sleep (Run& run, Return& ret, const Argument* args, size_t nargs,
const char_t* name, size_t len)
{
if (args[0].isIndexed())
{
run.setError (ERR_INVAL);
return -1;
}
long_t x = args[0].toInt();
/*Argument arg;
if (run.getGlobal(idLastSleep, arg) == 0)
qse_printf (QSE_T("GOOD: [%d]\n"), (int)arg.toInt());
else { qse_printf (QSE_T("BAD:\n")); }
*/
if (run.setGlobal (idLastSleep, x) <= -1) return -1;
#ifdef _WIN32
::Sleep ((DWORD)(x * 1000));
return ret.set ((long_t)0);
#else
return ret.set ((long_t)::sleep (x));
#endif
}
int sumintarray (Run& run, Return& ret, const Argument* args, size_t nargs,
const char_t* name, size_t len)
{
long_t x = 0;
if (args[0].isIndexed())
{
Argument idx(run), val(run);
int n = args[0].getFirstIndex (idx);
while (n > 0)
{
size_t len;
const char_t* ptr = idx.toStr(&len);
if (args[0].getIndexed(ptr, len, val) <= -1) return -1;
x += val.toInt ();
n = args[0].getNextIndex (idx);
}
if (n != 0) return -1;
}
else x += args[0].toInt();
return ret.set (x);
}
int arrayindices (Run& run, Return& ret, const Argument* args, size_t nargs,
const char_t* name, size_t len)
{
if (!args[0].isIndexed()) return 0;
Argument idx (run);
long_t i;
int n = args[0].getFirstIndex (idx);
for (i = 0; n > 0; i++)
{
size_t len;
const char_t* ptr = idx.toStr(&len);
n = args[0].getNextIndex (idx);
if (ret.setIndexed (i, ptr, len) <= -1) return -1;
}
if (n != 0) return -1;
return 0;
}
Run* parse (const char_t* in, const char_t* out)
{
srcInName = in;
srcOutName = out;
return StdAwk::parse ();
}
protected:
bool onLoopEnter (Run& run)
{
set_intr_run ();
return true;
}
void onLoopExit (Run& run, const Argument& ret)
{
unset_intr_run ();
if (verbose)
{
size_t len;
const char_t* ptr = ret.toStr (&len);
qse_printf (QSE_T("*** return [%.*s] ***\n"), (int)len, ptr);
}
}
int openSource (Source& io)
{
Source::Mode mode = io.getMode();
FILE* fp = QSE_NULL;
// TODO: use sio instead of stdio
if (mode == Source::READ)
{
if (srcInName == QSE_NULL)
{
io.setHandle (stdin);
return 0;
}
if (srcInName[0] == QSE_T('\0')) fp = stdin;
else fp = qse_fopen (srcInName, QSE_T("r"));
}
else if (mode == Source::WRITE)
{
if (srcOutName == QSE_NULL)
{
io.setHandle (stdout);
return 0;
}
if (srcOutName[0] == QSE_T('\0')) fp = stdout;
else fp = qse_fopen (srcOutName, QSE_T("w"));
}
if (fp == QSE_NULL) return -1;
io.setHandle (fp);
return 1;
}
int closeSource (Source& io)
{
FILE* fp = (FILE*)io.getHandle();
if (fp == stdout || fp == stderr) fflush (fp);
if (fp != stdin && fp != stdout && fp != stderr) fclose (fp);
io.setHandle (QSE_NULL);
return 0;
}
ssize_t readSource (Source& io, char_t* buf, size_t len)
{
FILE* fp = (FILE*)io.getHandle();
ssize_t n = 0;
while (n < (ssize_t)len)
{
qse_cint_t c = qse_fgetc (fp);
if (c == QSE_CHAR_EOF)
{
if (qse_ferror(fp)) n = -1;
break;
}
buf[n++] = c;
if (c == QSE_T('\n')) break;
}
return n;
}
ssize_t writeSource (Source& io, char_t* buf, size_t len)
{
FILE* fp = (FILE*)io.getHandle();
size_t left = len;
while (left > 0)
{
if (*buf == QSE_T('\0'))
{
if (qse_fputc(*buf,fp) == QSE_CHAR_EOF) return -1;
left -= 1; buf += 1;
}
else else
{
int chunk = (left > QSE_TYPE_MAX(int))? QSE_TYPE_MAX(int): (int)left;
int n = qse_fprintf (fp, QSE_T("%.*s"), chunk, buf);
if (n < 0 || n > chunk) return -1;
left -= n; buf += n;
}
}
return len;
}
void* allocMem (size_t n) throw ()
{
#ifdef _WIN32
return ::HeapAlloc (heap, 0, n);
#else
return ::malloc (n);
#endif
}
void* reallocMem (void* ptr, size_t n) throw ()
{
#ifdef _WIN32
if (ptr == NULL)
return ::HeapAlloc (heap, 0, n);
else
return ::HeapReAlloc (heap, 0, ptr, n);
#else
return ::realloc (ptr, n);
#endif
}
void freeMem (void* ptr) throw ()
{
#ifdef _WIN32
::HeapFree (heap, 0, ptr);
#else
::free (ptr);
#endif
}
private:
const char_t* srcInName;
const char_t* srcOutName;
int idLastSleep;
#ifdef _WIN32
void* heap;
#endif
};
#ifdef _WIN32
static BOOL WINAPI stop_run (DWORD ctrl_type)
{
if (ctrl_type == CTRL_C_EVENT ||
ctrl_type == CTRL_CLOSE_EVENT)
{
if (app_awk) app_awk->stop ();
return TRUE;
}
return FALSE;
}
#else
static int setsignal (int sig, void(*handler)(int), int restart)
{
struct sigaction sa_int;
sa_int.sa_handler = handler;
sigemptyset (&sa_int.sa_mask);
sa_int.sa_flags = 0;
if (restart)
{
#ifdef SA_RESTART
sa_int.sa_flags |= SA_RESTART;
#endif
}
else
{
#ifdef SA_INTERRUPT
sa_int.sa_flags |= SA_INTERRUPT;
#endif
}
return sigaction (sig, &sa_int, NULL);
}
static void stop_run (int sig)
{
int e = errno;
if (app_awk) app_awk->stop ();
errno = e;
}
#endif
static void set_intr_run (void)
{
#ifdef _WIN32
SetConsoleCtrlHandler (stop_run, TRUE);
#else
/*setsignal (SIGINT, stop_run, 1); TO BE MORE COMPATIBLE WITH WIN32*/
setsignal (SIGINT, stop_run, 0);
#endif
}
static void unset_intr_run (void)
{
#ifdef _WIN32
SetConsoleCtrlHandler (stop_run, FALSE);
#else
setsignal (SIGINT, SIG_DFL, 1);
#endif
}
static void print_error (const qse_char_t* msg)
{
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), msg); qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), msg);
} }
static struct static int run_awk (QSE::StdAwk& awk)
{ {
const qse_char_t* name; QSE::StdAwk::Run* run;
MyAwk::Option opt;
} otab[] =
{
{ QSE_T("implicit"), MyAwk::OPT_IMPLICIT },
{ QSE_T("explicit"), MyAwk::OPT_EXPLICIT },
{ QSE_T("bxor"), MyAwk::OPT_BXOR },
{ QSE_T("shift"), MyAwk::OPT_SHIFT },
{ QSE_T("idiv"), MyAwk::OPT_IDIV },
{ QSE_T("rio"), MyAwk::OPT_RIO },
{ QSE_T("rwpipe"), MyAwk::OPT_RWPIPE },
{ QSE_T("newline"), MyAwk::OPT_NEWLINE },
{ QSE_T("stripspaces"), MyAwk::OPT_STRIPSPACES },
{ QSE_T("nextofile"), MyAwk::OPT_NEXTOFILE },
{ QSE_T("crlf"), MyAwk::OPT_CRLF },
{ QSE_T("reset"), MyAwk::OPT_RESET },
{ QSE_T("maptovar"), MyAwk::OPT_MAPTOVAR },
{ QSE_T("pablock"), MyAwk::OPT_PABLOCK }
};
static void print_usage (const qse_char_t* argv0) const qse_char_t* script = QSE_T(
{ "function pa (x) {\n"
const qse_char_t* base; " reset ret;\n"
int j; " for (i in x) { print i, \"=>\", x[i]; ret += x[i]; }\n"
" return ret;\n"
"}\n"
"function pb (x) {\n"
" reset ret;\n"
" for (i in x) { ret[-i] = -x[i]; }\n"
" return ret;\n"
"}"
);
base = qse_strrchr(argv0, QSE_T('/')); QSE::StdAwk::SourceString in (script);
if (base == QSE_NULL) base = qse_strrchr(argv0, QSE_T('\\')); QSE::StdAwk::SourceFile out (QSE_T("awk07.out"));
if (base == QSE_NULL) base = argv0; else base++;
qse_printf (QSE_T("Usage: %s [-si file]? [-so file]? [-ci file]* [-co file]* [-w o:n]* \n"), base); // parse the script and deparse it to awk07.out
qse_printf (QSE_T(" -si file Specify the input source file\n")); run = awk.parse (&in, &out);
qse_printf (QSE_T(" The source code is read from stdin when it is not specified\n")); if (run == QSE_NULL) return -1;
qse_printf (QSE_T(" -so file Specify the output source file\n"));
qse_printf (QSE_T(" The deparsed code is not output when is it not specified\n"));
qse_printf (QSE_T(" -ci file Specify the input console file\n"));
qse_printf (QSE_T(" -co file Specify the output console file\n"));
qse_printf (QSE_T(" -w o:n Specify an old and new word pair\n"));
qse_printf (QSE_T(" o - an original word\n"));
qse_printf (QSE_T(" n - the new word to replace the original\n"));
qse_printf (QSE_T(" -v Print extra messages\n"));
QSE::StdAwk::Value arg[1];
qse_printf (QSE_T("\nYou may specify the following options to change the behavior of the interpreter.\n")); for (int i = 1; i <= 5; i++)
for (j = 0; j < (int)QSE_COUNTOF(otab); j++)
{ {
qse_printf (QSE_T(" -%-20s -no%-20s\n"), otab[j].name, otab[j].name); if (arg[0].setIndexedInt (
run, QSE::StdAwk::Value::IntIndex(i), i*20) <= -1) return -1;
} }
QSE::StdAwk::Value r;
// call the 'pa' function
if (awk.call (QSE_T("pa"), &r, arg, QSE_COUNTOF(arg)) <= -1) return -1;
// output the result in various types
qse_printf (QSE_T("RESULT: (int) [%lld]\n"), (long long)r.toInt());
qse_printf (QSE_T(" (real) [%Lf]\n"), (long double)r.toReal());
qse_printf (QSE_T(" (str) [%s]\n"), r.toStr(QSE_NULL));
// call the 'pb' function
if (awk.call (QSE_T("pb"), &r, arg, QSE_COUNTOF(arg)) <= -1) return -1;
// output the returned map.
QSE_ASSERT (r.isIndexed());
QSE::StdAwk::Value::IndexIterator iter;
QSE::StdAwk::Value::Index idx;
QSE::StdAwk::Value v;
qse_printf (QSE_T("RESULT:\n"));
iter = r.getFirstIndex (&idx);
while (iter != QSE::StdAwk::Value::IndexIterator::END)
{
if (r.getIndexed (idx, &v) <= -1) return -1;
qse_printf (QSE_T("\t[%.*s]=>[%lld]\n"),
(int)idx.len, idx.ptr, (long long)v.toInt());
iter = r.getNextIndex (&idx, iter);
}
return 0;
} }
static int awk_main (int argc, qse_char_t* argv[]) static int awk_main (int argc, qse_char_t* argv[])
{ {
MyAwk awk; QSE::StdAwk awk;
MyAwk::Run* run;
int mode = 0; int ret = awk.open();
const qse_char_t* srcin = QSE_T("");
const qse_char_t* srcout = NULL;
qse_size_t nsrcins = 0;
qse_size_t nsrcouts = 0;
if (awk.open() <= -1) // allow returning a map from a function and enable 'reset'
{ awk.setOption (
print_error (awk.getErrorMessage()); awk.getOption() |
return -1; QSE::StdAwk::OPT_MAPTOVAR |
} QSE::StdAwk::OPT_RESET);
if (ret >= 0) ret = run_awk (awk);
if (ret <= -1) print_error (awk.getErrorLine(), awk.getErrorMessage());
// ARGV[0]
if (awk.addArgument (QSE_T("awk05")) <= -1)
{
print_error (awk.getErrorMessage());
awk.close (); awk.close ();
return -1; return -1;
}
for (int i = 1; i < argc; i++)
{
if (mode == 0)
{
if (qse_strcmp(argv[i], QSE_T("-si")) == 0) mode = 1;
else if (qse_strcmp(argv[i], QSE_T("-so")) == 0) mode = 2;
else if (qse_strcmp(argv[i], QSE_T("-ci")) == 0) mode = 3;
else if (qse_strcmp(argv[i], QSE_T("-co")) == 0) mode = 4;
else if (qse_strcmp(argv[i], QSE_T("-w")) == 0) mode = 5;
else if (qse_strcmp(argv[i], QSE_T("-v")) == 0)
{
verbose = true;
}
else
{
if (argv[i][0] == QSE_T('-'))
{
int j;
if (argv[i][1] == QSE_T('n') && argv[i][2] == QSE_T('o'))
{
for (j = 0; j < (int)QSE_COUNTOF(otab); j++)
{
if (qse_strcmp(&argv[i][3], otab[j].name) == 0)
{
awk.setOption (awk.getOption() & ~otab[j].opt);
goto ok_valid;
}
}
}
else
{
for (j = 0; j < (int)QSE_COUNTOF(otab); j++)
{
if (qse_strcmp(&argv[i][1], otab[j].name) == 0)
{
awk.setOption (awk.getOption() | otab[j].opt);
goto ok_valid;
}
}
}
}
print_usage (argv[0]);
return -1;
ok_valid:
;
}
}
else
{
if (argv[i][0] == QSE_T('-'))
{
print_usage (argv[0]);
return -1;
}
if (mode == 1) // source input
{
if (nsrcins != 0)
{
print_usage (argv[0]);
return -1;
}
srcin = argv[i];
nsrcins++;
mode = 0;
}
else if (mode == 2) // source output
{
if (nsrcouts != 0)
{
print_usage (argv[0]);
return -1;
}
srcout = argv[i];
nsrcouts++;
mode = 0;
}
else if (mode == 3) // console input
{
if (awk.addArgument (argv[i]) <= -1)
{
print_error (QSE_T("too many console inputs"));
return -1;
}
mode = 0;
}
else if (mode == 4) // console output
{
if (awk.addConsoleOutput (argv[i]) <= -1)
{
print_error (QSE_T("too many console outputs"));
return -1;
}
mode = 0;
}
else if (mode == 5) // word replacement
{
const qse_char_t* p;
qse_size_t l;
p = qse_strchr(argv[i], QSE_T(':'));
if (p == QSE_NULL)
{
print_usage (argv[0]);
return -1;
}
l = qse_strlen (argv[i]);
awk.setWord (
argv[i], p - argv[i],
p + 1, l - (p - argv[i] + 1));
mode = 0;
}
}
}
if (mode != 0)
{
print_usage (argv[0]);
awk.close ();
return -1;
}
run = awk.parse (srcin, srcout);
if (run == QSE_NULL)
{
qse_fprintf (stderr, QSE_T("cannot parse: LINE[%d] %s\n"),
awk.getErrorLine(), awk.getErrorMessage());
awk.close ();
return -1;
}
awk.enableRunCallback ();
app_awk = &awk;
if (awk.loop () <= -1)
{
qse_fprintf (stderr, QSE_T("cannot run: LINE[%d] %s\n"),
awk.getErrorLine(), awk.getErrorMessage());
awk.close ();
return -1;
}
#if 0
MyAwk::Return args[2];
args[0].setRun (run);
args[1].setRun (run);
if (awk.call (QSE_T("add"), args, 2) <= -1)
{
qse_fprintf (stderr, QSE_T("cannot run: LINE[%d] %s\n"),
awk.getErrorLine(), awk.getErrorMessage());
awk.close ();
}
#endif
app_awk = QSE_NULL;
awk.close ();
return 0;
} }
int qse_main (int argc, qse_achar_t* argv[]) int qse_main (int argc, qse_achar_t* argv[])

671
qse/samples/awk/awk08.cpp Normal file
View File

@ -0,0 +1,671 @@
/*
* $Id: Awk.cpp 341 2008-08-20 10:58:19Z baconevi $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <qse/awk/StdAwk.hpp>
#include <qse/cmn/str.h>
#include <qse/cmn/stdio.h>
#include <qse/cmn/main.h>
#include <stdlib.h>
#include <math.h>
#if defined(_WIN32)
# include <windows.h>
#else
# include <unistd.h>
# include <signal.h>
# include <errno.h>
#endif
class MyAwk;
#ifdef _WIN32
static BOOL WINAPI stop_run (DWORD ctrl_type);
#else
static void stop_run (int sig);
#endif
static void set_intr_run (void);
static void unset_intr_run (void);
MyAwk* app_awk = QSE_NULL;
static bool verbose = false;
class MyAwk: public QSE::StdAwk
{
public:
MyAwk (): srcInName(QSE_NULL), srcOutName(QSE_NULL)
{
#ifdef _WIN32
heap = QSE_NULL;
#endif
}
~MyAwk ()
{
close ();
}
int open ()
{
#ifdef _WIN32
QSE_ASSERT (heap == QSE_NULL);
heap = ::HeapCreate (0, 1000000, 1000000);
if (heap == QSE_NULL) return -1;
#endif
int n = StdAwk::open ();
if (n <= -1)
{
#ifdef _WIN32
HeapDestroy (heap);
heap = QSE_NULL;
#endif
return -1;
}
idLastSleep = addGlobal (QSE_T("LAST_SLEEP"));
if (idLastSleep <= -1) goto failure;
if (addFunction (QSE_T("sleep"), 1, 1,
(FunctionHandler)&MyAwk::sleep) <= -1) goto failure;
if (addFunction (QSE_T("sumintarray"), 1, 1,
(FunctionHandler)&MyAwk::sumintarray) <= -1) goto failure;
if (addFunction (QSE_T("arrayindices"), 1, 1,
(FunctionHandler)&MyAwk::arrayindices) <= -1) goto failure;
return 0;
failure:
StdAwk::close ();
#ifdef _WIN32
HeapDestroy (heap);
heap = QSE_NULL;
#endif
return -1;
}
void close ()
{
StdAwk::close ();
#ifdef _WIN32
if (heap != QSE_NULL)
{
HeapDestroy (heap);
heap = QSE_NULL;
}
#endif
}
int sleep (Run& run, Return& ret, const Argument* args, size_t nargs,
const char_t* name, size_t len)
{
if (args[0].isIndexed())
{
run.setError (ERR_INVAL);
return -1;
}
long_t x = args[0].toInt();
/*Argument arg;
if (run.getGlobal(idLastSleep, arg) == 0)
qse_printf (QSE_T("GOOD: [%d]\n"), (int)arg.toInt());
else { qse_printf (QSE_T("BAD:\n")); }
*/
if (run.setGlobal (idLastSleep, x) <= -1) return -1;
#ifdef _WIN32
::Sleep ((DWORD)(x * 1000));
return ret.set ((long_t)0);
#else
return ret.set ((long_t)::sleep (x));
#endif
}
int sumintarray (Run& run, Return& ret, const Argument* args, size_t nargs,
const char_t* name, size_t len)
{
long_t x = 0;
if (args[0].isIndexed())
{
Argument idx(run), val(run);
int n = args[0].getFirstIndex (idx);
while (n > 0)
{
size_t len;
const char_t* ptr = idx.toStr(&len);
if (args[0].getIndexed(ptr, len, val) <= -1) return -1;
x += val.toInt ();
n = args[0].getNextIndex (idx);
}
if (n != 0) return -1;
}
else x += args[0].toInt();
return ret.set (x);
}
int arrayindices (Run& run, Return& ret, const Argument* args, size_t nargs,
const char_t* name, size_t len)
{
if (!args[0].isIndexed()) return 0;
Argument idx (run);
long_t i;
int n = args[0].getFirstIndex (idx);
for (i = 0; n > 0; i++)
{
size_t len;
const char_t* ptr = idx.toStr(&len);
n = args[0].getNextIndex (idx);
if (ret.setIndexed (i, ptr, len) <= -1) return -1;
}
if (n != 0) return -1;
return 0;
}
Run* parse (const char_t* in, const char_t* out)
{
srcInName = in;
srcOutName = out;
return StdAwk::parse ();
}
protected:
bool onLoopEnter (Run& run)
{
set_intr_run ();
return true;
}
void onLoopExit (Run& run, const Argument& ret)
{
unset_intr_run ();
if (verbose)
{
size_t len;
const char_t* ptr = ret.toStr (&len);
qse_printf (QSE_T("*** return [%.*s] ***\n"), (int)len, ptr);
}
}
int openSource (Source& io)
{
Source::Mode mode = io.getMode();
FILE* fp = QSE_NULL;
// TODO: use sio instead of stdio
if (mode == Source::READ)
{
if (srcInName == QSE_NULL)
{
io.setHandle (stdin);
return 0;
}
if (srcInName[0] == QSE_T('\0')) fp = stdin;
else fp = qse_fopen (srcInName, QSE_T("r"));
}
else if (mode == Source::WRITE)
{
if (srcOutName == QSE_NULL)
{
io.setHandle (stdout);
return 0;
}
if (srcOutName[0] == QSE_T('\0')) fp = stdout;
else fp = qse_fopen (srcOutName, QSE_T("w"));
}
if (fp == QSE_NULL) return -1;
io.setHandle (fp);
return 1;
}
int closeSource (Source& io)
{
FILE* fp = (FILE*)io.getHandle();
if (fp == stdout || fp == stderr) fflush (fp);
if (fp != stdin && fp != stdout && fp != stderr) fclose (fp);
io.setHandle (QSE_NULL);
return 0;
}
ssize_t readSource (Source& io, char_t* buf, size_t len)
{
FILE* fp = (FILE*)io.getHandle();
ssize_t n = 0;
while (n < (ssize_t)len)
{
qse_cint_t c = qse_fgetc (fp);
if (c == QSE_CHAR_EOF)
{
if (qse_ferror(fp)) n = -1;
break;
}
buf[n++] = c;
if (c == QSE_T('\n')) break;
}
return n;
}
ssize_t writeSource (Source& io, char_t* buf, size_t len)
{
FILE* fp = (FILE*)io.getHandle();
size_t left = len;
while (left > 0)
{
if (*buf == QSE_T('\0'))
{
if (qse_fputc(*buf,fp) == QSE_CHAR_EOF) return -1;
left -= 1; buf += 1;
}
else
{
int chunk = (left > QSE_TYPE_MAX(int))? QSE_TYPE_MAX(int): (int)left;
int n = qse_fprintf (fp, QSE_T("%.*s"), chunk, buf);
if (n < 0 || n > chunk) return -1;
left -= n; buf += n;
}
}
return len;
}
void* allocMem (size_t n) throw ()
{
#ifdef _WIN32
return ::HeapAlloc (heap, 0, n);
#else
return ::malloc (n);
#endif
}
void* reallocMem (void* ptr, size_t n) throw ()
{
#ifdef _WIN32
if (ptr == NULL)
return ::HeapAlloc (heap, 0, n);
else
return ::HeapReAlloc (heap, 0, ptr, n);
#else
return ::realloc (ptr, n);
#endif
}
void freeMem (void* ptr) throw ()
{
#ifdef _WIN32
::HeapFree (heap, 0, ptr);
#else
::free (ptr);
#endif
}
private:
const char_t* srcInName;
const char_t* srcOutName;
int idLastSleep;
#ifdef _WIN32
void* heap;
#endif
};
#ifdef _WIN32
static BOOL WINAPI stop_run (DWORD ctrl_type)
{
if (ctrl_type == CTRL_C_EVENT ||
ctrl_type == CTRL_CLOSE_EVENT)
{
if (app_awk) app_awk->stop ();
return TRUE;
}
return FALSE;
}
#else
static int setsignal (int sig, void(*handler)(int), int restart)
{
struct sigaction sa_int;
sa_int.sa_handler = handler;
sigemptyset (&sa_int.sa_mask);
sa_int.sa_flags = 0;
if (restart)
{
#ifdef SA_RESTART
sa_int.sa_flags |= SA_RESTART;
#endif
}
else
{
#ifdef SA_INTERRUPT
sa_int.sa_flags |= SA_INTERRUPT;
#endif
}
return sigaction (sig, &sa_int, NULL);
}
static void stop_run (int sig)
{
int e = errno;
if (app_awk) app_awk->stop ();
errno = e;
}
#endif
static void set_intr_run (void)
{
#ifdef _WIN32
SetConsoleCtrlHandler (stop_run, TRUE);
#else
/*setsignal (SIGINT, stop_run, 1); TO BE MORE COMPATIBLE WITH WIN32*/
setsignal (SIGINT, stop_run, 0);
#endif
}
static void unset_intr_run (void)
{
#ifdef _WIN32
SetConsoleCtrlHandler (stop_run, FALSE);
#else
setsignal (SIGINT, SIG_DFL, 1);
#endif
}
static void print_error (const qse_char_t* msg)
{
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), msg);
}
static struct
{
const qse_char_t* name;
MyAwk::Option opt;
} otab[] =
{
{ QSE_T("implicit"), MyAwk::OPT_IMPLICIT },
{ QSE_T("explicit"), MyAwk::OPT_EXPLICIT },
{ QSE_T("bxor"), MyAwk::OPT_BXOR },
{ QSE_T("shift"), MyAwk::OPT_SHIFT },
{ QSE_T("idiv"), MyAwk::OPT_IDIV },
{ QSE_T("rio"), MyAwk::OPT_RIO },
{ QSE_T("rwpipe"), MyAwk::OPT_RWPIPE },
{ QSE_T("newline"), MyAwk::OPT_NEWLINE },
{ QSE_T("stripspaces"), MyAwk::OPT_STRIPSPACES },
{ QSE_T("nextofile"), MyAwk::OPT_NEXTOFILE },
{ QSE_T("crlf"), MyAwk::OPT_CRLF },
{ QSE_T("reset"), MyAwk::OPT_RESET },
{ QSE_T("maptovar"), MyAwk::OPT_MAPTOVAR },
{ QSE_T("pablock"), MyAwk::OPT_PABLOCK }
};
static void print_usage (const qse_char_t* argv0)
{
const qse_char_t* base;
int j;
base = qse_strrchr(argv0, QSE_T('/'));
if (base == QSE_NULL) base = qse_strrchr(argv0, QSE_T('\\'));
if (base == QSE_NULL) base = argv0; else base++;
qse_printf (QSE_T("Usage: %s [-si file]? [-so file]? [-ci file]* [-co file]* [-w o:n]* \n"), base);
qse_printf (QSE_T(" -si file Specify the input source file\n"));
qse_printf (QSE_T(" The source code is read from stdin when it is not specified\n"));
qse_printf (QSE_T(" -so file Specify the output source file\n"));
qse_printf (QSE_T(" The deparsed code is not output when is it not specified\n"));
qse_printf (QSE_T(" -ci file Specify the input console file\n"));
qse_printf (QSE_T(" -co file Specify the output console file\n"));
qse_printf (QSE_T(" -w o:n Specify an old and new word pair\n"));
qse_printf (QSE_T(" o - an original word\n"));
qse_printf (QSE_T(" n - the new word to replace the original\n"));
qse_printf (QSE_T(" -v Print extra messages\n"));
qse_printf (QSE_T("\nYou may specify the following options to change the behavior of the interpreter.\n"));
for (j = 0; j < (int)QSE_COUNTOF(otab); j++)
{
qse_printf (QSE_T(" -%-20s -no%-20s\n"), otab[j].name, otab[j].name);
}
}
static int awk_main (int argc, qse_char_t* argv[])
{
MyAwk awk;
MyAwk::Run* run;
int mode = 0;
const qse_char_t* srcin = QSE_T("");
const qse_char_t* srcout = NULL;
qse_size_t nsrcins = 0;
qse_size_t nsrcouts = 0;
if (awk.open() <= -1)
{
print_error (awk.getErrorMessage());
return -1;
}
// ARGV[0]
if (awk.addArgument (QSE_T("awk05")) <= -1)
{
print_error (awk.getErrorMessage());
awk.close ();
return -1;
}
for (int i = 1; i < argc; i++)
{
if (mode == 0)
{
if (qse_strcmp(argv[i], QSE_T("-si")) == 0) mode = 1;
else if (qse_strcmp(argv[i], QSE_T("-so")) == 0) mode = 2;
else if (qse_strcmp(argv[i], QSE_T("-ci")) == 0) mode = 3;
else if (qse_strcmp(argv[i], QSE_T("-co")) == 0) mode = 4;
else if (qse_strcmp(argv[i], QSE_T("-w")) == 0) mode = 5;
else if (qse_strcmp(argv[i], QSE_T("-v")) == 0)
{
verbose = true;
}
else
{
if (argv[i][0] == QSE_T('-'))
{
int j;
if (argv[i][1] == QSE_T('n') && argv[i][2] == QSE_T('o'))
{
for (j = 0; j < (int)QSE_COUNTOF(otab); j++)
{
if (qse_strcmp(&argv[i][3], otab[j].name) == 0)
{
awk.setOption (awk.getOption() & ~otab[j].opt);
goto ok_valid;
}
}
}
else
{
for (j = 0; j < (int)QSE_COUNTOF(otab); j++)
{
if (qse_strcmp(&argv[i][1], otab[j].name) == 0)
{
awk.setOption (awk.getOption() | otab[j].opt);
goto ok_valid;
}
}
}
}
print_usage (argv[0]);
return -1;
ok_valid:
;
}
}
else
{
if (argv[i][0] == QSE_T('-'))
{
print_usage (argv[0]);
return -1;
}
if (mode == 1) // source input
{
if (nsrcins != 0)
{
print_usage (argv[0]);
return -1;
}
srcin = argv[i];
nsrcins++;
mode = 0;
}
else if (mode == 2) // source output
{
if (nsrcouts != 0)
{
print_usage (argv[0]);
return -1;
}
srcout = argv[i];
nsrcouts++;
mode = 0;
}
else if (mode == 3) // console input
{
if (awk.addArgument (argv[i]) <= -1)
{
print_error (QSE_T("too many console inputs"));
return -1;
}
mode = 0;
}
else if (mode == 4) // console output
{
if (awk.addConsoleOutput (argv[i]) <= -1)
{
print_error (QSE_T("too many console outputs"));
return -1;
}
mode = 0;
}
else if (mode == 5) // word replacement
{
const qse_char_t* p;
qse_size_t l;
p = qse_strchr(argv[i], QSE_T(':'));
if (p == QSE_NULL)
{
print_usage (argv[0]);
return -1;
}
l = qse_strlen (argv[i]);
awk.setWord (
argv[i], p - argv[i],
p + 1, l - (p - argv[i] + 1));
mode = 0;
}
}
}
if (mode != 0)
{
print_usage (argv[0]);
awk.close ();
return -1;
}
run = awk.parse (srcin, srcout);
if (run == QSE_NULL)
{
qse_fprintf (stderr, QSE_T("cannot parse: LINE[%d] %s\n"),
awk.getErrorLine(), awk.getErrorMessage());
awk.close ();
return -1;
}
awk.enableRunCallback ();
app_awk = &awk;
if (awk.loop () <= -1)
{
qse_fprintf (stderr, QSE_T("cannot run: LINE[%d] %s\n"),
awk.getErrorLine(), awk.getErrorMessage());
awk.close ();
return -1;
}
#if 0
MyAwk::Return args[2];
args[0].setRun (run);
args[1].setRun (run);
if (awk.call (QSE_T("add"), args, 2) <= -1)
{
qse_fprintf (stderr, QSE_T("cannot run: LINE[%d] %s\n"),
awk.getErrorLine(), awk.getErrorMessage());
awk.close ();
}
#endif
app_awk = QSE_NULL;
awk.close ();
return 0;
}
int qse_main (int argc, qse_achar_t* argv[])
{
return qse_runmain (argc,argv,awk_main);
}