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|