Guard against the POSIX allowed behavior where access (file, X_OK)
[platform/upstream/glib.git] / glib / gscanner.c
index e09e63e..790241a 100644 (file)
  * MT safe
  */
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include "config.h"
 
+#include       <errno.h>
 #include       <stdlib.h>
 #include       <stdarg.h>
 #include       <string.h>
 #include       <stdio.h>
-#include       "glib.h"
 #ifdef HAVE_UNISTD_H
 #include       <unistd.h>
 #endif
-#include       <errno.h>
 #ifdef G_OS_WIN32
 #include       <io.h>          /* For _read() */
 #endif
 
+#include       "glib.h"
+#include       "gprintfint.h"
+
 /* --- defines --- */
 #define        to_lower(c)                             ( \
        (guchar) (                                                      \
@@ -71,7 +71,6 @@ struct        _GScannerKey
 };
 
 
-
 /* --- variables --- */
 static GScannerConfig g_scanner_config_template =
 {
@@ -115,6 +114,7 @@ static GScannerConfig g_scanner_config_template =
   TRUE                 /* char_2_token */,
   FALSE                        /* symbol_2_token */,
   FALSE                        /* scope_0_fallback */,
+  FALSE                        /* store_int64 */,
 };
 
 
@@ -211,14 +211,15 @@ g_scanner_new (const GScannerConfig *config_templ)
   scanner->config->char_2_token                 = config_templ->char_2_token;
   scanner->config->symbol_2_token       = config_templ->symbol_2_token;
   scanner->config->scope_0_fallback     = config_templ->scope_0_fallback;
+  scanner->config->store_int64          = config_templ->store_int64;
   
   scanner->token = G_TOKEN_NONE;
-  scanner->value.v_int = 0;
+  scanner->value.v_int64 = 0;
   scanner->line = 1;
   scanner->position = 0;
   
   scanner->next_token = G_TOKEN_NONE;
-  scanner->next_value.v_int = 0;
+  scanner->next_value.v_int64 = 0;
   scanner->next_line = 1;
   scanner->next_position = 0;
   
