]> git.proxmox.com Git - mirror_corosync-qdevice.git/blob - qdevices/dynar-getopt-lex.c
Initial import from corosync codebase
[mirror_corosync-qdevice.git] / qdevices / dynar-getopt-lex.c
1 /*
2 * Copyright (c) 2015-2016 Red Hat, Inc.
3 *
4 * All rights reserved.
5 *
6 * Author: Jan Friesse (jfriesse@redhat.com)
7 *
8 * This software licensed under BSD license, the text of which follows:
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
12 *
13 * - Redistributions of source code must retain the above copyright notice,
14 * this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 * - Neither the name of the Red Hat, Inc. nor the names of its
19 * contributors may be used to endorse or promote products derived from this
20 * software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32 * THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 #include <string.h>
36
37 #include "dynar-getopt-lex.h"
38
39 void
40 dynar_getopt_lex_init(struct dynar_getopt_lex *lex, struct dynar *input)
41 {
42
43 memset(lex, 0, sizeof(*lex));
44 lex->input = input;
45 dynar_init(&lex->option, dynar_max_size(input));
46 dynar_init(&lex->value, dynar_max_size(input));
47 }
48
49 void
50 dynar_getopt_lex_destroy(struct dynar_getopt_lex *lex)
51 {
52
53 dynar_destroy(&lex->option);
54 dynar_destroy(&lex->value);
55 memset(lex, 0, sizeof(*lex));
56 }
57
58 /*
59 * 0 - no error
60 * -1 - Can't add character
61 */
62 int
63 dynar_getopt_lex_token_next(struct dynar_getopt_lex *lex)
64 {
65 size_t pos;
66 size_t size;
67 char *str;
68 char ch;
69 int state;
70
71 dynar_clean(&lex->option);
72 dynar_clean(&lex->value);
73
74 size = dynar_size(lex->input);
75 str = dynar_data(lex->input);
76
77 state = 1;
78 pos = lex->pos;
79
80 while (state != 0 && pos < size) {
81 ch = str[pos];
82
83 switch (state) {
84 case 1:
85 /*
86 * Read option name, wait for = or ,
87 */
88 if (ch == '=') {
89 pos++;
90 state = 2;
91 } else if (ch == ',') {
92 pos++;
93 state = 0;
94 } else {
95 pos++;
96 if (dynar_cat(&lex->option, &ch, sizeof(ch)) != 0) {
97 return (-1);
98 }
99 }
100 break;
101 case 2:
102 /*
103 * Wait for end of str or ,
104 */
105 if (ch == ',') {
106 pos++;
107 state = 0;
108 } else {
109 pos++;
110 if (dynar_cat(&lex->value, &ch, sizeof(ch)) != 0) {
111 return (-1);
112 }
113 }
114 break;
115 }
116 }
117
118 ch = '\0';
119 if (dynar_cat(&lex->option, &ch, sizeof(ch)) != 0) {
120 return (-1);
121 }
122 if (dynar_cat(&lex->value, &ch, sizeof(ch)) != 0) {
123 return (-1);
124 }
125
126 lex->pos = pos;
127
128 return (0);
129 }