Strv.h
[目次 | 型・クラス・構造体 | マクロ]
1|/**************************************************************************
2|* 1. <<< 可変長文字列 Variable String (StrV) >>>
3|***************************************************************************/
4|
5|#ifndef __STRV_H
6|#define __STRV_H
7|
8|/*----------------------------------------------------------------------
9|[Module Property]
10|name = StrV
11|title = 可変長文字列
12|category = 基本型
13|src = strv.c
14|depend =
15|priority =
16|accord =
17|----------------------------------------------------------------------*/
18|
19|#ifndef STDX_SETTING
20|#endif
21|
22|
23|#ifndef USES_PRIORITY_HEADER
24|/*[START_OF_PRIORITY_HEADER]*/
25|
26|#define USES_STRV
27|typedef struct _StrV StrV;
28|typedef struct _StrV_AbleElem StrV_AbleElem;
29|typedef struct _StrV_Mem StrV_Mem;
30|typedef struct _StrV_Set StrV_Set;
31|typedef struct _StrV_SetP StrV_SetP;
32|typedef struct _StrV_MemE StrV_MemE;
33|
34|#define StrV_Err_MallocEmpty 3181
35|
36|/*[END_OF_PRIORITY_HEADER]*/
37|#endif /* USES_PRIORITY_HEADER */
38|
39|
40|#ifdef _STDLIB
41|#include "stdlib.h"
42|#endif
43|
44|
45|/*------------------------------------------------------------------------*/
46|/* 2. <<< Interface Area ----------------------------------------------- >>> */
47|/*------------------------------------------------------------------------*/
48|
49|#ifdef __cplusplus
50|extern "C" {
51|#endif
52|
53|
54|
55|/***********************************************************
56|* 3. <<< [StrV] 可変長文字列 >>>
57|*【補足】
58|*・内部で malloc などヒープ系の関数を呼び出しており、
59|* 任意の長さの文字列を代入することができます。
60|*・使わなくなった文字列には、StrV_finish を呼び出す必要があります。
61|*・定数文字列の場合、StrX_Mem や StrX_Set を使用したほうが
62|* 効率的です。
63|************************************************************/
64|#define StrV_unitSize 32 /* メモリ領域を確保する単位(バイト) */
65|
66|void StrV_init( StrV* );
67|void StrV_finish( StrV* );
68|char* StrV_get( StrV* );
69|void StrV_cpy( StrV*, const char* s );
70|void StrV_cat( StrV*, const char* s );
71|void StrV_ins( StrV*, const char* s );
72|
73|
74|struct _StrV {
75| char* p; /* 文字列、アドレスが変わる可能性あり */
76|};
77|
78|
79|
80|/***********************************************************
81|* 4. <<< [StrV_AbleElem] ArrX_AbleElem から継承した StrV >>>
82|************************************************************/
83|#ifdef USES_ARRX
84|
85|struct _StrV_AbleElem {
86| ArrX_AbleElem inherit_ArrX_AbleElem;
87| StrV s;
88|};
89|
90|#endif
91|
92|
93|
94|/**************************************************************************
95|* 5. <<< [StrV_Mem] 文字列の記憶領域(malloc 使用) >>>
96|*【補足】
97|*・malloc を使用するので、ヒープメモリ領域が許す限り無限に領域を確保する
98|* ことができます。
99|*・格納した文字列の長さを後で変えることはできません。
100|*・StrV_Mem_alloc で確保した領域は、char* 型か StrV_Set 型で管理します。
101|**************************************************************************/
102|#ifdef USES_LISTX
103|#ifdef USES_STRX
104|
105|#define StrV_Mem_unitSize 2048 /* 増加する単位(バイト) */
106|#define StrV_Mem_maxLen 256 /* 一度に確保できる文字列領域(\0含む)サイズ */
107|
108|void StrV_Mem_init( StrV_Mem* );
109|void StrV_Mem_finish( StrV_Mem* );
110|void StrV_Mem_toEmpty( StrV_Mem* );
111|void StrV_Mem_setMax( StrV_Mem*, int x );
112|char* StrV_Mem_getFirst( StrV_Mem* );
113|char* StrV_Mem_alloc( StrV_Mem* );
114|/* StrV_Mem_forEach( StrV_Mem*, char** s ); */
115|void StrV_Mem_copy( StrV_Mem*, StrV_Mem* );
116|
117|#if defined( USES_STRX ) && defined( USES_LISTX )
118|struct _StrV_Mem {
119| ListX mems; /* StrV_MemE 型リスト */
120| StrV_MemE* mem_last;
121| int maxLen; /* →StrV_Mem_maxLen */
122|};
123|
124|struct _StrV_MemE { /* リスト要素:StrX_Mem のリスト */
125| StrX_Mem mem;
126| ListX_Elem inherit_ListX_Elem;
127|};
128|#endif
129|
130|/* 内部用 */
131|void StrV_Mem_forEach_imp( StrV_Mem*, StrV_SetP* pp );
132|
133|#endif
134|#endif
135|
136|
137|/**************************************************************************
138|* 6. <<< [StrV_Set] 文字列の記憶領域の部分集合(StrV_Mem用) >>>
139|* 7. <<< [StrV_SetP] StrV_Set_forEach 関数用イテレータ >>>
140|*【役割】
141|*・StrV_Mem に格納した文字列の部分集合です。
142|*・1つの StrX_Mem 領域に対して、複数の集合を表現できます。
143|*・参照した文字列の長さを変えることはできません。
144|**************************************************************************/
145|#ifdef USES_LISTX
146|#ifdef USES_STRX
147|
148|struct _StrV_Set {
149| char* first; /* 最初の文字列の先頭アドレス */
150| char* last; /* 最後の次の文字列の先頭アドレス */
151| StrV_MemE* firstVE; /* first の StrV_MemE 型リストの参照 */
152|};
153|void StrV_Set_init( StrV_Set* );
154|void StrV_Set_init1( StrV_Set*, StrV_Mem* );
155|void StrV_Set_init2( StrV_Set*, StrV_Mem* );
156|/* StrV_Set_forEach( StrV_Set*, StrV_SetP* ); */
157|
158|
159|struct _StrV_SetP {
160| char* p; /* 現在参照している文字列 */
161| StrV_MemE* pVE; /* 現在参照している StrV_MemE 型リスト */
162|};
163|
164|
165|/* 内部用 */
166|void StrV_Set_forEach_imp( StrV_Set*, StrV_SetP* pp );
167|
168|#endif
169|#endif
170|
171|
172|/*------------------------------------------------------------------------*/
173|/* 8. <<< Mapping Area ------------------------------------------------- >>> */
174|/*------------------------------------------------------------------------*/
175|
176|
177|/***********************************************************************
178|* 9. <<< [StrV_get] 文字列を参照する >>>
179|*【引数】
180|* ・StrV* this; 可変長文字列
181|* ・char* 返り値; 文字列へのポインタ
182|*【補足】
183|*・返り値でアクセスできるメモリ領域は変更しても構いませんが、
184|* 文字列長が長くなる場合は、StrV_cpy 関数を使用してください。
185|************************************************************************/
186|#define StrV_get( this ) \
187| ((this)->p)
188|
189|
190|
191|/***********************************************************************
192|* 10. <<< [StrV_Mem_setMax] 一度に確保できる文字列領域のサイズを設定する >>>
193|*【補足】
194|*・StrV_Mem_alloc 関数で得られたアドレスから文字列を格納することが
195|* できると保証する長さ('\0'文字含む)を設定します。
196|************************************************************************/
197|#ifdef USES_LISTX
198|#ifdef USES_STRX
199|
200|#define StrV_Mem_setMax( this, x ) \
201| (this)->maxLen = (x)
202|
203|#endif
204|#endif
205|
206|
207|/***********************************************************************
208|* 11. <<< [StrV_Mem_getFirst] 最初の要素を参照する >>>
209|************************************************************************/
210|#define StrV_Mem_getFirst( this ) \
211| ( StrX_Mem_getFirst( \
212| &ListX_getFirst( &(this)->mems, StrV_MemE )->mem ) )
213|
214|/**************************************************************************
215|* 12. <<< [StrV_Mem_forEach] 集合に含まれる文字列を列挙しながらループする >>>
216|*【引数】
217|* ・StrV_SetP* pp; 要素文字列(char*ポインタ)を持ったイテレータ
218|* ・StrV_Set* set; 文字列の記憶領域
219|*【補足】
220|*・for 文の中で使用します。
221|* StrV_SetP pp;
222|* for ( StrV_Mem_forEach( &set, &pp ) )
223|* strcpy( s, pp.p );
224|***************************************************************************/
225|#ifdef USES_LISTX
226|#ifdef USES_STRX
227|
228|/* StrV_Mem_forEach( StrV_Mem*, char** s ); */
229|
230|#define StrV_Mem_forEach( set, pp ) \
231| (pp)->p = (ListX_getFirst(&(set)->mems, StrV_MemE)->mem.buf == \
232| ListX_getFirst(&(set)->mems, StrV_MemE)->mem.pBuf ? NULL : \
233| ListX_getFirst(&(set)->mems, StrV_MemE)->mem.buf + 1 ), \
234| (pp)->pVE = ListX_getFirst(&(set)->mems, StrV_MemE); \
235| (pp)->p != NULL ; \
236| StrV_Mem_forEach_imp( (set), (pp) )
237|
238|#endif
239|#endif
240|
241|/**************************************************************************
242|* 13. <<< [StrV_Set_init] 空集合を定義する >>>
243|*【型】
244|* void StrV_Set_init( StrV_Set* );
245|***************************************************************************/
246|#define StrV_Set_init( this ) \
247| ( (this)->first = NULL, (this)->last = NULL )
248|
249|
250|/**************************************************************************
251|* 14. <<< [StrV_Set_init1] 集合を定義する(step-1) >>>
252|* 15. <<< [StrV_Set_init2] 集合を定義する(step-2) >>>
253|*【補足】
254|*・StrV_Set_init1 から StrV_Set_init2 の間に
255|* mem に StrV_Mem_alloc した文字列の集合に初期化します。
256|*・StrV_Set_init2 を呼び出す前に、集合の最後の要素に相当する
257|* 文字列を格納しておいてください。
258|***************************************************************************/
259|#ifdef USES_LISTX
260|#ifdef USES_STRX
261|
262|#define StrV_Set_init1( this, _mem ) \
263|( \
264| ( (this)->first = strchr( (_mem)->mem_last->mem.pBuf, '\0' ) + 1 ), \
265| (this)->firstVE = (_mem)->mem_last \
266|)
267|
268|#define StrV_Set_init2( this, _mem ) \
269| ( (this)->last = strchr( (_mem)->mem_last->mem.pBuf, '\0' ) + 1 )
270|
271|
272|#endif
273|#endif
274|
275|
276|/**************************************************************************
277|* 16. <<< [StrV_Set_forEach] 集合に含まれる文字列を列挙しながらループする >>>
278|*【引数】
279|* ・StrV_SetP* pp; 要素文字列(char*ポインタ)を持ったイテレータ
280|* ・StrV_Set* set; 文字列の記憶領域
281|*【補足】
282|*・for 文の中で使用します。
283|* StrV_SetP pp;
284|* for ( StrV_Set_forEach( &set, &pp ) )
285|* strcpy( s, pp.p );
286|***************************************************************************/
287|#ifdef USES_LISTX
288|#ifdef USES_STRX
289|
290|#define StrV_Set_forEach( set, pp ) \
291| (pp)->p = ((set)->first==(set)->last ? NULL : (set)->first), \
292| (pp)->pVE = (set)->firstVE; \
293| (pp)->p != NULL ; \
294| StrV_Set_forEach_imp( (set), (pp) )
295|
296|#endif
297|#endif
298|
299|#ifdef __cplusplus
300|}
301|#endif
302|
303|#endif
304|
305|