* Added sv_split to strlib.c/h (similar to sv_parse).

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@12459 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
FlavioJS 2008-04-02 15:55:15 +00:00
parent a6de8bacab
commit bc272fbc39
2 changed files with 104 additions and 10 deletions

View File

@ -367,14 +367,13 @@ int strline(const char* str, size_t pos)
/////////////////////////////////////////////////////////////////////
/// Parses a delim-separated string.
/// Starts parsing at startoff and fills the out_pos array with the start and
/// end positions in the string of the line and fields (that fit the array).
/// Returns the number of fields or -1 if an error occurs.
/// Starts parsing at startoff and fills the pos array with position pairs.
/// out_pos[0] and out_pos[1] are the start and end of line.
/// Other position pairs are the start and end of fields.
/// Returns the number of fields found or -1 if an error occurs.
///
/// out_pos can be NULL.
/// Positions out_pos[0] and out_pos[1] are for the line start and end
/// positions. If a line terminator is found, the end position is placed there.
/// The next values of the array are the start and end positions of the fields.
/// If a line terminator is found, the end position is placed there.
/// out_pos[2] and out_pos[3] for the first field, out_pos[4] and out_pos[5]
/// for the seconds field and so on.
/// Unfilled positions are set to -1.
@ -386,7 +385,7 @@ int strline(const char* str, size_t pos)
/// @param out_pos Array of resulting positions
/// @param npos Size of the pos array
/// @param opt Options that determine the parsing behaviour
/// @return Number of fields in the string or -1 if an error occured
/// @return Number of fields found in the string or -1 if an error occured
int sv_parse(const char* str, int len, int startoff, char delim, int* out_pos, int npos, enum e_svopt opt)
{
int i;
@ -533,6 +532,92 @@ int sv_parse(const char* str, int len, int startoff, char delim, int* out_pos, i
return count;
}
/// Splits a delim-separated string.
/// WARNING: this function modifies the input string
/// Starts splitting at startoff and fills the out_fields array.
/// out_fields[0] is the start of the next line.
/// Other entries are the start of fields (nul-teminated).
/// Returns the number of fields found or -1 if an error occurs.
///
/// out_fields can be NULL.
/// Fields that don't fit in out_fields are not nul-terminated.
/// Extra entries in out_fields are filled with the end of line (empty string).
///
/// @param str String to parse
/// @param len Length of the string
/// @param startoff Where to start parsing
/// @param delim Field delimiter
/// @param out_fields Array of resulting fields
/// @param nfields Size of the field array
/// @param opt Options that determine the parsing behaviour
/// @return Number of fields found in the string or -1 if an error occured
int sv_split(char* str, int len, int startoff, char delim, char** out_fields, int nfields, enum e_svopt opt)
{
int pos[1024];
int i;
int done;
char* eol;
int ret = sv_parse(str, len, startoff, delim, pos, ARRAYLENGTH(pos), opt);
if( ret == -1 || out_fields == NULL || nfields <= 0 )
return ret; // nothing to do
// next line
eol = str + pos[1];
if( eol[0] == '\0' )
{
*out_fields = eol;
}
else if( (opt&SV_TERMINATE_LF) && eol[0] == '\n' )
{
eol[0] = '\0';
*out_fields = eol + 1;
}
else if( (opt&SV_TERMINATE_CRLF) && eol[0] == '\r' && eol[1] == '\n' )
{
eol[0] = eol[1] = '\0';
*out_fields = eol + 2;
}
else if( (opt&SV_TERMINATE_LF) && eol[0] == '\r' )
{
eol[0] = '\0';
*out_fields = eol + 1;
}
else
{
ShowError("sv_split: unknown line delimiter 0x02%x.\n", (unsigned char)eol[0]);
return -1;// error
}
++out_fields;
--nfields;
// fields
i = 2;
done = 0;
while( done < ret && nfields > 0 )
{
if( i < ARRAYLENGTH(pos) )
{// split field
*out_fields = str + pos[i];
str[pos[i+1]] = '\0';
// next field
i += 2;
++done;
++out_fields;
--nfields;
}
else
{// get more fields
sv_parse(str, len, pos[i-1] + 1, delim, pos, ARRAYLENGTH(pos), opt);
i = 2;
}
}
// remaining fields
for( i = 0; i < nfields; ++i )
out_fields[i] = eol;
return ret;
}
/// Escapes src to out_dest according to the format of the C compiler.
/// Returns the length of the escaped string.
/// out_dest should be len*4+1 in size.

View File

@ -65,11 +65,20 @@ typedef enum e_svopt
#define SV_ESCAPE_C_SUPPORTED "abtnvfr\?\"'\\"
/// Parses a delim-separated string.
/// Starts parsing at startoff and fills the pos array with the start and end
/// positions in the string of the line and fields (that fit the array).
/// Returns the number of fields or -1 if an error occurs.
/// Starts parsing at startoff and fills the pos array with position pairs.
/// out_pos[0] and out_pos[1] are the start and end of line.
/// Other position pairs are the start and end of fields.
/// Returns the number of fields found or -1 if an error occurs.
int sv_parse(const char* str, int len, int startoff, char delim, int* out_pos, int npos, enum e_svopt opt);
/// Splits a delim-separated string.
/// WARNING: this function modifies the input string
/// Starts splitting at startoff and fills the out_fields array.
/// out_fields[0] is the start of the next line.
/// Other entries are the start of fields (nul-teminated).
/// Returns the number of fields found or -1 if an error occurs.
int sv_split(char* str, int len, int startoff, char delim, char** out_fields, int nfields, enum e_svopt opt);
/// Escapes src to out_dest according to the format of the C compiler.
/// Returns the length of the escaped string.
/// out_dest should be len*4+1 in size.