Strv.c
[目次 | 関数 | マクロ]
1|/**************************************************************************
2|* 1. <<< 可変長文字列 Variable String (StrV) >>>
3|***************************************************************************/
4|
5|#define STDLIBS_INCLUDE
6|#define STDLIBS_INCLUDE_STRING_H
7|#define STDLIBS_INCLUDE_STDLIB_H
8|#ifdef USES_MXP_AUTOINC
9| #include "strv.ah" /* Auto include header, Look at mixer-... folder */
10|#else
11| #include <all.h>
12|#endif
13|
14|
15|/*-------------------------------------------------------------------------*/
16|/* 2. <<< ◆(StrV) 可変長文字列 >>> */
17|/*-------------------------------------------------------------------------*/
18|
19|
20|
21|/***********************************************************************
22|* 3. <<< [StrV_init] 初期化する >>>
23|*【補足】
24|*・初期化後の文字列の値は "" です。NULL ではありません。
25|************************************************************************/
26|void StrV_init( StrV* m )
27|{
28| m->p = malloc(StrV_unitSize);
29| if ( m->p == NULL ) error();
30| ERRORS_FINISHCHK_FOR_INIT( StrV_finish );
31|
32| m->p[0] = '\0';
33|}
34|
35|
36|
37|/***********************************************************************
38|* 4. <<< [StrV_finish] 後始末する >>>
39|************************************************************************/
40|void StrV_finish( StrV* m )
41|{
42| free( m->p );
43| ERRORS_FINISHCHK_FOR_FINISH( StrV_finish );
44|}
45|
46|/***********************************************************************
47|* 5. <<< [StrV_cpy] 文字列を代入する >>>
48|*【補足】
49|*・内部で、free & malloc することがあります。
50|************************************************************************/
51|void StrV_cpy( StrV* m, const char* s )
52|{
53| if ( strlen( s ) / StrV_unitSize >
54| strlen( m->p ) / StrV_unitSize ) {
55| int size;
56|
57| free( m->p );
58| size = strlen( s ) + StrV_unitSize;
59| m->p = malloc( size - size % StrV_unitSize );
60| }
61| strcpy( m->p, s );
62|}
63|
64|
65|
66|/***********************************************************************
67|* 6. <<< [StrV_cat] 文字列を連結する >>>
68|*【補足】
69|*・内部で、free & malloc することがあり、文字列を格納しているアドレスが
70|* 変わる可能性があります。
71|************************************************************************/
72|void StrV_cat( StrV* m, const char* s )
73|{
74| int size = strlen( m->p ) + strlen( s );
75|
76| if ( size / StrV_unitSize >
77| (int)strlen( m->p ) / StrV_unitSize ) {
78| char* p;
79|
80| size += StrV_unitSize;
81| p = malloc( size - size % StrV_unitSize );
82| strcpy( p, m-> p );
83| free( m->p );
84| m->p = p;
85| }
86| strcat( m->p, s );
87|}
88|
89|
90|
91|/***********************************************************************
92|* 7. <<< [StrV_ins] 文字列を挿入する >>>
93|*【補足】
94|*・内部で、free & malloc することがあり、文字列を格納しているアドレスが
95|* 変わる可能性があります。
96|************************************************************************/
97|void StrV_ins( StrV* m, const char* s )
98|{
99| int len1 = strlen( m->p );
100| int len2 = strlen( s );
101| int size = len1 + len2;
102|
103| if ( size / StrV_unitSize >
104| (int)len1 / StrV_unitSize ) {
105| char* p;
106|
107| size += StrV_unitSize;
108| p = malloc( size - size % StrV_unitSize );
109| strcpy( p, m-> p );
110| free( m->p );
111| m->p = p;
112| }
113| memmove( m->p + len2, m->p, len1 + 1 );
114| memcpy( m->p, s, len2 );
115|}
116|
117|
118|
119|/*-------------------------------------------------------------------------*/
120|/* 8. <<< ◆(StrV_Mem) 固定長文字列の記憶領域(malloc 使用)>>> */
121|/*-------------------------------------------------------------------------*/
122|
123|
124|/***********************************************************************
125|* 9. <<< [StrV_Mem_init] 初期化する >>>
126|************************************************************************/
127|#ifdef USES_LISTX
128|void StrV_Mem_init( StrV_Mem* m )
129|{
130| StrV_MemE* ve = (StrV_MemE*)malloc( sizeof(StrV_MemE) );
131| void* memX = malloc( StrV_Mem_unitSize );
132|
133| /* 初期化する */
134| ListX_init( &m->mems );
135| ListX_addFirst( &m->mems, ve );
136| StrX_Mem_init( &ve->mem, memX, StrV_Mem_unitSize );
137|
138| m->mem_last = ve;
139| m->maxLen = StrV_Mem_maxLen;
140|
141| ERRORS_FINISHCHK_FOR_INIT( StrV_Mem_finish );
142|}
143|#endif
144|
145|
146|
147|/***********************************************************************
148|* 10. <<< [StrV_Mem_finish] 後始末する >>>
149|************************************************************************/
150|#ifdef USES_LISTX
151|void StrV_Mem_finish( StrV_Mem* m )
152|{
153| StrV_MemE* ve;
154| StrV_MemE* ve2;
155| ERRORS_FINISHCHK_FOR_FINISH( StrV_Mem_finish );
156|
157| for ( ListX_forEachFree( &m->mems, &ve, StrV_MemE, &ve2, free ) ) {
158| free( StrX_Mem_getTopAdr( &ve->mem ) );
159| }
160|}
161|#endif
162|
163|
164|/***********************************************************************
165|* 11. <<< [StrV_Mem_toEmpty] 要素を空にする >>>
166|************************************************************************/
167|#ifdef USES_LISTX
168|void StrV_Mem_toEmpty( StrV_Mem* m )
169|{
170| StrV_MemE* ve;
171| StrV_MemE* ve2;
172| void* memX;
173|
174| /* 後始末する */
175| for ( ListX_forEachFree( &m->mems, &ve, StrV_MemE, &ve2, free ) ) {
176| free( StrX_Mem_getTopAdr( &ve->mem ) );
177| }
178|
179| /* 初期化する */
180| ve = (StrV_MemE*)malloc( sizeof(StrV_MemE) );
181| memX = malloc( StrV_Mem_unitSize );
182| ListX_init( &m->mems );
183| ListX_addFirst( &m->mems, ve );
184| StrX_Mem_init( &ve->mem, memX, StrV_Mem_unitSize );
185|
186| m->mem_last = ve;
187| m->maxLen = StrV_Mem_maxLen;
188|}
189|#endif
190|
191|
192|/***********************************************************************
193|* 12. <<< [StrV_Mem_alloc] メモリ領域を確保する >>>
194|*【補足】
195|*・返り値によって得られたアドレスのさす領域は、m->maxLen の大きさだけ
196|* 保証されています。(参照:StrV_Mem_setMax マクロ)
197|*・過去に取得した返り値(アドレス)は、StrV_Mem_alloc の内部で
198|* realloc されたときに無効になります。
199|************************************************************************/
200|#ifdef USES_LISTX
201|char* StrV_Mem_alloc( StrV_Mem* m )
202|{
203| StrX_Mem* mem = &m->mem_last->mem;
204|
205| /* 確保したメモリ領域が不足してきたとき、メモリ領域を追加確保する */
206| if ( (int)StrX_Mem_getLeftSize( mem ) <= m->maxLen ) {
207| StrV_MemE* ve = (StrV_MemE*)malloc( sizeof(StrV_MemE) );
208| void* memX = malloc( StrV_Mem_unitSize );
209|
210| /* リスト要素を初期化する */
211| ListX_Elem_insertNext( m->mem_last, ve );
212| StrX_Mem_init( &ve->mem, memX, StrV_Mem_unitSize );
213| m->mem_last = ve;
214|
215| mem = &ve->mem;
216| ASSERT( (int)StrX_Mem_getLeftSize( mem ) > m->maxLen );
217| }
218|
219| return StrX_Mem_alloc( mem );
220|}
221|#endif
222|
223|
224|/**************************************************************************
225|* 13. <<< [StrV_Mem_forEach_imp] StrV_Mem_forEach の実装 >>>
226|**************************************************************************/
227|#ifdef USES_LISTX
228|void StrV_Mem_forEach_imp( StrV_Mem* m, StrV_SetP* pp )
229|{
230| if ( pp->p < pp->pVE->mem.pBuf ) {
231| pp->p = strchr( pp->p, '\0' ) + 1;
232| if ( pp->p > ListX_getFirst(&m->mems, StrV_MemE)->mem.pBuf ) pp->p = NULL;
233| }
234| else {
235| pp->pVE = pp->pVE->inherit_ListX_Elem;
236| if ( pp->pVE == NULL ) pp->p = NULL;
237| else pp->p = pp->pVE->mem.buf + 1;
238| }
239|}
240|#endif
241|
242|/**************************************************************************
243|* 14. <<< [StrV_Mem_copy] 同じ構成の複製を作成する >>>
244|*【補足】
245|*・src も dst も初期化してあること
246|**************************************************************************/
247|void StrV_Mem_copy( StrV_Mem* dst, StrV_Mem* src )
248|{
249| StrV_SetP sp;
250| char* p;
251|
252| for ( StrV_Mem_forEach( src, &sp ) ) {
253| p = StrV_Mem_alloc( dst );
254| strcpy( p, sp.p );
255| }
256|}
257|
258|
259|/*-------------------------------------------------------------------------*/
260|/* 15. <<< ◆(StrV_Set) 文字列の記憶領域の部分集合 >>> */
261|/*-------------------------------------------------------------------------*/
262|
263|
264|
265|/**************************************************************************
266|* 16. <<< [StrV_Set_forEach_imp] StrV_Set_forEach の実装 >>>
267|**************************************************************************/
268|#ifdef USES_LISTX
269|void StrV_Set_forEach_imp( StrV_Set* m, StrV_SetP* pp )
270|{
271| if ( pp->p < pp->pVE->mem.pBuf ) {
272| pp->p = strchr( pp->p, '\0' ) + 1;
273| if ( pp->p == m->last ) pp->p = NULL;
274| }
275| else {
276| pp->pVE = pp->pVE->inherit_ListX_Elem;
277| if ( pp->pVE == NULL ) pp->p = NULL;
278| else pp->p = pp->pVE->mem.buf + 1;
279| }
280|}
281|#endif
282|
283|