| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- /**
- * @file NCDConfigTokenizer.c
- * @author Ambroz Bizjak <ambrop7@gmail.com>
- *
- * @section LICENSE
- *
- * This file is part of BadVPN.
- *
- * BadVPN is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * BadVPN is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
- #include <string.h>
- #include <stddef.h>
- #include <misc/debug.h>
- #include <misc/string_begins_with.h>
- #include <ncdconfig/NCDConfigTokenizer.h>
- static int is_name_char (char c)
- {
- return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_');
- }
- static int is_name_first_char (char c)
- {
- return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_');
- }
- static int is_space_char (char c)
- {
- return (c == ' ' || c == '\t' || c == '\n' || c == '\r');
- }
- static int string_equals (char *str, int str_len, char *needle)
- {
- return (str_len == strlen(needle) && !memcmp(str, needle, str_len));
- }
- void NCDConfigTokenizer_Tokenize (char *str, size_t left, NCDConfigTokenizer_output output, void *user)
- {
- size_t position = 0;
-
- while (left > 0) {
- size_t l;
- int error = 0;
- int token;
- void *token_val = NULL;
- char dec[NCD_MAX_SIZE + 1];
-
- if (*str == '#') {
- l = 1;
- while (l < left && str[l] != '\n') {
- l++;
- }
- token = 0;
- }
- else if (l = data_begins_with(str, left, "{")) {
- token = NCD_TOKEN_CURLY_OPEN;
- }
- else if (l = data_begins_with(str, left, "}")) {
- token = NCD_TOKEN_CURLY_CLOSE;
- }
- else if (l = data_begins_with(str, left, "(")) {
- token = NCD_TOKEN_ROUND_OPEN;
- }
- else if (l = data_begins_with(str, left, ")")) {
- token = NCD_TOKEN_ROUND_CLOSE;
- }
- else if (l = data_begins_with(str, left, ";")) {
- token = NCD_TOKEN_SEMICOLON;
- }
- else if (l = data_begins_with(str, left, ".")) {
- token = NCD_TOKEN_DOT;
- }
- else if (l = data_begins_with(str, left, ",")) {
- token = NCD_TOKEN_COMMA;
- }
- else if (is_name_first_char(*str)) {
- l = 1;
- while (l < left) {
- if (!is_name_char(str[l])) {
- break;
- }
- l++;
- }
-
- // check size
- if (l > NCD_MAX_SIZE) {
- error = 1;
- goto out;
- }
-
- // copy and terminate
- memcpy(dec, str, l);
- dec[l] = '\0';
-
- if (!strcmp(dec, "process")) {
- token = NCD_TOKEN_PROCESS;
- }
- else {
- token = NCD_TOKEN_NAME;
- token_val = dec;
- }
- }
- else if (*str == '"') {
- size_t dec_len = 0;
-
- // decode string on the fly
- l = 1;
- while (l < left) {
- char dec_ch;
-
- if (str[l] == '\\') {
- if (!(l + 1 < left)) {
- error = 1;
- goto out;
- }
-
- dec_ch = str[l + 1];
- l += 2;
- }
- else if (str[l] == '"') {
- break;
- }
- else {
- dec_ch = str[l];
- l++;
- }
-
- // check size
- if (dec_len == NCD_MAX_SIZE) {
- error = 1;
- goto out;
- }
-
- // append decoded char
- dec[dec_len] = dec_ch;
- dec_len++;
- }
-
- // make sure closing quote was found
- if (l == left) {
- error = 1;
- goto out;
- }
-
- l++;
-
- // terminate
- dec[dec_len] = '\0';
-
- token = NCD_TOKEN_STRING;
- token_val = dec;
- }
- else if (is_space_char(*str)) {
- token = 0;
- l = 1;
- }
- else {
- error = 1;
- }
-
- out:
-
- // report error
- if (error) {
- output(user, NCD_ERROR, NULL, position);
- return;
- }
-
- // output token
- if (token) {
- if (!output(user, token, token_val, position)) {
- return;
- }
- }
-
- str += l;
- left -= l;
- position += l;
- }
-
- output(user, NCD_EOF, NULL, position);
- }
|