From: Thadeu Lima de Souza Cascardo Date: Sun, 26 Apr 2015 15:51:11 +0000 (+0000) Subject: Adiciona tokenizer. X-Git-Url: http://git.cascardo.eti.br/?p=cascardo%2Fdeclara.git;a=commitdiff_plain;h=404cd65c3fbb3e44782bb11ce2e31ea5d544b315 Adiciona tokenizer. --- diff --git a/token.c b/token.c new file mode 100644 index 0000000..6591ff9 --- /dev/null +++ b/token.c @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2015 Thadeu Lima de Souza Cascardo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 "token.h" +#include +#include +#include + +static char * token_unescape(char *start, char *end) +{ + int escape = 0; + char *s, *r, *n; + s = n = malloc(end - start); + if (!s) + return NULL; + for (r = start + 1; r < end; r++) { + if (escape) { + *s = *r; + s++; + escape = 0; + } else if (*r == '\\') { + escape = 1; + } else { + *s = *r; + s++; + } + } + *s = 0; + return n; +} + +static char * token_next(char *line, char **end) +{ + char *start; + char *lend; + char cend; + int escape = 0; + start = line; + while (isspace(*start)) + start++; + if (*start == '"') { + lend = start + 1; + while (*lend) { + cend = *lend; + lend++; + if (escape) + escape = 0; + else if (cend == '\\') + escape = 1; + else if (cend == '"') + break; + } + } else { + lend = start; + while (*lend && !isspace(*lend)) + lend++; + } + *end = lend; + return start; +} + +char ** tokens_new(char *line) +{ + char **args = NULL; + size_t alloc = 0; + size_t next = 0; + const int inc = 8; + int more = 0; + char *start; + char *end; + int i; + end = line; + do { + if (next <= alloc) { + char **nargs; + alloc += inc; + nargs = realloc(args, alloc * sizeof(char *)); + if (!nargs) { + for (i = 0; i < alloc - inc; i++) + if (args[i]) + free(args[i]); + free(args); + return NULL; + } + for (i = alloc - inc; i < alloc; i++) + nargs[i] = NULL; + args = nargs; + } + start = token_next(end, &end); + if (start == end) + break; + if (*start == '"') { + args[next] = token_unescape(start, end - 1); + } else { + args[next] = strndup(start, end - start); + } + if (!args[next]) { + for (i = 0; i < alloc; i++) + if (args[i]) + free(args[i]); + free(args); + return NULL; + } + next++; + } while (1); + return args; +} + +void tokens_free(char **args) +{ + char *arg; + for (arg = *args; *arg; arg++) + free(arg); + free(args); +} diff --git a/token.h b/token.h new file mode 100644 index 0000000..5050c26 --- /dev/null +++ b/token.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2015 Thadeu Lima de Souza Cascardo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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. + */ + +#ifndef _TOKEN_H +#define _TOKEN_H + +char ** tokens_new(char *line); +void tokens_free(char **args); + +#endif