1 /**
2 * \file mlt_tokeniser.c
3 * \brief string tokeniser
4 * \see mlt_tokeniser_s
5 *
6 * Copyright (C) 2002-2014 Meltytech, LLC
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 /* System header files */
24 #include <stdlib.h>
25 #include <string.h>
26
27 /* Application header files */
28 #include "mlt_tokeniser.h"
29
30 /** Initialise a tokeniser.
31 */
32
mlt_tokeniser_init()33 mlt_tokeniser mlt_tokeniser_init( )
34 {
35 mlt_tokeniser tokeniser = calloc( 1, sizeof( mlt_tokeniser_t ) );
36 tokeniser->input = NULL;
37 tokeniser->tokens = NULL;
38 tokeniser->count = 0;
39 tokeniser->size = 0;
40 return tokeniser;
41 }
42
43 /** Clear the tokeniser.
44 */
45
mlt_tokeniser_clear(mlt_tokeniser tokeniser)46 static void mlt_tokeniser_clear( mlt_tokeniser tokeniser )
47 {
48 int index = 0;
49 for ( index = 0; index < tokeniser->count; index ++ )
50 free( tokeniser->tokens[ index ] );
51 tokeniser->count = 0;
52 free( tokeniser->input );
53 tokeniser->input = NULL;
54 }
55
56 /** Append a string to the tokeniser.
57 */
58
mlt_tokeniser_append(mlt_tokeniser tokeniser,char * token)59 static int mlt_tokeniser_append( mlt_tokeniser tokeniser, char *token )
60 {
61 int error = 0;
62
63 if ( tokeniser->count == tokeniser->size )
64 {
65 tokeniser->size += 20;
66 tokeniser->tokens = realloc( tokeniser->tokens, tokeniser->size * sizeof( char * ) );
67 }
68
69 if ( tokeniser->tokens != NULL )
70 {
71 tokeniser->tokens[ tokeniser->count ++ ] = strdup( token );
72 }
73 else
74 {
75 tokeniser->count = 0;
76 error = -1;
77 }
78 return error;
79 }
80
81 /** Parse a string by splitting on the delimiter provided.
82 */
83
mlt_tokeniser_parse_new(mlt_tokeniser tokeniser,char * string,const char * delimiter)84 int mlt_tokeniser_parse_new( mlt_tokeniser tokeniser, char *string, const char *delimiter )
85 {
86 if ( !string || !delimiter ) return 0;
87 int count = 0;
88 int length = strlen( string );
89 int delimiter_size = strlen( delimiter );
90 int index = 0;
91 char *token = strdup( string );
92
93 mlt_tokeniser_clear( tokeniser );
94 tokeniser->input = strdup( string );
95 strcpy( token, "" );
96
97 for ( index = 0; index < length; )
98 {
99 char *start = string + index;
100 char *end = strstr( start, delimiter );
101
102 if ( end == NULL )
103 {
104 strcat( token, start );
105 mlt_tokeniser_append( tokeniser, token );
106 index = length;
107 count ++;
108 }
109 else if ( start != end )
110 {
111 strncat( token, start, end - start );
112 index += end - start;
113 if ( strchr( token, '\"' ) == NULL || token[ strlen( token ) - 1 ] == '\"' )
114 {
115 mlt_tokeniser_append( tokeniser, token );
116 strcpy( token, "" );
117 count ++;
118 }
119 else while ( strncmp( string + index, delimiter, delimiter_size ) == 0 )
120 {
121 strncat( token, delimiter, delimiter_size );
122 index += delimiter_size;
123 }
124 }
125 else
126 {
127 index += delimiter_size;
128 }
129 }
130
131 /* Special case - malformed string condition */
132 if ( !strcmp( token, "" ) )
133 {
134 count = 0 - ( count - 1 );
135 mlt_tokeniser_append( tokeniser, token );
136 }
137
138 free( token );
139 return count;
140 }
141
142 /** Get the original input.
143 */
144
mlt_tokeniser_get_input(mlt_tokeniser tokeniser)145 char *mlt_tokeniser_get_input( mlt_tokeniser tokeniser )
146 {
147 return tokeniser->input;
148 }
149
150 /** Get the number of tokens.
151 */
152
mlt_tokeniser_count(mlt_tokeniser tokeniser)153 int mlt_tokeniser_count( mlt_tokeniser tokeniser )
154 {
155 return tokeniser->count;
156 }
157
158 /** Get a token as a string.
159 */
160
mlt_tokeniser_get_string(mlt_tokeniser tokeniser,int index)161 char *mlt_tokeniser_get_string( mlt_tokeniser tokeniser, int index )
162 {
163 if ( index < tokeniser->count )
164 return tokeniser->tokens[ index ];
165 else
166 return NULL;
167 }
168
169 /** Close the tokeniser.
170 */
171
mlt_tokeniser_close(mlt_tokeniser tokeniser)172 void mlt_tokeniser_close( mlt_tokeniser tokeniser )
173 {
174 mlt_tokeniser_clear( tokeniser );
175 free( tokeniser->tokens );
176 free( tokeniser );
177 }
178