@@ -289,12 +290,12 @@ g_scanner_msg_handler (GScanner           *scanner,
 {
   g_return_if_fail (scanner != NULL);
   
-  fprintf (stderr, "%s:%d: ",
-          scanner->input_name ? scanner->input_name : "<memory>",
-          scanner->line);
+  _g_fprintf (stderr, "%s:%d: ",
+             scanner->input_name ? scanner->input_name : "<memory>",
+             scanner->line);
   if (is_error)
-    fprintf (stderr, "error: ");
-  fprintf (stderr, "%s\n", message);
+    _g_fprintf (stderr, "error: ");
+  _g_fprintf (stderr, "%s\n", message);
 }
 
 void
@@ -608,7 +609,7 @@ g_scanner_cur_value (GScanner *scanner)
 {
   GTokenValue v;
   
-  v.v_int = 0;
+  v.v_int64 = 0;
   
   g_return_val_if_fail (scanner != NULL, v);
 
@@ -654,7 +655,7 @@ g_scanner_input_file (GScanner *scanner,
     g_scanner_sync_file_offset (scanner);
 
   scanner->token = G_TOKEN_NONE;
-  scanner->value.v_int = 0;
+  scanner->value.v_int64 = 0;
   scanner->line = 1;
   scanner->position = 0;
   scanner->next_token = G_TOKEN_NONE;
@@ -682,7 +683,7 @@ g_scanner_input_text (GScanner        *scanner,
     g_scanner_sync_file_offset (scanner);
 
   scanner->token = G_TOKEN_NONE;
-  scanner->value.v_int = 0;
+  scanner->value.v_int64 = 0;
   scanner->line = 1;
   scanner->position = 0;
   scanner->next_token = G_TOKEN_NONE;
@@ -855,7 +856,7 @@ g_scanner_unexp_token (GScanner             *scanner,
   switch (scanner->token)
     {
     case G_TOKEN_EOF:
-      g_snprintf (token_string, token_string_len, "end of file");
+      _g_snprintf (token_string, token_string_len, "end of file");
       break;
       
     default:
@@ -864,14 +865,14 @@ g_scanner_unexp_token (GScanner           *scanner,
          if ((scanner->token >= ' ' && scanner->token <= '~') ||
              strchr (scanner->config->cset_identifier_first, scanner->token) ||
              strchr (scanner->config->cset_identifier_nth, scanner->token))
-           g_snprintf (token_string, token_string_len, "character `%c'", scanner->token);
+           _g_snprintf (token_string, token_string_len, "character `%c'", scanner->token);
          else
-           g_snprintf (token_string, token_string_len, "character `\\%o'", scanner->token);
+           _g_snprintf (token_string, token_string_len, "character `\\%o'", scanner->token);
          break;
        }
       else if (!scanner->config->symbol_2_token)
        {
-         g_snprintf (token_string, token_string_len, "(unknown) token <%d>", scanner->token);
+         _g_snprintf (token_string, token_string_len, "(unknown) token <%d>", scanner->token);
          break;
        }
       /* fall through */
@@ -881,18 +882,18 @@ g_scanner_unexp_token (GScanner           *scanner,
           expected_token > G_TOKEN_LAST))
        print_unexp = FALSE;
       if (symbol_name)
-       g_snprintf (token_string,
-                   token_string_len,
-                   "%s%s `%s'",
-                   print_unexp ? "" : "invalid ",
-                   symbol_spec,
-                   symbol_name);
+       _g_snprintf (token_string,
+                    token_string_len,
+                    "%s%s `%s'",
+                    print_unexp ? "" : "invalid ",
+                    symbol_spec,
+                    symbol_name);
       else
-       g_snprintf (token_string,
-                   token_string_len,
-                   "%s%s",
-                   print_unexp ? "" : "invalid ",
-                   symbol_spec);
+       _g_snprintf (token_string,
+                    token_string_len,
+                    "%s%s",
+                    print_unexp ? "" : "invalid ",
+                    symbol_spec);
       break;
       
     case G_TOKEN_ERROR:
@@ -901,42 +902,42 @@ g_scanner_unexp_token (GScanner           *scanner,
       switch (scanner->value.v_error)
        {
        case G_ERR_UNEXP_EOF:
-         g_snprintf (token_string, token_string_len, "scanner: unexpected end of file");
+         _g_snprintf (token_string, token_string_len, "scanner: unexpected end of file");
          break;
          
        case G_ERR_UNEXP_EOF_IN_STRING:
-         g_snprintf (token_string, token_string_len, "scanner: unterminated string constant");
+         _g_snprintf (token_string, token_string_len, "scanner: unterminated string constant");
          break;
          
        case G_ERR_UNEXP_EOF_IN_COMMENT:
-         g_snprintf (token_string, token_string_len, "scanner: unterminated comment");
+         _g_snprintf (token_string, token_string_len, "scanner: unterminated comment");
          break;
          
        case G_ERR_NON_DIGIT_IN_CONST:
-         g_snprintf (token_string, token_string_len, "scanner: non digit in constant");
+         _g_snprintf (token_string, token_string_len, "scanner: non digit in constant");
          break;
          
        case G_ERR_FLOAT_RADIX:
-         g_snprintf (token_string, token_string_len, "scanner: invalid radix for floating constant");
+         _g_snprintf (token_string, token_string_len, "scanner: invalid radix for floating constant");
          break;
          
        case G_ERR_FLOAT_MALFORMED:
-         g_snprintf (token_string, token_string_len, "scanner: malformed floating constant");
+         _g_snprintf (token_string, token_string_len, "scanner: malformed floating constant");
          break;
          
        case G_ERR_DIGIT_RADIX:
-         g_snprintf (token_string, token_string_len, "scanner: digit is beyond radix");
+         _g_snprintf (token_string, token_string_len, "scanner: digit is beyond radix");
          break;
          
        case G_ERR_UNKNOWN:
        default:
-         g_snprintf (token_string, token_string_len, "scanner: unknown error");
+         _g_snprintf (token_string, token_string_len, "scanner: unknown error");
          break;
        }
       break;
       
     case G_TOKEN_CHAR:
-      g_snprintf (token_string, token_string_len, "character `%c'", scanner->value.v_char);
+      _g_snprintf (token_string, token_string_len, "character `%c'", scanner->value.v_char);
       break;
       
     case G_TOKEN_IDENTIFIER:
@@ -944,7 +945,7 @@ g_scanner_unexp_token (GScanner             *scanner,
       if (expected_token == G_TOKEN_IDENTIFIER ||
          expected_token == G_TOKEN_IDENTIFIER_NULL)
        print_unexp = FALSE;
-      g_snprintf (token_string,
+      _g_snprintf (token_string,
                  token_string_len,
                  "%s%s `%s'",
                  print_unexp ? "" : "invalid ",
@@ -956,29 +957,32 @@ g_scanner_unexp_token (GScanner           *scanner,
     case G_TOKEN_OCTAL:
     case G_TOKEN_INT:
     case G_TOKEN_HEX:
-      g_snprintf (token_string, token_string_len, "number `%ld'", scanner->value.v_int);
+      if (scanner->config->store_int64)
+       _g_snprintf (token_string, token_string_len, "number `%llu'", scanner->value.v_int64);
+      else
+       _g_snprintf (token_string, token_string_len, "number `%lu'", scanner->value.v_int);
       break;
       
     case G_TOKEN_FLOAT:
-      g_snprintf (token_string, token_string_len, "number `%.3f'", scanner->value.v_float);
+      _g_snprintf (token_string, token_string_len, "number `%.3f'", scanner->value.v_float);
       break;
       
     case G_TOKEN_STRING:
       if (expected_token == G_TOKEN_STRING)
        print_unexp = FALSE;
-      g_snprintf (token_string,
-                 token_string_len,
-                 "%s%sstring constant \"%s\"",
-                 print_unexp ? "" : "invalid ",
-                 scanner->value.v_string[0] == 0 ? "empty " : "",
-                 scanner->value.v_string);
+      _g_snprintf (token_string,
+                  token_string_len,
+                  "%s%sstring constant \"%s\"",
+                  print_unexp ? "" : "invalid ",
+                  scanner->value.v_string[0] == 0 ? "empty " : "",
+                  scanner->value.v_string);
       token_string[token_string_len - 2] = '"';
       token_string[token_string_len - 1] = 0;
       break;
       
     case G_TOKEN_COMMENT_SINGLE:
     case G_TOKEN_COMMENT_MULTI:
-      g_snprintf (token_string, token_string_len, "comment");
+      _g_snprintf (token_string, token_string_len, "comment");
       break;
       
     case G_TOKEN_NONE:
@@ -998,7 +1002,7 @@ g_scanner_unexp_token (GScanner            *scanner,
       gboolean need_valid;
       gchar *tstring;
     case G_TOKEN_EOF:
-      g_snprintf (expected_string, expected_string_len, "end of file");
+      _g_snprintf (expected_string, expected_string_len, "end of file");
       break;
     default:
       if (expected_token >= 1 && expected_token <= 255)
@@ -1006,14 +1010,14 @@ g_scanner_unexp_token (GScanner         *scanner,
          if ((expected_token >= ' ' && expected_token <= '~') ||
              strchr (scanner->config->cset_identifier_first, expected_token) ||
              strchr (scanner->config->cset_identifier_nth, expected_token))
-           g_snprintf (expected_string, expected_string_len, "character `%c'", expected_token);
+           _g_snprintf (expected_string, expected_string_len, "character `%c'", expected_token);
          else
-           g_snprintf (expected_string, expected_string_len, "character `\\%o'", expected_token);
+           _g_snprintf (expected_string, expected_string_len, "character `\\%o'", expected_token);
          break;
        }
       else if (!scanner->config->symbol_2_token)
        {
-         g_snprintf (expected_string, expected_string_len, "(unknown) token <%d>", expected_token);
+         _g_snprintf (expected_string, expected_string_len, "(unknown) token <%d>", expected_token);
          break;
        }
       /* fall through */
@@ -1021,67 +1025,67 @@ g_scanner_unexp_token (GScanner         *scanner,
       need_valid = (scanner->token == G_TOKEN_SYMBOL ||
                    (scanner->config->symbol_2_token &&
                     scanner->token > G_TOKEN_LAST));
-      g_snprintf (expected_string,
-                 expected_string_len,
-                 "%s%s",
-                 need_valid ? "valid " : "",
-                 symbol_spec);
+      _g_snprintf (expected_string,
+                  expected_string_len,
+                  "%s%s",
+                  need_valid ? "valid " : "",
+                  symbol_spec);
       /* FIXME: should we attempt to lookup the symbol_name for symbol_2_token? */
       break;
     case G_TOKEN_CHAR:
-      g_snprintf (expected_string, expected_string_len, "%scharacter",
-                 scanner->token == G_TOKEN_CHAR ? "valid " : "");
+      _g_snprintf (expected_string, expected_string_len, "%scharacter",
+                  scanner->token == G_TOKEN_CHAR ? "valid " : "");
       break;
     case G_TOKEN_BINARY:
       tstring = "binary";
-      g_snprintf (expected_string, expected_string_len, "%snumber (%s)",
-                 scanner->token == expected_token ? "valid " : "", tstring);
+      _g_snprintf (expected_string, expected_string_len, "%snumber (%s)",
+                  scanner->token == expected_token ? "valid " : "", tstring);
       break;
     case G_TOKEN_OCTAL:
       tstring = "octal";
-      g_snprintf (expected_string, expected_string_len, "%snumber (%s)",
-                 scanner->token == expected_token ? "valid " : "", tstring);
+      _g_snprintf (expected_string, expected_string_len, "%snumber (%s)",
+                  scanner->token == expected_token ? "valid " : "", tstring);
       break;
     case G_TOKEN_INT:
       tstring = "integer";
-      g_snprintf (expected_string, expected_string_len, "%snumber (%s)",
-                 scanner->token == expected_token ? "valid " : "", tstring);
+      _g_snprintf (expected_string, expected_string_len, "%snumber (%s)",
+                  scanner->token == expected_token ? "valid " : "", tstring);
       break;
     case G_TOKEN_HEX:
       tstring = "hexadecimal";
-      g_snprintf (expected_string, expected_string_len, "%snumber (%s)",
-                 scanner->token == expected_token ? "valid " : "", tstring);
+      _g_snprintf (expected_string, expected_string_len, "%snumber (%s)",
+                  scanner->token == expected_token ? "valid " : "", tstring);
       break;
     case G_TOKEN_FLOAT:
       tstring = "float";
-      g_snprintf (expected_string, expected_string_len, "%snumber (%s)",
-                 scanner->token == expected_token ? "valid " : "", tstring);
+      _g_snprintf (expected_string, expected_string_len, "%snumber (%s)",
+                  scanner->token == expected_token ? "valid " : "", tstring);
       break;
     case G_TOKEN_STRING:
-      g_snprintf (expected_string,
-                 expected_string_len,
-                 "%sstring constant",
-                 scanner->token == G_TOKEN_STRING ? "valid " : "");
+      _g_snprintf (expected_string,
+                  expected_string_len,
+                  "%sstring constant",
+                  scanner->token == G_TOKEN_STRING ? "valid " : "");
       break;
     case G_TOKEN_IDENTIFIER:
     case G_TOKEN_IDENTIFIER_NULL:
       need_valid = (scanner->token == G_TOKEN_IDENTIFIER_NULL ||
                    scanner->token == G_TOKEN_IDENTIFIER);
-      g_snprintf (expected_string,
-                 expected_string_len,
-                 "%s%s",
-                 need_valid ? "valid " : "",
-                 identifier_spec);
+      _g_snprintf (expected_string,
+                  expected_string_len,
+                  "%s%s",
+                  need_valid ? "valid " : "",
+                  identifier_spec);
       break;
     case G_TOKEN_COMMENT_SINGLE:
       tstring = "single-line";
-      g_snprintf (expected_string, expected_string_len, "%scomment (%s)",
-                 scanner->token == expected_token ? "valid " : "", tstring);
+      _g_snprintf (expected_string, expected_string_len, "%scomment (%s)",
+                  scanner->token == expected_token ? "valid " : "", tstring);
       break;
     case G_TOKEN_COMMENT_MULTI:
       tstring = "multi-line";
-      g_snprintf (expected_string, expected_string_len, "%scomment (%s)",
-                 scanner->token == expected_token ? "valid " : "", tstring);
+      _g_snprintf (expected_string, expected_string_len, "%scomment (%s)",
+                  scanner->token == expected_token ? "valid " : "", tstring);
       break;
     case G_TOKEN_NONE:
     case G_TOKEN_ERROR:
@@ -1189,7 +1193,10 @@ g_scanner_get_token_i (GScanner  *scanner,
       scanner->config->int_2_float)
     {
       *token_p = G_TOKEN_FLOAT;
-      value_p->v_float = value_p->v_int;
+      if (scanner->config->store_int64)
+       value_p->v_float = value_p->v_int64;
+      else
+       value_p->v_float = value_p->v_int;
     }
   
   errno = 0;
@@ -1213,7 +1220,7 @@ g_scanner_get_token_ll    (GScanner       *scanner,
   guchar          ch;
   
   config = scanner->config;
-  (*value_p).v_int = 0;
+  (*value_p).v_int64 = 0;
   
   if ((scanner->text >= scanner->text_end && scanner->input_fd < 0) ||
       scanner->token == G_TOKEN_EOF)
@@ -1234,7 +1241,7 @@ g_scanner_get_token_ll    (GScanner       *scanner,
       
       ch = g_scanner_get_char (scanner, line_p, position_p);
       
-      value.v_int = 0;
+      value.v_int64 = 0;
       token = G_TOKEN_NONE;
       
       /* this is *evil*, but needed ;(
@@ -1557,30 +1564,31 @@ g_scanner_get_token_ll  (GScanner       *scanner,
          while (in_number);
          
          endptr = NULL;
-         switch (token)
+         if (token == G_TOKEN_FLOAT)
+           value.v_float = g_strtod (gstring->str, &endptr);
+         else
            {
-           case G_TOKEN_BINARY:
-             value.v_binary = strtol (gstring->str, &endptr, 2);
-             break;
-             
-           case G_TOKEN_OCTAL:
-             value.v_octal = strtol (gstring->str, &endptr, 8);
-             break;
-             
-           case G_TOKEN_INT:
-             value.v_int = strtol (gstring->str, &endptr, 10);
-             break;
-             
-           case G_TOKEN_FLOAT:
-             value.v_float = g_strtod (gstring->str, &endptr);
-             break;
-             
-           case G_TOKEN_HEX:
-             value.v_hex = strtol (gstring->str, &endptr, 16);
-             break;
-             
-           default:
-             break;
+             guint64 ui64 = 0;
+             switch (token)
+               {
+               case G_TOKEN_BINARY:
+                 ui64 = g_ascii_strtoull (gstring->str, &endptr, 2);
+                 break;
+               case G_TOKEN_OCTAL:
+                 ui64 = g_ascii_strtoull (gstring->str, &endptr, 8);
+                 break;
+               case G_TOKEN_INT:
+                 ui64 = g_ascii_strtoull (gstring->str, &endptr, 10);
+                 break;
+               case G_TOKEN_HEX:
+                 ui64 = g_ascii_strtoull (gstring->str, &endptr, 16);
+                 break;
+               default: ;
+               }
+             if (scanner->config->store_int64)
+               value.v_int64 = ui64;
+             else
+               value.v_int = ui64;
            }
          if (endptr && *endptr)
            {