Materialised said:
Hi Everyone,
I apologise if this is covered in the FAQ, I did look, but nothing
actually stood out to me as being relative to my subject.
I want to create a 2 dimensional array, a 'array of strings'. I already
know that no individual string will be longer than 50 characters. I just
don't know before run time how many elements of the array will be needed.
I have heard it is possible to dynamically allocate memory for a 2
dimensional array as long as the size of the 2nd element is shown. Is
this correct? And if so could someone post a simple example for me, to
base my own code off.
Thanks
If you want to borrow free dynamic-array-of-string code, look at
FreeDOS edlin, which actually uses dynamic-array-of-dynamic-string,
which is even cooler. Anyway, here's the URL:
http://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/dos/edline/edlin21.zip
and the relevant code:
/* defines.h -- standard defines */
#ifndef DEFINES_H
#define DEFINES_H
#include <stddef.h>
typedef void fvoid_t ();
typedef enum capacity
{
default_size,
reserve
} capacity;
#ifndef NPOS
#define NPOS ((size_t)(-1))
#endif
void Nomemory ();
#endif
/* END OF FILE */
/* defines.c -- implementation of functions from defines.h
AUTHOR: Gregory Pietsch
*/
#include <stdio.h>
#include <stdlib.h>
#include "defines.h"
void
Nomemory (void)
{
fputs ("No memory\n", stderr);
abort ();
}
/* END OF FILE */
/* dynarray.h - dynamic array header
*/
#include <stdlib.h>
#include <stdio.h>
#include "defines.h"
#define _VAL(y,x) y ## x
#define _NM(y,x) _VAL(y,x)
#ifdef PROTOS_ONLY
/* types */
typedef struct _NM (TS, _ARRAY_T)
{
T *_Ptr;
size_t _Len, _Res;
} _NM (TS, _ARRAY_T);
_NM (TS, _ARRAY_T) * _NM (TS, _create) (void);
void
_NM (TS, _destroy) (_NM (TS, _ARRAY_T) *);
void
_NM (TS, _ctor) (_NM (TS, _ARRAY_T) *);
void
_NM (TS, _ctor_with_size) (_NM (TS, _ARRAY_T) *, size_t,
capacity);
void
_NM (TS, _copy_ctor) (_NM (TS, _ARRAY_T) *, _NM (TS, _ARRAY_T)
*);
void
_NM (TS, _ctor_from_ptr) (_NM (TS, _ARRAY_T) *, T *, size_t);
void
_NM (TS, _dtor) (_NM (TS, _ARRAY_T) *);
_NM (TS, _ARRAY_T) * _NM (TS, _append) (_NM (TS, _ARRAY_T) *, T *,
size_t,
size_t);
_NM (TS, _ARRAY_T) * _NM (TS, _assign) (_NM (TS, _ARRAY_T) *, T *,
size_t,
size_t);
_NM (TS, _ARRAY_T) * _NM (TS, _insert) (_NM (TS, _ARRAY_T) *, size_t,
T *,
size_t, size_t);
_NM (TS, _ARRAY_T) * _NM (TS, _remove) (_NM (TS, _ARRAY_T) *, size_t,
size_t);
_NM (TS, _ARRAY_T) * _NM (TS, _subarray) (_NM (TS, _ARRAY_T) *,
_NM (TS, _ARRAY_T) *,
size_t,
size_t);
void
_NM (TS, _swap) (_NM (TS, _ARRAY_T) *, _NM (TS, _ARRAY_T) *);
T *
_NM (TS, _get_at) (_NM (TS, _ARRAY_T) *, size_t);
void
_NM (TS, _put_at) (_NM (TS, _ARRAY_T) *, size_t, T *);
T *
_NM (TS, _base) (_NM (TS, _ARRAY_T) *);
size_t
_NM (TS, _length) (_NM (TS, _ARRAY_T) *);
void
_NM (TS, _resize) (_NM (TS, _ARRAY_T) *, size_t, T *);
size_t
_NM (TS, _reserve) (_NM (TS, _ARRAY_T) *);
void
_NM (TS, _set_reserve) (_NM (TS, _ARRAY_T) *, size_t);
#else
#ifndef Tctor
#define Tctor(x)
#endif
#ifndef Tdtor
#define Tdtor(x)
#endif
#ifndef Tassign
#define Tassign(x,y) (*(x) = *(y))
#endif
/* functions */
static void _NM (TS, _Xinv) (void)
{
fputs ("Invalid dynamic array argument\n", stderr);
abort ();
}
static void _NM (TS, _Xlen) (void)
{
fputs ("Length error: dynamic array too long\n", stderr);
abort ();
}
static void _NM (TS, _Xran) (void)
{
fputs ("Out of range: invalid dynamic array position\n", stderr);
abort ();
}
static void _NM (TS, _Tidy) (_NM (TS, _ARRAY_T) * this, int
_Constructed)
{
size_t i;
if (_Constructed && this->_Ptr != 0)
{
for (i = 0; i < this->_Len; i++)
Tdtor (this->_Ptr + i);
free (this->_Ptr);
}
this->_Len = 0;
this->_Ptr = 0;
this->_Res = 0;
}
static void _NM (TS, _Grow) (_NM (TS, _ARRAY_T) * this, size_t _N, T *
_S,
int _Trim)
{
size_t _Os = this->_Ptr == 0 ? 0 : this->_Res;
size_t _I, _M, _R;
T *_Np;
if (_N == 0)
{
if (_Trim)
_NM (TS, _Tidy) (this, 1);
}
else if (_N == _Os || _N < _Os && !_Trim);
else
{
_M = this->_Ptr == 0 && _N < this->_Res ? this->_Res : _N;
_Np = calloc (_M, sizeof (T));
if (_Np == 0)
Nomemory (); /* no memory */
for (_I = 0; _I < _M; _I++)
Tctor (_Np + _I);
_R = _M;
_M = _N < this->_Len ? _N : this->_Len;
for (_I = 0; _I < _M; ++_I)
Tassign (_Np + _I, this->_Ptr + _I);
if (_S != 0)
for (; _I < this->_Res; ++_I)
Tassign (_Np + _I, _S);
_NM (TS, _Tidy) (this, 1);
this->_Ptr = _Np;
this->_Res = _R;
}
this->_Len = _N;
}
_NM (TS, _ARRAY_T) * _NM (TS, _create) (void)
{
_NM (TS, _ARRAY_T) * x = malloc (sizeof (_NM (TS, _ARRAY_T)));
if (x == 0)
Nomemory ();
_NM (TS, _Tidy) (x, 0);
return x;
}
void _NM (TS, _destroy) (_NM (TS, _ARRAY_T) * x)
{
_NM (TS, _Tidy) (x, 1);
free (x);
}
void _NM (TS, _ctor) (_NM (TS, _ARRAY_T) * this)
{
_NM (TS, _Tidy) (this, 0);
}
void _NM (TS, _ctor_with_size) (_NM (TS, _ARRAY_T) * this, size_t n,
capacity c)
{
_NM (TS, _Tidy) (this, 0);
this->_Res = n;
if (c == default_size)
_NM (TS, _Grow) (this, n, 0, 0);
}
void _NM (TS, _copy_ctor) (_NM (TS, _ARRAY_T) * this, _NM (TS,
_ARRAY_T) * x)
{
size_t i;
_NM (TS, _Tidy) (this, 0);
_NM (TS, _Grow) (this, _NM (TS, _length) (x), 0, 0);
for (i = 0; i < this->_Len; i++)
Tassign (this->_Ptr + i, x->_Ptr + i);
}
void _NM (TS, _ctor_from_ptr) (_NM (TS, _ARRAY_T) * this, T * s,
size_t n)
{
if (s == 0)
_NM (TS, _Xinv) ();
_NM (TS, _Tidy) (this, 0);
_NM (TS, _assign) (this, s, n, 1);
}
void _NM (TS, _dtor) (_NM (TS, _ARRAY_T) * this)
{
_NM (TS, _Tidy) (this, 1);
}
_NM (TS, _ARRAY_T) * _NM (TS, _append) (_NM (TS, _ARRAY_T) * this, T *
_S,
size_t _N, size_t _D)
{
size_t _I;
if (NPOS - this->_Len <= _N)
_NM (TS, _Xlen) ();
_I = this->_Len;
for (_NM (TS, _Grow) (this, _N += _I, 0, 0); _I < _N; ++_I, _S +=
_D)
Tassign (this->_Ptr + _I, _S);
return this;
}
_NM (TS, _ARRAY_T) * _NM (TS, _assign) (_NM (TS, _ARRAY_T) * this, T *
_S,
size_t _N, size_t _D)
{
size_t _I;
_NM (TS, _Grow) (this, _N, 0, 1);
for (_I = 0; _I < _N; ++_I, _S += _D)
Tassign (this->_Ptr + _I, _S);
return this;
}
_NM (TS, _ARRAY_T) * _NM (TS, _insert) (_NM (TS, _ARRAY_T) * this,
size_t _P,
T * _S, size_t _N, size_t _D)
{
size_t _I;
if (this->_Len < _P)
_NM (TS, _Xran) ();
if (NPOS - this->_Len <= _N)
_NM (TS, _Xlen) ();
if (0 < _N)
{
_I = this->_Len - _P;
for (_NM (TS, _Grow) (this, _N + this->_Len, 0, 0); 0 < _I
{
--_I;
Tassign (this->_Ptr + (_P + _N + _I), this->_Ptr + (_P +
_I));
}
for (_I = 0; _I < _N; ++_I, _S += _D)
Tassign (this->_Ptr + (_P + _I), _S);
}
return this;
}
_NM (TS, _ARRAY_T) * _NM (TS, _remove) (_NM (TS, _ARRAY_T) * this,
size_t _P,
size_t _N)
{
size_t _M, _I;
if (this->_Len < _P)
_NM (TS, _Xran) ();
if (this->_Len - _P < _N)
_N = this->_Len - _P;
if (0 < _N)
{
_M = this->_Len - _P - _N;
for (_I = 0; _I < _M; ++_I)
Tassign (this->_Ptr + (_P + _I), this->_Ptr + (_P + _I + _N));
_NM (TS, _Grow) (this, this->_Len - _N, 0, 0);
}
return this;
}
_NM (TS, _ARRAY_T) * _NM (TS, _subarray) (_NM (TS, _ARRAY_T) * this,
_NM (TS, _ARRAY_T) * _X,
size_t _P,
size_t _N)
{
if (this->_Len < _P)
_NM (TS, _Xran) ();
if (this->_Len - _P < _N)
_N = this->_Len - _P;
return this == _X ? (_NM (TS, _remove) (this, _P + _N, NPOS),
_NM (TS, _remove) (this, 0, _P))
: _NM (TS, _assign) (_X, this->_Ptr + _P, _N, 1);
}
void _NM (TS, _swap) (_NM (TS, _ARRAY_T) * this, _NM (TS, _ARRAY_T) *
_X)
{
T *_Tp;
size_t _T;
_Tp = this->_Ptr;
this->_Ptr = _X->_Ptr;
_X->_Ptr = _Tp;
_T = this->_Len;
this->_Len = _X->_Len;
_X->_Len = _T;
_T = this->_Res;
this->_Res = _X->_Res;
_X->_Res = _T;
}
T *_NM (TS, _get_at) (_NM (TS, _ARRAY_T) * this, size_t _I)
{
if (this->_Len <= _I)
_NM (TS, _Xran) ();
return this->_Ptr + _I;
}
void _NM (TS, _put_at) (_NM (TS, _ARRAY_T) * this, size_t _I, T * _X)
{
if (this->_Len < _I)
_NM (TS, _Xran) ();
else if (this->_Len == _I)
_NM (TS, _append) (this, _X, 1, 1);
else
Tassign (this->_Ptr + _I, _X);
}
T *_NM (TS, _base) (_NM (TS, _ARRAY_T) * this)
{
return this->_Len != 0 ? this->_Ptr : 0;
}
size_t _NM (TS, _length) (_NM (TS, _ARRAY_T) * this)
{
return this->_Len;
}
void _NM (TS, _resize) (_NM (TS, _ARRAY_T) * this, size_t _N, T * _X)
{
_NM (TS, _Grow) (this, _N, _X, 1);
}
size_t _NM (TS, _reserve) (_NM (TS, _ARRAY_T) * this)
{
return this->_Res;
}
void _NM (TS, _set_reserve) (_NM (TS, _ARRAY_T) * this, size_t _R)
{
if (this->_Ptr == 0)
this->_Res = _R;
}
#endif
#undef _NM
#undef _VAL
/* END OF FILE */
/* dynamic string function header
AUTHOR: Gregory Pietsch
*/
#ifndef DYNSTR_H
#define DYNSTR_H
#include "defines.h"
typedef struct STRING_T
{
char *ptr;
size_t len, res;
} STRING_T;
/* exported functions */
void DSctor (STRING_T * this);
void DSctor_with_size (STRING_T * this, size_t n, capacity c);
void DSdtor (STRING_T * this);
STRING_T *DScreate (void);
void DSdestroy (STRING_T * this);
STRING_T *DSappendchar (STRING_T * this, int c, size_t nr);
STRING_T *DSappendcstr (STRING_T * this, char *s, size_t ns);
STRING_T *DSappend (STRING_T * this, STRING_T * str, size_t pos,
size_t ns);
STRING_T *DSassignchar (STRING_T * this, int c, size_t n);
STRING_T *DSassigncstr (STRING_T * this, char *s, size_t n);
STRING_T *DSassign (STRING_T * this, STRING_T * str, size_t pos,
size_t ns);
STRING_T *DSinsertchar (STRING_T * this, size_t p0, int c, size_t nr);
STRING_T *DSinsertcstr (STRING_T * this, size_t p0, char *s, size_t
ns);
STRING_T *DSinsert (STRING_T * this, size_t p0, STRING_T * str, size_t
pos,
size_t ns);
STRING_T *DSremove (STRING_T * this, size_t p0, size_t nr);
STRING_T *DSreplacechar (STRING_T * this, size_t p0, size_t n0, int c,
size_t nr);
STRING_T *DSreplacecstr (STRING_T * this, size_t p0, size_t n0, char
*s,
size_t ns);
STRING_T *DSreplace (STRING_T * this, size_t p0, size_t n0, STRING_T *
str,
size_t pos, size_t ns);
int DSget_at (STRING_T * this, size_t p0);
void DSput_at (STRING_T * this, size_t p0, int c);
size_t DScopy (STRING_T * this, char *s, size_t n, size_t p0);
size_t DSfind (STRING_T * this, char *s, size_t p0, size_t n);
size_t DSrfind (STRING_T * this, char *s, size_t p0, size_t n);
size_t DSfind_first_of (STRING_T * this, char *s, size_t p0, size_t
n);
size_t DSfind_last_of (STRING_T * this, char *s, size_t p0, size_t n);
size_t DSfind_first_not_of (STRING_T * this, char *s, size_t p0,
size_t n);
size_t DSfind_last_not_of (STRING_T * this, char *s, size_t p0, size_t
n);
int DScomparechar (STRING_T * this, int c, size_t p0, size_t ns);
int DScomparecstr (STRING_T * this, char *s, size_t p0, size_t ns);
int DScompare (STRING_T * this, STRING_T * str, size_t p0, size_t ns);
char *DScstr (STRING_T * this);
size_t DSlength (STRING_T * this);
void DSresize (STRING_T * this, size_t n, int c);
size_t DSreserve (STRING_T * this);
void DSset_reserve (STRING_T * this, size_t n);
STRING_T *DSsubstr (STRING_T * this, size_t p, size_t n);
#define T STRING_T
#define TS DAS
#define Tassign(x,y) DSassign(x,y,0,NPOS)
#define Tctor(x) DSctor(x)
#define Tdtor(x) DSdtor(x)
#define PROTOS_ONLY
#include "dynarray.h"
#undef T
#undef TS
#undef Tassign
#undef Tctor
#undef Tdtor
#undef PROTOS_ONLY
#endif
/* END OF FILE */
/* dynstr.c -- dynamic string functions
AUTHOR: Gregory Pietsch
*/
/* includes */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "defines.h"
#include "dynstr.h"
/* macros */
#define MIN_SIZE 31
/* typedefs */
/* functions */
static void
DStidy (STRING_T * this, int constructed)
{
if (constructed && this->ptr)
free (this->ptr);
this->ptr = 0;
this->len = 0;
this->res = 0;
}
static int
DSgrow (STRING_T * this, size_t n, int trim)
{
size_t osize = this->ptr == 0 ? 0 : this->res;
size_t size;
char *s;
if (n == 0)
{
if (trim && MIN_SIZE < osize)
DStidy (this, 1);
else if (this->ptr)
this->ptr[this->len = 0] = '\0';
return 0;
}
else if (n == osize || n < osize && !trim)
return 1;
else
{
size = this->ptr == 0 && n < this->res ? this->res : n;
if ((size |= MIN_SIZE) == NPOS)
--size;
if ((s = (char *) realloc (this->ptr, size + 1)) == 0
&& (s = (char *) realloc (this->ptr, (size = n) + 1)) == 0)
Nomemory ();
this->ptr = s;
this->res = size;
return 1;
}
}
static void
DSxlen (void)
{
fputs ("string too long\n", stderr);
abort ();
}
static void
DSxran (void)
{
fputs ("invalid string position\n", stderr);
abort ();
}
/* exported functions */
void
DSctor (STRING_T * this)
{
DStidy (this, 0);
}
void
DSctor_with_size (STRING_T * this, size_t n, capacity c)
{
DStidy (this, 0);
this->res = n;
if (c == default_size)
DSassignchar (this, '\0', n);
}
void
DSdtor (STRING_T * this)
{
DStidy (this, 1);
}
STRING_T *
DScreate (void)
{
STRING_T *this = malloc (sizeof (STRING_T));
if (this == 0)
Nomemory ();
DSctor (this);
return this;
}
void
DSdestroy (STRING_T * this)
{
DSdtor (this);
free (this);
}
STRING_T *
DSappendchar (STRING_T * this, int c, size_t nr)
{
size_t n;
if (NPOS - this->len <= nr)
DSxlen ();
if (0 < nr && DSgrow (this, n = this->len + nr, 0))
{
memset (this->ptr + this->len, c, nr);
this->ptr[this->len = n] = '\0';
}
return this;
}
STRING_T *
DSappendcstr (STRING_T * this, char *s, size_t ns)
{
size_t n;
if (ns == NPOS)
ns = strlen (s);
if (NPOS - this->len <= ns)
DSxlen ();
if (0 < ns && DSgrow (this, n = this->len + ns, 0))
{
memcpy (this->ptr + this->len, s, ns);
this->ptr[this->len = n] = '\0';
}
return this;
}
STRING_T *
DSappend (STRING_T * this, STRING_T * str, size_t pos, size_t ns)
{
size_t n;
if (DSlength (str) < pos)
DSxran ();
n = DSlength (str) - pos;
if (n < ns)
ns = n;
if (NPOS - this->len <= ns)
DSxlen ();
if (0 < ns && DSgrow (this, n = this->len + ns, 0))
{
memcpy (this->ptr + this->len, DScstr (str) + pos, ns);
this->ptr[this->len = n] = '\0';
}
return this;
}
STRING_T *
DSassignchar (STRING_T * this, int c, size_t n)
{
if (n == NPOS)
DSxlen ();
if (DSgrow (this, n, 1))
{
memset (this->ptr, c, n);
this->ptr[this->len = n] = '\0';
}
return this;
}
STRING_T *
DSassigncstr (STRING_T * this, char *s, size_t n)
{
if (n == NPOS)
n = strlen (s);
if (DSgrow (this, n, 1))
{
memcpy (this->ptr, s, n);
this->ptr[this->len = n] = '\0';
}
return this;
}
STRING_T *
DSassign (STRING_T * this, STRING_T * str, size_t pos, size_t ns)
{
size_t n;
if (DSlength (str) < pos)
DSxran ();
n = DSlength (str) - pos;
if (ns < n)
n = ns;
if (this == str)
{
DSremove (this, pos + n, NPOS);
DSremove (this, 0, pos);
}
else if (DSgrow (this, n, 1))
{
memcpy (this->ptr, DScstr (str) + pos, n);
this->ptr[this->len = n] = '\0';
}
return this;
}
STRING_T *
DSinsertchar (STRING_T * this, size_t p0, int c, size_t nr)
{
size_t n;
if (this->len < p0)
DSxran ();
if (NPOS - this->len <= nr)
DSxlen ();
if (0 < nr && DSgrow (this, n = this->len + nr, 0))
{
memmove (this->ptr + (p0 + nr), this->ptr + p0, this->len - p0);
memset (this->ptr + p0, c, nr);
this->ptr[this->len = n] = '\0';
}
return this;
}
STRING_T *
DSinsertcstr (STRING_T * this, size_t p0, char *s, size_t ns)
{
size_t n;
if (this->len < p0)
DSxran ();
if (ns == NPOS)
ns = strlen (s);
if (NPOS - this->len <= ns)
DSxlen ();
if (0 < ns && DSgrow (this, n = this->len + ns, 0))
{
memmove (this->ptr + (p0 + ns), this->ptr + p0, this->len - p0);
memcpy (this->ptr + p0, s, ns);
this->ptr[this->len = n] = '\0';
}
return this;
}
STRING_T *
DSinsert (STRING_T * this, size_t p0, STRING_T * str, size_t pos,
size_t ns)
{
size_t n;
if (this->len < p0 || DSlength (str) < pos)
DSxran ();
n = DSlength (str) - pos;
if (n < ns)
ns = n;
if (NPOS - this->len <= ns)
DSxlen ();
if (0 < ns && DSgrow (this, n = this->len + ns, 0))
{
memmove (this->ptr + (p0 + ns), this->ptr + p0, this->len - p0);
memcpy (this->ptr + p0, DScstr (str) + pos, ns);
this->ptr[this->len = n] = '\0';
}
return this;
}
STRING_T *
DSremove (STRING_T * this, size_t p0, size_t nr)
{
size_t n;
if (this->len < p0)
DSxran ();
if (this->len - p0 < nr)
nr = this->len - p0;
if (0 < nr)
{
memmove (this->ptr + p0, this->ptr + (p0 + nr), this->len - p0 -
nr);
n = this->len - nr;
if (DSgrow (this, n, 0))
this->ptr[this->len = n] = '\0';
}
return this;
}
STRING_T *
DSreplacechar (STRING_T * this, size_t p0, size_t n0, int c, size_t
nr)
{
size_t n, nm;
if (this->len < p0)
DSxran ();
if (this->len - p0 < n0)
n0 = this->len - p0;
if (NPOS - nr <= this->len - n0)
DSxlen ();
nm = this->len - n0 - p0;
if (nr < n0)
memmove (this->ptr + (p0 + nr), this->ptr + (p0 + n0), nm);
if ((0 < nr || 0 < n0) && DSgrow (this, n = this->len + nr - n0, 0))
{
if (n0 < nr)
memmove (this->ptr + (p0 + nr), this->ptr + (p0 + n0), nm);
memset (this->ptr + p0, c, nr);
this->ptr[this->len = n] = '\0';
}
return this;
}
STRING_T *
DSreplacecstr (STRING_T * this, size_t p0, size_t n0, char *s, size_t
ns)
{
size_t n, nm;
if (this->len < p0)
DSxran ();
if (ns == NPOS)
ns = strlen (s);
if (NPOS - ns <= this->len - n0)
DSxlen ();
nm = this->len - n0 - p0;
if (ns < n0)
memmove (this->ptr + (p0 + ns), this->ptr + (p0 + n0), nm);
if ((0 < ns || 0 < n0) && DSgrow (this, n = this->len + ns - n0, 0))
{
if (n0 < ns)
memmove (this->ptr + (p0 + ns), this->ptr + (p0 + n0), nm);
memcpy (this->ptr + p0, s, ns);
this->ptr[this->len = n] = '\0';
}
return this;
}
STRING_T *
DSreplace (STRING_T * this, size_t p0, size_t n0, STRING_T * str,
size_t pos, size_t ns)
{
size_t n, nm;
if (this->len < p0 || DSlength (str) < pos)
DSxran ();
n = DSlength (str) - pos;
if (n < ns)
ns = n;
if (NPOS - ns <= this->len - n0)
DSxlen ();
nm = this->len - n0 - p0;
if (ns < n0)
memmove (this->ptr + (p0 + ns), this->ptr + (p0 + n0), nm);
if ((0 < ns || 0 < n0) && DSgrow (this, n = this->len + ns - n0, 0))
{
if (n0 < ns)
memmove (this->ptr + (p0 + ns), this->ptr + (p0 + n0), nm);
memcpy (this->ptr + p0, DScstr (str) + pos, ns);
this->ptr[this->len = n] = '\0';
}
return this;
}
int
DSget_at (STRING_T * this, size_t p0)
{
if (this->len <= p0)
DSxran ();
return this->ptr[p0];
}
void
DSput_at (STRING_T * this, size_t p0, int c)
{
if (this->len < p0)
DSxran ();
else if (this->len == p0)
DSappendchar (this, c, 1);
else
this->ptr[p0] = c;
}
size_t
DScopy (STRING_T * this, char *s, size_t n, size_t p0)
{
if (this->len < p0)
DSxran ();
if (this->len - p0 < n)
n = this->len - p0;
memcpy (s, this->ptr + p0, n);
return n;
}
size_t
DSfind (STRING_T * this, char *s, size_t p0, size_t n)
{
size_t nmax;
char *t, *u;
if (n == 0 || n == NPOS && (n = strlen (s)) == 0)
return 0;
if (p0 < this->len && n <= (nmax = this->len - p0))
{
for (nmax -= n - 1, u = this->ptr + p0;
(t = (char *) memchr (u, *s, nmax)) != 0;
nmax -= t - u + 1, u = t + 1)
if (memcmp (t, s, n) == 0)
return t - this->ptr;
}
return NPOS;
}
size_t
DSrfind (STRING_T * this, char *s, size_t p0, size_t n)
{
char *t;
if (n == 0 || n == NPOS && (n = strlen (s)) == 0)
return 0;
if (n <= this->len)
for (t = this->ptr + (p0 < this->len - n ? p0 : this->len - n);;
--t)
if (*t == *s && memcmp (t, s, n) == 0)
return t - this->ptr;
else if (t == this->ptr)
break;
return NPOS;
}
size_t
DSfind_first_of (STRING_T * this, char *s, size_t p0, size_t n)
{
char *t, *u;
if (n == 0 || n == NPOS && (n = strlen (s)) == 0)
return 0;
if (p0 < this->len)
{
u = this->ptr + this->len;
for (t = this->ptr + p0; t < u; t++)
if (memchr (s, *t, n) != 0)
return t - this->ptr;
}
return NPOS;
}
size_t
DSfind_last_of (STRING_T * this, char *s, size_t p0, size_t n)
{
char *t;
if (n == 0 || n == NPOS && (n = strlen (s)) == 0)
return 0;
if (0 < this->len)
for (t = this->ptr + (p0 < this->len ? p0 : this->len - 1);; t--)
if (memchr (s, *t, n) != 0)
return t - this->ptr;
else if (t == this->ptr)
break;
return NPOS;
}
size_t
DSfind_first_not_of (STRING_T * this, char *s, size_t p0, size_t n)
{
char *t, *u;
if (n == 0 || n == NPOS && (n = strlen (s)) == 0)
return 0;
if (p0 < this->len)
{
u = this->ptr + this->len;
for (t = this->ptr + p0; t < u; t++)
if (memchr (s, *t, n) == 0)
return t - this->ptr;
}
return NPOS;
}
size_t
DSfind_last_not_of (STRING_T * this, char *s, size_t p0, size_t n)
{
char *t;
if (n == 0 || n == NPOS && (n = strlen (s)) == 0)
return 0;
if (0 < this->len)
for (t = this->ptr + (p0 < this->len ? p0 : this->len - 1);; t--)
if (memchr (s, *t, n) == 0)
return t - this->ptr;
else if (t == this->ptr)
break;
return NPOS;
}
int
DScomparechar (STRING_T * this, int c, size_t p0, size_t ns)
{
size_t n;
char *s, *t;
if (this->len < p0)
DSxran ();
n = this->len - p0;
for (s = this->ptr + p0, t = s + (n < ns ? n : ns); s < t; s++)
if (*s != c)
return (*(unsigned char *) s < (unsigned char) c ? -1 : 1);
return (n < ns ? -1 : n > ns);
}
int
DScomparecstr (STRING_T * this, char *s, size_t p0, size_t ns)
{
size_t n;
int ans;
if (this->len < p0)
DSxran ();
n = this->len - p0;
if (ns == NPOS)
ns = strlen (s);
ans = memcmp (this->ptr + p0, s, n < ns ? n : ns);
return ans ? ans : n < ns ? -1 : n > ns;
}
int
DScompare (STRING_T * this, STRING_T * str, size_t p0, size_t ns)
{
size_t n;
int ans;
if (this->len < p0)
DSxran ();
n = this->len - p0;
if (DSlength (str) < ns)
ns = DSlength (str);
ans = memcmp (this->ptr + p0, DScstr (str), n < ns ? n : ns);
return ans ? ans : n < ns ? -1 : n > ns;
}
char *
DScstr (STRING_T * this)
{
return this->ptr ? this->ptr : "";
}
size_t
DSlength (STRING_T * this)
{
return this->len;
}
void
DSresize (STRING_T * this, size_t n, int c)
{
if (n < this->len)
DSremove (this, n, NPOS);
else
DSappendchar (this, c, n - this->len);
}
size_t
DSreserve (STRING_T * this)
{
return this->res;
}
void
DSset_reserve (STRING_T * this, size_t n)
{
if (this->ptr == 0)
this->res = n;
}
STRING_T *
DSsubstr (STRING_T * this, size_t p, size_t n)
{
STRING_T *s = DScreate ();
DSassign (s, this, p, n);
return s;
}
#define T STRING_T
#define TS DAS
#define Tassign(x,y) DSassign(x,y,0,NPOS)
#define Tctor(x) DSctor(x)
#define Tdtor(x) DSdtor(x)
#undef PROTOS_ONLY
#include "dynarray.h"
#undef T
#undef TS
#undef Tassign
#undef Tctor
#undef Tdtor
/* END OF FILE */
Gregory Pietsch