[misc] Add missing initializer in _error_default struct instance.
[vsc-common.git] / cli / token.c
1 /*
2  * token.c: Library for interactive commandline interfaces
3  *
4  * Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
19  */
20
21 /*!
22  * @file
23  */
24
25 #include <libvscmisc/assert.h>
26 #include <libvscmisc/error.h>
27 #include <libvscmisc/memory.h>
28
29 #include "token.h"
30
31 void
32 _vsc_cli_token_parse (struct VscError *error, const char *input, char **token,
33                       const char **input_tail)
34 {
35         const char *ptr = input;
36         int quote = FALSE;
37         const char *start = NULL;
38         int length = 0;
39
40         VSC__ASSERT (error != NULL);
41         VSC__ASSERT (! error->occured);
42         VSC__ASSERT (input != NULL);
43         VSC__ASSERT (token != NULL);
44         VSC__ASSERT (input_tail != NULL);
45
46         *token = NULL;
47
48         while (ptr != NULL && *ptr != '\0' && (*ptr == ' ' || *ptr == '\t')) {
49                 ++ptr;
50         }
51
52         if (ptr == NULL || *ptr == '\0') {
53                 *input_tail = NULL;
54                 return;
55         }
56
57         if (*ptr == ',') {
58                 *input_tail = ++ptr;
59                 return;
60         }
61
62         while (*ptr != '\0') {
63                 if (quote == FALSE && (*ptr == ' ' || *ptr == '\t' || *ptr == ',')) {
64                         break;
65                 }
66
67                 if (*ptr == '"') {
68                         ++ptr;
69
70                         if (! quote) {
71                                 quote = TRUE;
72                         } else {
73                                 quote = FALSE;
74                                 break;
75                         }
76                 }
77
78                 if (start == NULL) {
79                         start = ptr;
80                 }
81
82                 ++ptr;
83                 ++length;
84         }
85
86         if (quote) {
87                 VSC__ERROR1 (error, VSC__ERROR_CODE__INTERNAL_ERROR,
88                              "Input is malformed, missing \"");
89                 return;
90         }
91
92         *input_tail = ptr;
93
94         if (start == NULL || *start == '\0' || length == 0) {
95                 return;
96         }
97
98         *token = vsc_alloc (error, length + 1);
99
100         if (error->occured) {
101                 VSC__APPEND_ERROR0 (error, VSC__ERROR_CODE__TRACE);
102                 return;
103         }
104
105         memcpy (*token, start, length);
106         (*token)[length] = '\0';
107 }