blob: 60acc7aa1fbcae6f674c499140697c8d583779fd [file] [log] [blame]
// Copyright 2011 Google Inc. All Rights Reserved.
// Author: qianzhang@google.com (ken Zhang)
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "channel_buffer.h"
#include "utility.h"
#define sage_log(x) _sagelog x
void _sagelog( int type, int level, const char* cstr, ... );
static const char* delimiter = " \t,;\r\n:=|'\"#";
static int is_delimiter( char ch )
{
int i;
if ( ch == 0 ) return 1;
for ( i = 0; delimiter[i]; i++ )
if ( ch == delimiter[i] ) return 1;
return 0;
}
//format name:zzz (or name=zzzz)
int get_string_by_name( char*p, const char* name, char* string, int max_len, char **next )
{
char *s, *e;
e = p;
while ( e != NULL && *e ) {
s = strstr( e, name );
if ( s == NULL )
return 0;
//is a token name
if ( ((s > p && is_delimiter(*(s-1))) || s == p ) && is_delimiter( *(s+strlen(name)) ) ) {
s += (int)strlen(name);
while( *s && ( *s == ' ' || *s == '\t' ) )
s++; //skip white space
if ( *s == '=' || *s == ':' ) {
s++;
while( *s && ( *s == ' ' || *s == '\t' ) )
s++; //skip white space
if ( *s ) {
int i=0;
while ( i++<max_len && *s && *s != ' ' && *s != '\t' && *s != '\n' && *s != '\r')
*string++ = *s++;
*string = 0x0; //terminator
if ( next != NULL ) {
while ( *s && *s != ' ' && *s != '\t' && *s != '\n' && *s != '\r')
s++;
*next = s;
}
return 1;
}
}
}
e = ++s;
}
return 0;
}
//format name:zzz (or name=zzzz)
int get_string_by_token( char*p, int num, char* string, int max_len, char **next )
{
int count = 0;
char *s;
s = p;
if ( s == NULL )
return 0;
while ( *s ) {
while( *s && ( *s == ' ' || *s == '\t' || *s == '\r' || *s == '\n' ) )
s++; //skip white space
if ( *s == 0 )
break;
if ( count++ != num ) {
while( *s && !( *s == ' ' || *s == '\t' || *s == ';' || *s == ',' || *s == '\r' || *s == '\n' ) )
s++; //skip a token
} else {
if ( *s ) {
int i=0;
while ( i++<max_len && *s && !( *s == ' ' || *s == '\t' || *s == ';' || *s == ',' || *s == '\r' || *s == '\n' ) )
*string++ = *s++;
*string = 0x0; //terminator
if ( next != NULL ) {
while ( *s && !( *s == ' ' || *s == '\t' || *s == '\r' || *s == '\n' ) )
s++;
*next = s;
}
return 1;
}
}
if ( *s )
s++;
}
return 0;
}
//format name:"zzz" (or name="zzzz")
int get_quote_string_by_name( char*p, const char* name, char* string, int max_len, char **next )
{
char *s, *e;
e = p;
while ( e != NULL && *e ) {
s = strstr( e, name );
if ( s == NULL ) return 0;
//is a token name
if ( ((s > p && is_delimiter(*(s-1))) || s == p ) && is_delimiter( *(s+strlen(name)) ) ) {
s += (int)strlen(name);
while( *s && ( *s == ' ' || *s == '\t' ) )
s++; //skip white space
if ( *s == '=' || *s == ':' ) {
s++;
while( *s && ( *s == ' ' || *s == '\t' ) )
s++; //skip white space
if ( *s == '\"' ) {
int i=0;
s++;
while ( i++<max_len && *s && *s != '\"' )
*string++ = *s++;
*string = 0x0; //terminator
if ( next != NULL) {
while ( *s && *s != '\"' )
s++;
*next = s+1;
}
return 1;
} else
return 0;
}
}
e = ++s;
}
return 0;
}
int get_int_val_by_name( char*p, const char* name, int* val, char** next )
{
char *s, *e;
e = p;
while( e != NULL && *e ) {
s = strstr( e, name );
if ( s == NULL )
return 0;
//is a token name
if ( ( (s > p && is_delimiter(*(s-1)) ) || s == p ) && is_delimiter( *(s+strlen(name)) ) ) {
s += strlen(name);
while( *s && ( *s == ' ' || *s == '\t' ) )
s++; //skip white space
if ( *s == '=' || *s == ':' ) {
s++;
while( *s && ( *s == ' ' || *s == '\t' ) )
s++; //skip white space
if ( *s ) {
*val = atoi( s );
if (*val < 0 && *s == '-' )
s++;
while( *s >= '0' && *s <= '9')
s++;
if ( next != NULL )
*next = s;
return 1;
}
}
}
e = ++s;
}
return 0;
}
struct channel_list_t* _create_channel_list( int num )
{
if ( num <= 0 )
return NULL;
struct channel_list_t *cl = malloc( sizeof( struct channel_list_t));
if ( cl == NULL )
return NULL;
cl->num = num;
cl->channel_num = 0;
cl->ce = malloc( sizeof(struct channel_entry_t)*num );
if ( cl->ce == NULL ) {
free( cl );
return NULL;
}
memset( cl->ce, 0x0, sizeof(struct channel_entry_t)*num );
return cl;
}
void _release_channel_list( struct channel_list_t *cl )
{
if ( cl ) {
if ( cl->ce )
free( cl->ce );
free( cl );
}
}
struct channel_list_t* _joint_channel_list( struct channel_list_t* cl1, struct channel_list_t* cl2 )
{
int i, n, channel_num;
if ( cl1 == NULL )
return cl2;
if ( cl2 == NULL )
return cl1;
channel_num = cl1->channel_num + cl2->channel_num;
if ( channel_num < cl1->num ) {
n = 0;
for ( i = cl1->channel_num; i<channel_num; i++ )
cl1->ce[i] = cl2->ce[n++];
cl2->channel_num = channel_num;
_release_channel_list( cl2 );
return cl1;
} else if ( channel_num < cl2->num ) {
n = 0;
for ( i = cl2->channel_num; i<channel_num; i++ )
cl2->ce[i] = cl1->ce[n++];
cl2->channel_num = channel_num;
_release_channel_list( cl1 );
return cl2;
} else {
struct channel_list_t* cl = _create_channel_list( channel_num );
for ( i = 0; i<cl1->channel_num; i++ )
cl->ce[i] = cl1->ce[i];
for ( n = 0; n<cl2->channel_num; n++ )
cl->ce[i++] = cl2->ce[n];
_release_channel_list( cl1 );
_release_channel_list( cl2 );
cl->channel_num = channel_num;
return cl;
}
return NULL;
}