aboutsummaryrefslogtreecommitdiff
path: root/project/dclib/dclib-basics.h
diff options
context:
space:
mode:
authorWiimm <wiimm@wiimm.de>2021-04-07 11:00:18 +0200
committerWiimm <wiimm@wiimm.de>2021-04-07 11:00:18 +0200
commit9ccd762ee98823e8de27e294ce8b63e3eb8f2f9b (patch)
treeae586b532aa92608ba963cfd11f4987c582ef4a1 /project/dclib/dclib-basics.h
parenta9415225000b204931f04d602f81780e1d3f06c4 (diff)
SZS 2.24a
Diffstat (limited to '')
-rw-r--r--project/dclib/dclib-basics.h394
1 files changed, 341 insertions, 53 deletions
diff --git a/project/dclib/dclib-basics.h b/project/dclib/dclib-basics.h
index c5395f6..5412d52 100644
--- a/project/dclib/dclib-basics.h
+++ b/project/dclib/dclib-basics.h
@@ -629,6 +629,40 @@ uint GetTextBOMLen ( const void * data, uint data_size );
//
///////////////////////////////////////////////////////////////////////////////
+/////////////// CopyMode_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[CopyMode_t]]
+
+typedef enum CopyMode_t
+{
+ CPM_COPY, // make a copy of the data, alloced
+ CPM_MOVE, // move the alloced data
+ CPM_LINK, // link the data
+
+} CopyMode_t;
+
+///////////////////////////////////////////////////////////////////////////////
+
+void * CopyData
+(
+ const void *data, // data to copy/move/link
+ uint size, // size of 'data'
+ CopyMode_t mode, // copy mode
+ bool *res_alloced // not NULL:
+ // store true, if data must be freed
+ // otherwise store false
+);
+
+///////////////////////////////////////////////////////////////////////////////
+
+void FreeData
+(
+ const void *data, // data to free
+ CopyMode_t mode // copy mode
+);
+
+//
+///////////////////////////////////////////////////////////////////////////////
/////////////// struct mem_t ///////////////
///////////////////////////////////////////////////////////////////////////////
// [[mem_t]]
@@ -640,8 +674,8 @@ typedef struct mem_t
}
mem_t;
-extern mem_t EmptyMem; // mem_t(EmptyString,0)
-extern mem_t NullMem; // mem_t(0,0)
+extern mem_t EmptyMem; // mem_t(EmptyString,0)
+extern mem_t NullMem; // mem_t(0,0)
//-----------------------------------------------------------------------------
@@ -651,6 +685,7 @@ static inline mem_t MemByChar ( char ch )
return mem;
}
+// NULL allowed
static inline mem_t MemByString0 ( ccp str )
{
if (!str)
@@ -660,18 +695,21 @@ static inline mem_t MemByString0 ( ccp str )
return mem;
}
+// NULL forbidden
static inline mem_t MemByString ( ccp str )
{
mem_t mem = { str, strlen(str) };
return mem;
}
+// NULL forbidden if len<0
static inline mem_t MemByStringS ( ccp str, int len )
{
mem_t mem = { str, len < 0 ? strlen(str) : len };
return mem;
}
+// NULL forbidden if end=0
static inline mem_t MemByStringE ( ccp str, ccp end )
{
mem_t mem = { str, end ? end-str : strlen(str) };
@@ -792,6 +830,103 @@ static inline char * DupStrMem ( const mem_t src )
//
///////////////////////////////////////////////////////////////////////////////
+/////////////// struct exmem_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[exmem_t]]
+
+typedef struct exmem_t
+{
+ mem_t data; // pointer and size of data
+ u32 attrib; // user defined attribute
+ bool is_original; // true: 'data' is a copy of source
+ bool is_circ_buf; // true: 'data' is part of circ-buf
+ bool is_alloced; // true: 'data' is alloced (not circ-buf)
+ bool is_key_alloced; // true: external key is alloced
+}
+exmem_t;
+
+extern exmem_t EmptyExMem; // mem_t(EmptyString,0),false,false
+extern exmem_t NullExMem; // mem_t(0,0),false,false
+
+//-----------------------------------------------------------------------------
+// constructors
+
+static inline exmem_t ExMemByChar ( char ch )
+{
+ exmem_t em = { .data={ &ch, 1 }, .is_original=true };
+ return em;
+}
+
+static inline exmem_t ExMemByString0 ( ccp str )
+{
+ if (!str)
+ return NullExMem;
+
+ exmem_t em = { .data={ str, strlen(str) }, .is_original=true };
+ return em;
+}
+
+static inline exmem_t ExMemByString ( ccp str )
+{
+ exmem_t em = { .data={ str, str ? strlen(str) : 0 }, .is_original=true };
+ return em;
+}
+
+static inline exmem_t ExMemByStringS ( ccp str, int len )
+{
+ exmem_t em = { .data={ str, !str ? 0 : len < 0 ? strlen(str) : len }, .is_original=true };
+ return em;
+}
+
+static inline exmem_t ExMemByStringE ( ccp str, ccp end )
+{
+ exmem_t em = { .data={ str, !str ? 0 : end ? end-str : strlen(str) }, .is_original=true };
+ return em;
+}
+
+static inline exmem_t ExMemByS ( ccp str, int len )
+{
+ exmem_t em = { .data={ str, len }, .is_original=true };
+ return em;
+}
+
+static inline exmem_t ExMemByE ( ccp str, ccp end )
+{
+ exmem_t em = { .data={ str, end-str }, .is_original=true };
+ return em;
+}
+
+//-----------------------------------------------------------------------------
+// interface
+
+// 'em' maybe modified ignoring 'const'
+void FreeExMem ( const exmem_t *em );
+void FreeExMemCM ( const exmem_t *em, CopyMode_t copy_mode ); // free if CPM_MOVE
+
+exmem_t AllocExMemS
+(
+ cvp src, // NULL or source
+ int src_len, // len of 'src'; if -1: use strlen(source)
+ bool try_circ, // use circ-buffer, if result is small enough
+ cvp orig, // NULL or data to compare
+ int orig_len // len of 'orig'; if -1: use strlen(source)
+);
+
+static inline exmem_t AllocExMemM ( mem_t src, bool try_circ, mem_t orig )
+ { return AllocExMemS(src.ptr,src.len,try_circ,orig.ptr,orig.len); }
+
+void AssignExMem ( exmem_t *dest, const exmem_t *source, CopyMode_t copy_mode );
+static inline exmem_t CopyExMem ( const exmem_t *source, CopyMode_t copy_mode )
+ { exmem_t em = {{0}}; AssignExMem(&em,source,copy_mode); return em; }
+
+exmem_t CopyExMemS ( ccp string, int slen, CopyMode_t copy_mode );
+static inline exmem_t CopyExMemM ( const mem_t source, CopyMode_t copy_mode )
+ { return CopyExMemS(source.ptr,source.len,copy_mode); }
+
+ccp PrintExMem ( const exmem_t * em ); // print to circ-buf
+
+//
+///////////////////////////////////////////////////////////////////////////////
/////////////// struct mem_list_t ///////////////
///////////////////////////////////////////////////////////////////////////////
// [[mem_list_t]]
@@ -825,7 +960,9 @@ mem_list_mode_t;
//-----------------------------------------------------------------------------
-void InitializeMemList ( mem_list_t *ml );
+static inline void InitializeMemList ( mem_list_t *ml )
+ { DASSERT(ml); memset(ml,0,sizeof(*ml)); }
+
void ResetMemList ( mem_list_t *ml );
void MoveMemList ( mem_list_t *dest, mem_list_t *src );
@@ -1037,39 +1174,6 @@ uint PurgeCircBuf ( CircBuf_t *cb );
//
///////////////////////////////////////////////////////////////////////////////
-/////////////// CopyMode_t ///////////////
-///////////////////////////////////////////////////////////////////////////////
-
-typedef enum CopyMode_t
-{
- CPM_COPY, // make a copy of the data, alloced
- CPM_MOVE, // move the alloced data
- CPM_LINK, // link the data
-
-} CopyMode_t;
-
-///////////////////////////////////////////////////////////////////////////////
-
-void * CopyData
-(
- const void *data, // data to copy/move/link
- uint size, // size of 'data'
- CopyMode_t mode, // copy mode
- bool *res_alloced // not NULL:
- // store true, if data must be freed
- // otherwise store false
-);
-
-///////////////////////////////////////////////////////////////////////////////
-
-void FreeData
-(
- const void *data, // data to free
- CopyMode_t mode // copy mode
-);
-
-//
-///////////////////////////////////////////////////////////////////////////////
/////////////// split strings ///////////////
///////////////////////////////////////////////////////////////////////////////
@@ -1192,7 +1296,7 @@ ccp ProgramDirectory(void);
void DefineLogDirectory ( ccp path0, bool force );
// get 'ProgInfo.logdir' without tailing '/' ("." as fall back)
-ccp GetLogDirectory();
+ccp GetLogDirectory(void);
#ifdef __CYGWIN__
ccp ProgramPathNoExt(void);
@@ -1264,7 +1368,7 @@ ccp PathAllocPPE ( ccp path1, ccp path2, ccp ext );
static inline ccp PathCatPPE ( char *buf, size_t bufsize, ccp path1, ccp path2, ccp ext )
{ return PathCatBufPPE(buf,bufsize,path1,path2,ext); }
-// Same as PathCatPP*(), but use 'base' as prefix for relative pathes.
+// Same as PathCatPP*(), but use 'base' as prefix for relative paths.
// If 'base' is NULL (but not empty), use getcwd() instead.
// PathCatBufBP() and PathCatBP() are special: path can be part of buf
char *PathCatBufBP ( char *buf, size_t bufsize, ccp base, ccp path );
@@ -1389,9 +1493,12 @@ char * PrintID
#define CIRC_BUF_MAX_ALLOC 0x0400 // request limit
#define CIRC_BUF_SIZE 0x4000 // internal buffer size
+// returns true if 'ptr' points into circ buffer => ignored by FreeString()
+bool IsCircBuf ( cvp ptr );
+
char * GetCircBuf
(
- // never returns NULL, but always ALIGN(4)
+ // Never returns NULL, but always ALIGN(4)
u32 buf_size // wanted buffer size, caller must add 1 for NULL-term
// if buf_size > CIRC_BUF_MAX_ALLOC:
@@ -1400,7 +1507,7 @@ char * GetCircBuf
char * CopyCircBuf
(
- // never returns NULL, but always ALIGN(4)
+ // Never returns NULL, but always ALIGN(4)
cvp data, // source to copy
u32 data_size // see GetCircBuf()
@@ -1408,8 +1515,8 @@ char * CopyCircBuf
char * CopyCircBuf0
(
- // never returns NULL, but always ALIGN(4)
- // an additional char is alloced and set to NULL
+ // Like CopyCircBuf(), but an additional char is alloced and set to NULL
+ // Never returns NULL, but always ALIGN(4).
cvp data, // source to copy
u32 data_size // see GetCircBuf()
@@ -1417,11 +1524,32 @@ char * CopyCircBuf0
char * PrintCircBuf
(
+ // returns CopyCircBuf0() or EmptyString.
+
ccp format, // format string for vsnprintf()
... // arguments for 'format'
)
__attribute__ ((__format__(__printf__,1,2)));
+char * AllocCircBuf
+(
+ // Never returns NULL. Call FreeString(RESULT) to free possible alloced memory.
+
+ cvp src, // NULL or source
+ int src_len, // len of 'src'; if -1: use strlen(source)
+ bool try_circ // use circ-buffer, if result is small enough
+);
+
+char * AllocCircBuf0
+(
+ // Never returns NULL. Call FreeString(RESULT) to free possible alloced memory.
+ // Like AllocCircBuf(), but an additional char is alloced and set to NULL
+
+ cvp src, // NULL or source
+ int src_len, // len of 'src'; if -1: use strlen(source)
+ bool try_circ // use circ-buffer, if result is small enough
+);
+
void ReleaseCircBuf
(
ccp end_buf, // pointer to end of previous alloced buffer
@@ -2171,6 +2299,7 @@ typedef enum CharMode_t // select encodig/decoding method
CHMD_UTF8 = 0x01, // UTF8 support enabled (compatible with legacy bool)
CHMD_ESC = 0x02, // escape ESC by \e
+ CHMD__MODERN = CHMD_UTF8 | CHMD_ESC,
CHMD__ALL = CHMD_UTF8 | CHMD_ESC,
}
__attribute__ ((packed)) CharMode_t;
@@ -2233,13 +2362,25 @@ extern ccp TableDecode64default, TableEncode64default;
///////////////////////////////////////////////////////////////////////////////
+uint GetEscapedSize
+(
+ // returns the needed buffer size for PrintEscapedString()
+
+ ccp source, // NULL or string to print
+ int src_len, // length of string. if -1, str is null terminated
+ CharMode_t char_mode, // modes, bit field (CHMD_*)
+ char quote // NULL or quotation char, that must be quoted
+);
+
+//-----------------------------------------------------------------------------
+
char * PrintEscapedString
(
// returns 'buf'
char *buf, // valid destination buffer
uint buf_size, // size of 'buf', >= 10
- ccp source, // NULL string to print
+ ccp source, // NULL or string to print
int len, // length of string. if -1, str is null terminated
CharMode_t char_mode, // modes, bit field (CHMD_*)
char quote, // NULL or quotation char, that must be quoted
@@ -2250,7 +2391,7 @@ char * PrintEscapedString
uint ScanEscapedString
(
- // returns the number of valid bytes in 'buf' (NULL term not counted)
+ // returns the number of valid bytes in 'buf' (NULL term added but not counted)
char *buf, // valid destination buffer, maybe source
uint buf_size, // size of 'buf'
@@ -2540,6 +2681,71 @@ ccp GetShiftJISStatistics(void);
//
///////////////////////////////////////////////////////////////////////////////
+/////////////// escape/quote strings, alloc space ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+char * EscapeString
+(
+ // Returns a pointer.
+ // Use FreeString(result) to free possible alloced result.
+ // circ-buffer is ignored by FreeString().
+
+ cvp src, // NULL or source
+ int src_len, // size of 'src'. If -1: Use strlen(src)
+ cvp return_if_null, // return this, if 'src==NULL'
+ cvp return_if_empty, // return this, if src is empty (have no chars)
+ CharMode_t char_mode, // how to escape
+ char quote, // quoting character: " or ' or $ (for $'...')
+ bool try_circ, // use circ-buffer, if result is small enough
+ uint *dest_len // not NULL: Store length of result here
+);
+
+//-----------------------------------------------------------------------------
+
+static inline char * EscapeStringM ( mem_t src, cvp if_null, CharMode_t cm )
+ { return EscapeString(src.ptr,src.len,if_null,EmptyString,cm,0,false,0); }
+
+static char * EscapeStringS ( ccp src, cvp if_null, CharMode_t cm )
+ { return EscapeString(src,-1,if_null,EmptyString,cm,0,false,0); }
+
+//-----------------------------------------------------------------------------
+
+static inline char * EscapeStringCircM ( mem_t src, cvp if_null, CharMode_t cm )
+ { return EscapeString(src.ptr,src.len,if_null,EmptyString,cm,0,true,0); }
+
+static char * EscapeStringCircS ( ccp src, cvp if_null, CharMode_t cm )
+ { return EscapeString(src,-1,if_null,EmptyString,cm,0,true,0); }
+
+//-----------------------------------------------------------------------------
+
+static inline char * QuoteStringM ( mem_t src, cvp if_null, CharMode_t cm )
+ { return EscapeString(src.ptr,src.len,if_null,EmptyQuote,cm,true,false,0); }
+
+static char * QuoteStringS ( ccp src, cvp if_null, CharMode_t cm )
+ { return EscapeString(src,-1,if_null,EmptyQuote,cm,'"',false,0); }
+
+static inline char * QuoteBashM ( mem_t src, cvp if_null, CharMode_t cm )
+ { return EscapeString(src.ptr,src.len,if_null,EmptyQuote,cm,'$',false,0); }
+
+static char * QuoteBashS ( ccp src, cvp if_null, CharMode_t cm )
+ { return EscapeString(src,-1,if_null,EmptyQuote,cm,'$',false,0); }
+
+//-----------------------------------------------------------------------------
+
+static inline char * QuoteStringCircM ( mem_t src, cvp if_null, CharMode_t cm )
+ { return EscapeString(src.ptr,src.len,if_null,EmptyQuote,cm,'"',true,0); }
+
+static char * QuoteStringCircS ( ccp src, cvp if_null, CharMode_t cm )
+ { return EscapeString(src,-1,if_null,EmptyQuote,cm,'"',true,0); }
+
+static inline char * QuoteBashCircM ( mem_t src, cvp if_null, CharMode_t cm )
+ { return EscapeString(src.ptr,src.len,if_null,EmptyQuote,cm,'$',true,0); }
+
+static char * QuoteBashCircS ( ccp src, cvp if_null, CharMode_t cm )
+ { return EscapeString(src,-1,if_null,EmptyQuote,cm,'$',true,0); }
+
+//
+///////////////////////////////////////////////////////////////////////////////
/////////////// scan keywords ///////////////
///////////////////////////////////////////////////////////////////////////////
@@ -2748,16 +2954,20 @@ OffOn_t;
extern const KeywordTab_t KeyTab_OFF_AUTO_ON[];
-int ScanKeywordOffAutoOn
+int ScanKeywordOffAutoOnEx
(
// returns one of OFFON_*
+ const KeywordTab_t *keytab, // Keyword table. If NULL, then use KeyTab_OFF_AUTO_ON[]
ccp arg, // argument to scan
int on_empty, // return this value on empty
uint max_num, // >0: additionally accept+return number <= max_num
ccp object // NULL (silent) or object for error messages
);
+static inline int ScanKeywordOffAutoOn( ccp arg, int on_empty, uint max_num, ccp object )
+ { return ScanKeywordOffAutoOnEx(0,arg,on_empty,max_num,object); }
+
ccp GetKeywordOffAutoOn ( OffOn_t value );
//
@@ -4393,9 +4603,12 @@ uint RemoveStringFieldByIndex ( StringField_t * sf, int index, int n );
// helper function
ccp * InsertStringFieldHelper ( StringField_t * sf, int idx );
-// append at the end an do not sort
+// append at the end and do not sort
void AppendStringField ( StringField_t * sf, ccp key, bool move_key );
+// append at the end if nor already exists, do not sort
+void AppendUniqueStringField ( StringField_t * sf, ccp key, bool move_key );
+
// re-sort field using sf->func_cmp()
void SortStringField ( StringField_t * sf );
@@ -4484,7 +4697,9 @@ typedef struct ParamField_t
//-----------------------------------------------------------------------------
-void InitializeParamField ( ParamField_t * pf );
+static inline void InitializeParamField ( ParamField_t * pf )
+ { DASSERT(pf); memset(pf,0,sizeof(*pf)); }
+
void ResetParamField ( ParamField_t * pf );
void MoveParamField ( ParamField_t * dest, ParamField_t * src );
@@ -4492,18 +4707,16 @@ int FindParamFieldIndex ( const ParamField_t * pf, ccp key, int not_found_value
ParamFieldItem_t * FindParamField ( const ParamField_t * pf, ccp key );
ParamFieldItem_t * FindParamFieldByNum ( const ParamField_t * pf, uint num );
ParamFieldItem_t * FindInsertParamField
- ( ParamField_t * pf, ccp key, bool move_key, bool *old_found );
-ParamFieldItem_t * CountParamField ( ParamField_t * pf, ccp key, bool move_key );
+ ( ParamField_t * pf, ccp key, bool move_key, uint num, bool *old_found );
+ParamFieldItem_t * IncrementParamField ( ParamField_t * pf, ccp key, bool move_key );
+// Insert: Insert only if not found, Replace: Insert or replace data
// return: true if item inserted/deleted
bool InsertParamField ( ParamField_t * pf, ccp key, bool move_key, uint num, cvp data );
bool ReplaceParamField( ParamField_t * pf, ccp key, bool move_key, uint num, cvp data );
bool RemoveParamField ( ParamField_t * pf, ccp key );
-ParamFieldItem_t * InsertParamFieldEx
- ( ParamField_t * pf, ccp key, bool move_key, uint num, bool *found );
-
-// append at the end an do not sort
+// append at the end and do not sort
ParamFieldItem_t * AppendParamField
( ParamField_t * pf, ccp key, bool move_key, uint num, cvp data );
@@ -4515,6 +4728,81 @@ ParamFieldItem_t * MatchParamField ( const ParamField_t * pf, ccp key );
//
///////////////////////////////////////////////////////////////////////////////
+/////////////// struct exmem_list_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[exmem_key_t]]
+
+typedef struct exmem_key_t
+{
+ ccp key; // string as main key => data.is_key_alloced
+ exmem_t data; // data
+}
+exmem_key_t;
+
+//-----------------------------------------------------------------------------
+// [[exmem_list_t]]
+
+typedef struct exmem_list_t
+{
+ exmem_key_t *list; // data list
+ uint used; // number of used titles in the title field
+ uint size; // number of allocated pointers in 'field'
+ bool is_unsorted; // true: list is not sorted (Append() was used)
+ int (*func_cmp)( ccp s1, ccp s2 ); // compare function, default is strcmp()
+}
+exmem_list_t;
+
+//-----------------------------------------------------------------------------
+
+static inline void InitializeEML ( exmem_list_t * eml )
+ { DASSERT(eml); memset(eml,0,sizeof(*eml)); }
+
+void ResetEML ( exmem_list_t * eml );
+void MoveEML ( exmem_list_t * dest, exmem_list_t * src );
+
+// return the index of the (next) item
+uint FindHelperEML ( const exmem_list_t * eml, ccp key, bool *found );
+
+int FindIndexEML ( const exmem_list_t * eml, ccp key, int not_found_value );
+exmem_key_t * FindEML ( const exmem_list_t * eml, ccp key );
+exmem_key_t * FindAttribEML ( const exmem_list_t * eml, u32 attrib );
+exmem_key_t * FindInsertEML ( exmem_list_t * eml, ccp key, CopyMode_t cm_key, bool *old_found );
+
+// Insert if not found, ignore othwerwise. Return true if item inserted
+bool InsertEML ( exmem_list_t * eml, ccp key, CopyMode_t cm_key,
+ const exmem_t *data, CopyMode_t cm_data );
+
+// Insert or replace content. Return true if item inserted
+bool ReplaceEML ( exmem_list_t * eml, ccp key, CopyMode_t cm_key,
+ const exmem_t *data, CopyMode_t cm_data );
+
+// Replace content if found. Return true if item found
+bool OverwriteEML ( exmem_list_t * eml, ccp key, CopyMode_t cm_key,
+ const exmem_t *data, CopyMode_t cm_data );
+
+// Append at the end and do not sort
+exmem_key_t * AppendEML ( exmem_list_t * eml, ccp key, CopyMode_t cm_key,
+ const exmem_t *data, CopyMode_t cm_data );
+
+// Return true if item found and removed
+bool RemoveEML ( exmem_list_t * eml, ccp key );
+
+
+// find first pattern that matches
+exmem_key_t * MatchEML ( const exmem_list_t * eml, ccp key );
+
+void DumpEML ( FILE *f, int indent, const exmem_list_t * eml, ccp info );
+
+//-----------------------------------------------------------------------------
+
+exmem_t ResolveSymbolsEML ( const exmem_list_t * eml, ccp source );
+uint ResolveAllSymbolsEML ( exmem_list_t * eml );
+
+// add symbols 'home', 'etc', 'install' = 'prog' and 'cwd'
+void AddStandardSymbolsEML ( exmem_list_t * eml, bool overwrite );
+
+//
+///////////////////////////////////////////////////////////////////////////////
/////////////// Memory Map ///////////////
///////////////////////////////////////////////////////////////////////////////
// [[MemMapItem_t]]