Fixes from clang / scan-build
[freeradius.git] / src / lib / token.c
index 6191471..47fb90a 100644 (file)
 #include <freeradius-devel/ident.h>
 RCSID("$Id$")
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
+#include <freeradius-devel/libradius.h>
 #include <freeradius-devel/token.h>
 
-static const LRAD_NAME_NUMBER tokens[] = {
+#include <ctype.h>
+
+static const FR_NAME_NUMBER tokens[] = {
        { "=~", T_OP_REG_EQ,    }, /* order is important! */
        { "!~", T_OP_REG_NE,    },
        { "{",  T_LCBRACE,      },
@@ -70,15 +69,15 @@ static const LRAD_NAME_NUMBER tokens[] = {
  *     At end-of-line, buf[0] is set to '\0'.
  *     Returns 0 or special token value.
  */
-static LRAD_TOKEN getthing(char **ptr, char *buf, int buflen, int tok,
-                          const LRAD_NAME_NUMBER *tokenlist)
+static FR_TOKEN getthing(const char **ptr, char *buf, int buflen, int tok,
+                        const FR_NAME_NUMBER *tokenlist)
 {
-       char    *s, *p;
-       int     quote;
-       int     escape;
-       int     x;
-       const LRAD_NAME_NUMBER*t;
-       LRAD_TOKEN rcode;
+       char *s;
+       const char *p;
+       int     quote, end = 0;
+       unsigned int    x;
+       const FR_NAME_NUMBER*t;
+       FR_TOKEN rcode;
 
        buf[0] = 0;
 
@@ -102,7 +101,7 @@ static LRAD_TOKEN getthing(char **ptr, char *buf, int buflen, int tok,
                        while (isspace((int) *p))
                                p++;
                        *ptr = p;
-                       return (LRAD_TOKEN) t->number;
+                       return (FR_TOKEN) t->number;
                }
        }
 
@@ -112,14 +111,15 @@ static LRAD_TOKEN getthing(char **ptr, char *buf, int buflen, int tok,
            (*p == '\'') ||
            (*p == '`')) {
                quote = *p;
+               end = 0;
                p++;
        }
        s = buf;
-       escape = 0;
 
        while (*p && buflen-- > 1) {
-               if (escape) {
-                       escape = 0;
+               if (quote && (*p == '\\')) {
+                       p++;
+
                        switch(*p) {
                                case 'r':
                                        *s++ = '\r';
@@ -130,14 +130,9 @@ static LRAD_TOKEN getthing(char **ptr, char *buf, int buflen, int tok,
                                case 't':
                                        *s++ = '\t';
                                        break;
-                               case '"':
-                                       *s++ = '"';
-                                       break;
-                               case '\'':
-                                       *s++ = '\'';
-                                       break;
-                               case '`':
-                                       *s++ = '`';
+                               case '\0':
+                                       *s++ = '\\';
+                                       p--; /* force EOS */
                                        break;
                                default:
                                        if (*p >= '0' && *p <= '9' &&
@@ -151,12 +146,8 @@ static LRAD_TOKEN getthing(char **ptr, char *buf, int buflen, int tok,
                        p++;
                        continue;
                }
-               if (*p == '\\') {
-                       p++;
-                       escape = 1;
-                       continue;
-               }
                if (quote && (*p == quote)) {
+                       end = 1;
                        p++;
                        break;
                }
@@ -175,6 +166,11 @@ static LRAD_TOKEN getthing(char **ptr, char *buf, int buflen, int tok,
        }
        *s++ = 0;
 
+       if (quote && !end) {
+               fr_strerror_printf("Unterminated string");
+               return T_OP_INVALID;
+       }
+
        /* Skip whitespace again. */
        while (*p && isspace((int) *p))
                p++;
@@ -206,7 +202,7 @@ static LRAD_TOKEN getthing(char **ptr, char *buf, int buflen, int tok,
  *     Read a "word" - this means we don't honor
  *     tokens as delimiters.
  */
-int getword(char **ptr, char *buf, int buflen)
+int getword(const char **ptr, char *buf, int buflen)
 {
        return getthing(ptr, buf, buflen, 0, tokens) == T_EOL ? 0 : 1;
 }
@@ -215,9 +211,9 @@ int getword(char **ptr, char *buf, int buflen)
  *     Read a bare "word" - this means we don't honor
  *     tokens as delimiters.
  */
-int getbareword(char **ptr, char *buf, int buflen)
+int getbareword(const char **ptr, char *buf, int buflen)
 {
-       LRAD_TOKEN token;
+       FR_TOKEN token;
 
        token = getthing(ptr, buf, buflen, 0, NULL);
        if (token != T_BARE_WORD) {
@@ -230,17 +226,39 @@ int getbareword(char **ptr, char *buf, int buflen)
 /*
  *     Read the next word, use tokens as delimiters.
  */
-LRAD_TOKEN gettoken(char **ptr, char *buf, int buflen)
+FR_TOKEN gettoken(const char **ptr, char *buf, int buflen)
 {
        return getthing(ptr, buf, buflen, 1, tokens);
 }
 
 /*
+ *     Expect a string.
+ */
+FR_TOKEN getstring(const char **ptr, char *buf, int buflen)
+{
+       const char *p;
+
+       if (!ptr || !*ptr || !buf) return T_OP_INVALID;
+       
+       p = *ptr;
+
+       while (p && (isspace((int)*p))) p++;
+
+       *ptr = p;
+
+       if ((*p == '"') || (*p == '\'') || (*p == '`')) {
+               return gettoken(ptr, buf, buflen);
+       }
+
+       return getthing(ptr, buf, buflen, 0, tokens);
+}
+
+/*
  *     Convert a string to an integer
  */
-int lrad_str2int(const LRAD_NAME_NUMBER *table, const char *name, int def)
+int fr_str2int(const FR_NAME_NUMBER *table, const char *name, int def)
 {
-       const LRAD_NAME_NUMBER *this;
+       const FR_NAME_NUMBER *this;
 
        for (this = table; this->name != NULL; this++) {
                if (strcasecmp(this->name, name) == 0) {
@@ -254,10 +272,10 @@ int lrad_str2int(const LRAD_NAME_NUMBER *table, const char *name, int def)
 /*
  *     Convert an integer to a string.
  */
-const char *lrad_int2str(const LRAD_NAME_NUMBER *table, int number,
+const char *fr_int2str(const FR_NAME_NUMBER *table, int number,
                         const char *def)
 {
-       const LRAD_NAME_NUMBER *this;
+       const FR_NAME_NUMBER *this;
 
        for (this = table; this->name != NULL; this++) {
                if (this->number == number) {