More editing. Use gcc, not ld to link. On native Win32 use _unlink(). Use
[platform/upstream/glib.git] / gscanner.c
index b73ca4c..832ca31 100644 (file)
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
+
+/*
+ * Modified by the GLib Team and others 1997-1999.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+/* 
+ * MT safe
+ */
+
 #define                __gscanner_c__
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #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>
 #include       <sys/types.h>   /* needed for sys/stat.h */
 #include       <sys/stat.h>
-#include       "glib.h"
-
-
+#ifdef NATIVE_WIN32
+#include       <io.h>          /* For _read() */
+#endif
 
 /* --- defines --- */
 #define        to_lower(c)                             ( \
@@ -61,7 +80,7 @@ struct        _GScannerKey
 static GScannerConfig g_scanner_config_template =
 {
   (
-   " \t\n"
+   " \t\r\n"
    )                   /* cset_skip_characters */,
   (
    G_CSET_a_2_z
@@ -153,7 +172,7 @@ g_scanner_char_2_num (guchar        c,
 GScanner*
 g_scanner_new (GScannerConfig  *config_templ)
 {
-  register GScanner    *scanner;
+  GScanner *scanner;
   
   if (!config_templ)
     config_templ = &g_scanner_config_template;
@@ -222,11 +241,11 @@ g_scanner_free_value (GTokenType     *token_p,
 {
   switch (*token_p)
     {
-    case  G_TOKEN_STRING:
-    case  G_TOKEN_IDENTIFIER:
-    case  G_TOKEN_IDENTIFIER_NULL:
-    case  G_TOKEN_COMMENT_SINGLE:
-    case  G_TOKEN_COMMENT_MULTI:
+    case G_TOKEN_STRING:
+    case G_TOKEN_IDENTIFIER:
+    case G_TOKEN_IDENTIFIER_NULL:
+    case G_TOKEN_COMMENT_SINGLE:
+    case G_TOKEN_COMMENT_MULTI:
       g_free (value_p->v_string);
       break;
       
@@ -328,8 +347,8 @@ static gint
 g_scanner_key_equal (gconstpointer v1,
                     gconstpointer v2)
 {
-  register const GScannerKey *key1 = v1;
-  register const GScannerKey *key2 = v2;
+  const GScannerKey *key1 = v1;
+  const GScannerKey *key2 = v2;
   
   return (key1->scope_id == key2->scope_id) && (strcmp (key1->symbol, key2->symbol) == 0);
 }
@@ -337,14 +356,14 @@ g_scanner_key_equal (gconstpointer v1,
 static guint
 g_scanner_key_hash (gconstpointer v)
 {
-  register const GScannerKey *key = v;
-  register gchar *c;
-  register guint h;
+  const GScannerKey *key = v;
+  gchar *c;
+  guint h;
   
   h = key->scope_id;
   for (c = key->symbol; *c; c++)
     {
-      register guint g;
+      guint g;
       
       h = (h << 4) + *c;
       g = h & 0xf0000000;
@@ -363,15 +382,15 @@ g_scanner_lookup_internal (GScanner       *scanner,
                           guint         scope_id,
                           const gchar  *symbol)
 {
-  register GScannerKey *key_p;
+  GScannerKey  *key_p;
   GScannerKey key;
   
   key.scope_id = scope_id;
   
   if (!scanner->config->case_sensitive)
     {
-      register gchar *d;
-      register const gchar *c;
+      gchar *d;
+      const gchar *c;
       
       key.symbol = g_new (gchar, strlen (symbol) + 1);
       for (d = key.symbol, c = symbol; *c; c++, d++)
@@ -395,7 +414,7 @@ g_scanner_scope_add_symbol (GScanner        *scanner,
                            const gchar *symbol,
                            gpointer     value)
 {
-  register GScannerKey *key;
+  GScannerKey  *key;
   
   g_return_if_fail (scanner != NULL);
   g_return_if_fail (symbol != NULL);
@@ -410,7 +429,7 @@ g_scanner_scope_add_symbol (GScanner        *scanner,
       key->value = value;
       if (!scanner->config->case_sensitive)
        {
-         register gchar *c;
+         gchar *c;
          
          c = key->symbol;
          while (*c != 0)
@@ -430,7 +449,7 @@ g_scanner_scope_remove_symbol (GScanner        *scanner,
                               guint        scope_id,
                               const gchar *symbol)
 {
-  register GScannerKey *key;
+  GScannerKey  *key;
   
   g_return_if_fail (scanner != NULL);
   g_return_if_fail (symbol != NULL);
@@ -449,8 +468,8 @@ gpointer
 g_scanner_lookup_symbol (GScanner      *scanner,
                         const gchar    *symbol)
 {
-  register GScannerKey *key;
-  register guint scope_id;
+  GScannerKey  *key;
+  guint scope_id;
   
   g_return_val_if_fail (scanner != NULL, NULL);
   
@@ -473,7 +492,7 @@ g_scanner_scope_lookup_symbol (GScanner           *scanner,
                               guint           scope_id,
                               const gchar    *symbol)
 {
-  register GScannerKey *key;
+  GScannerKey  *key;
   
   g_return_val_if_fail (scanner != NULL, NULL);
   
@@ -492,7 +511,7 @@ guint
 g_scanner_set_scope (GScanner      *scanner,
                     guint           scope_id)
 {
-  register guint old_scope_id;
+  guint old_scope_id;
   
   g_return_val_if_fail (scanner != NULL, 0);
   
@@ -507,34 +526,34 @@ g_scanner_foreach_internal (gpointer  _key,
                            gpointer  _value,
                            gpointer  _user_data)
 {
-  register GScannerKey *key;
-  register gpointer *d;
-  register GHFunc func;
-  register gpointer func_data;
-  register guint *scope_id;
+  GScannerKey *key;
+  gpointer *d;
+  GHFunc func;
+  gpointer user_data;
+  guint *scope_id;
   
   d = _user_data;
   func = (GHFunc) d[0];
-  func_data = d[1];
+  user_data = d[1];
   scope_id = d[2];
   key = _value;
   
   if (key->scope_id == *scope_id)
-    func (key->symbol, key->value, func_data);
+    func (key->symbol, key->value, user_data);
 }
 
 void
 g_scanner_scope_foreach_symbol (GScanner       *scanner,
                                guint           scope_id,
                                GHFunc          func,
-                               gpointer        func_data)
+                               gpointer        user_data)
 {
   gpointer d[3];
   
   g_return_if_fail (scanner != NULL);
   
   d[0] = (gpointer) func;
-  d[1] = func_data;
+  d[1] = user_data;
   d[2] = &scope_id;
   
   g_hash_table_foreach (scanner->symbol_table, g_scanner_foreach_internal, d);
@@ -614,9 +633,14 @@ g_scanner_cur_value (GScanner *scanner)
   GTokenValue v;
   
   v.v_int = 0;
-  g_return_val_if_fail (scanner != NULL, v);
   
-  return scanner->value;
+  g_return_val_if_fail (scanner != NULL, v);
+
+  /* MSC isn't capable of handling return scanner->value; ? */
+
+  v = scanner->value;
+
+  return v;
 }
 
 guint
@@ -650,6 +674,9 @@ g_scanner_input_file (GScanner *scanner,
   g_return_if_fail (scanner != NULL);
   g_return_if_fail (input_fd >= 0);
 
+  if (scanner->input_fd >= 0)
+    g_scanner_sync_file_offset (scanner);
+
   scanner->token = G_TOKEN_NONE;
   scanner->value.v_int = 0;
   scanner->line = 1;
@@ -675,6 +702,9 @@ g_scanner_input_text (GScanner        *scanner,
   else
     text = NULL;
 
+  if (scanner->input_fd >= 0)
+    g_scanner_sync_file_offset (scanner);
+
   scanner->token = G_TOKEN_NONE;
   scanner->value.v_int = 0;
   scanner->line = 1;
@@ -701,8 +731,8 @@ g_scanner_peek_next_char (GScanner *scanner)
     }
   else if (scanner->input_fd >= 0)
     {
-      register gint count;
-      register gchar *buffer;
+      gint count;
+      gchar *buffer;
 
       buffer = scanner->buffer;
       do
@@ -729,19 +759,46 @@ g_scanner_peek_next_char (GScanner *scanner)
     return 0;
 }
 
+void
+g_scanner_sync_file_offset (GScanner *scanner)
+{
+  g_return_if_fail (scanner != NULL);
+
+  /* for file input, rewind the filedescriptor to the current
+   * buffer position and blow the file read ahead buffer. usefull for
+   * third party uses of our filedescriptor, which hooks onto the current
+   * scanning position.
+   */
+
+  if (scanner->input_fd >= 0 && scanner->text_end > scanner->text)
+    {
+      gint buffered;
+
+      buffered = scanner->text_end - scanner->text;
+      if (lseek (scanner->input_fd, - buffered, SEEK_CUR) >= 0)
+       {
+         /* we succeeded, blow our buffer's contents now */
+         scanner->text = NULL;
+         scanner->text_end = NULL;
+       }
+      else
+       errno = 0;
+    }
+}
+
 static guchar
 g_scanner_get_char (GScanner   *scanner,
                    guint       *line_p,
                    guint       *position_p)
 {
-  register guchar fchar;
+  guchar fchar;
 
   if (scanner->text < scanner->text_end)
     fchar = *(scanner->text++);
   else if (scanner->input_fd >= 0)
     {
-      register gint count;
-      register gchar *buffer;
+      gint count;
+      gchar *buffer;
 
       buffer = scanner->buffer;
       do
@@ -760,6 +817,12 @@ g_scanner_get_char (GScanner       *scanner,
          scanner->text = buffer + 1;
          scanner->text_end = buffer + count;
          fchar = *buffer;
+         if (!fchar)
+           {
+             g_scanner_sync_file_offset (scanner);
+             scanner->text_end = scanner->text;
+             scanner->input_fd = -1;
+           }
        }
     }
   else
@@ -787,12 +850,12 @@ g_scanner_unexp_token (GScanner           *scanner,
                       const gchar      *message,
                       gint              is_error)
 {
-  register gchar       *token_string;
-  register guint       token_string_len;
-  register gchar       *expected_string;
-  register guint       expected_string_len;
-  register gchar       *message_prefix;
-  register gboolean    print_unexp;
+  gchar        *token_string;
+  guint        token_string_len;
+  gchar        *expected_string;
+  guint        expected_string_len;
+  gchar        *message_prefix;
+  gboolean print_unexp;
   void (*msg_handler)  (GScanner*, const gchar*, ...);
   
   g_return_if_fail (scanner != NULL);
@@ -815,7 +878,7 @@ g_scanner_unexp_token (GScanner             *scanner,
   
   switch (scanner->token)
     {
-    case  G_TOKEN_EOF:
+    case G_TOKEN_EOF:
       g_snprintf (token_string, token_string_len, "end of file");
       break;
       
@@ -836,7 +899,7 @@ g_scanner_unexp_token (GScanner             *scanner,
          break;
        }
       /* fall through */
-    case  G_TOKEN_SYMBOL:
+    case G_TOKEN_SYMBOL:
       if (expected_token == G_TOKEN_SYMBOL ||
          (scanner->config->symbol_2_token &&
           expected_token > G_TOKEN_LAST))
@@ -856,52 +919,54 @@ g_scanner_unexp_token (GScanner           *scanner,
                    symbol_spec);
       break;
       
-    case  G_TOKEN_ERROR:
+    case G_TOKEN_ERROR:
       print_unexp = FALSE;
       expected_token = G_TOKEN_NONE;
       switch (scanner->value.v_error)
        {
-       case  G_ERR_UNEXP_EOF:
+       case G_ERR_UNEXP_EOF:
          g_snprintf (token_string, token_string_len, "scanner: unexpected end of file");
          break;
          
-       case  G_ERR_UNEXP_EOF_IN_STRING:
+       case G_ERR_UNEXP_EOF_IN_STRING:
          g_snprintf (token_string, token_string_len, "scanner: unterminated string constant");
          break;
          
-       case  G_ERR_UNEXP_EOF_IN_COMMENT:
+       case G_ERR_UNEXP_EOF_IN_COMMENT:
          g_snprintf (token_string, token_string_len, "scanner: unterminated comment");
          break;
          
-       case  G_ERR_NON_DIGIT_IN_CONST:
+       case G_ERR_NON_DIGIT_IN_CONST:
          g_snprintf (token_string, token_string_len, "scanner: non digit in constant");
          break;
          
-       case  G_ERR_FLOAT_RADIX:
+       case G_ERR_FLOAT_RADIX:
          g_snprintf (token_string, token_string_len, "scanner: invalid radix for floating constant");
          break;
          
-       case  G_ERR_FLOAT_MALFORMED:
+       case G_ERR_FLOAT_MALFORMED:
          g_snprintf (token_string, token_string_len, "scanner: malformed floating constant");
          break;
          
-       case  G_ERR_DIGIT_RADIX:
+       case G_ERR_DIGIT_RADIX:
          g_snprintf (token_string, token_string_len, "scanner: digit is beyond radix");
          break;
          
-       case  G_ERR_UNKNOWN:
+       case G_ERR_UNKNOWN:
        default:
          g_snprintf (token_string, token_string_len, "scanner: unknown error");
          break;
        }
       break;
       
-    case  G_TOKEN_CHAR:
+    case G_TOKEN_CHAR:
       g_snprintf (token_string, token_string_len, "character `%c'", scanner->value.v_char);
       break;
       
-    case  G_TOKEN_IDENTIFIER:
-      if (expected_token == G_TOKEN_IDENTIFIER)
+    case G_TOKEN_IDENTIFIER:
+    case G_TOKEN_IDENTIFIER_NULL:
+      if (expected_token == G_TOKEN_IDENTIFIER ||
+         expected_token == G_TOKEN_IDENTIFIER_NULL)
        print_unexp = FALSE;
       g_snprintf (token_string,
                  token_string_len,
@@ -911,18 +976,18 @@ g_scanner_unexp_token (GScanner           *scanner,
                  scanner->value.v_string);
       break;
       
-    case  G_TOKEN_BINARY:
-    case  G_TOKEN_OCTAL:
-    case  G_TOKEN_INT:
-    case  G_TOKEN_HEX:
+    case G_TOKEN_BINARY:
+    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);
       break;
       
-    case  G_TOKEN_FLOAT:
+    case G_TOKEN_FLOAT:
       g_snprintf (token_string, token_string_len, "number `%.3f'", scanner->value.v_float);
       break;
       
-    case  G_TOKEN_STRING:
+    case G_TOKEN_STRING:
       if (expected_token == G_TOKEN_STRING)
        print_unexp = FALSE;
       g_snprintf (token_string,
@@ -935,12 +1000,12 @@ g_scanner_unexp_token (GScanner          *scanner,
       token_string[token_string_len - 1] = 0;
       break;
       
-    case  G_TOKEN_COMMENT_SINGLE:
-    case  G_TOKEN_COMMENT_MULTI:
+    case G_TOKEN_COMMENT_SINGLE:
+    case G_TOKEN_COMMENT_MULTI:
       g_snprintf (token_string, token_string_len, "comment");
       break;
       
-    case  G_TOKEN_NONE:
+    case G_TOKEN_NONE:
       /* somehow the user's parsing code is screwed, there isn't much
        * we can do about it.
        * Note, a common case to trigger this is
@@ -973,7 +1038,7 @@ g_scanner_unexp_token (GScanner            *scanner,
          break;
        }
       /* fall through */
-    case  G_TOKEN_SYMBOL:
+    case G_TOKEN_SYMBOL:
       need_valid = (scanner->token == G_TOKEN_SYMBOL ||
                    (scanner->config->symbol_2_token &&
                     scanner->token > G_TOKEN_LAST));
@@ -985,30 +1050,32 @@ g_scanner_unexp_token (GScanner          *scanner,
       /* FIXME: should we attempt to lookup the symbol_name for symbol_2_token? */
       break;
       
-    case  G_TOKEN_INT:
+    case G_TOKEN_INT:
       g_snprintf (expected_string, expected_string_len, "number (integer)");
       break;
       
-    case  G_TOKEN_FLOAT:
+    case G_TOKEN_FLOAT:
       g_snprintf (expected_string, expected_string_len, "number (float)");
       break;
       
-    case  G_TOKEN_STRING:
+    case G_TOKEN_STRING:
       g_snprintf (expected_string,
                  expected_string_len,
                  "%sstring constant",
                  scanner->token == G_TOKEN_STRING ? "valid " : "");
       break;
       
-    case  G_TOKEN_IDENTIFIER:
+    case G_TOKEN_IDENTIFIER:
+    case G_TOKEN_IDENTIFIER_NULL:
       g_snprintf (expected_string,
                  expected_string_len,
                  "%s%s",
-                 scanner->token == G_TOKEN_IDENTIFIER ? "valid " : "",
+                 (scanner->token == G_TOKEN_IDENTIFIER_NULL ||
+                  scanner->token == G_TOKEN_IDENTIFIER ? "valid " : ""),
                  identifier_spec);
       break;
       
-    case  G_TOKEN_NONE:
+    case G_TOKEN_NONE:
       break;
     }
   
@@ -1064,9 +1131,11 @@ g_scanner_stat_mode (const gchar *filename)
   gint         st_mode;
   
   stat_buf = g_new0 (struct stat, 1);
-  
+#ifdef HAVE_LSTAT  
   lstat (filename, stat_buf);
-  
+#else
+  stat (filename, stat_buf);
+#endif
   st_mode = stat_buf->st_mode;
   
   g_free (stat_buf);
@@ -1135,15 +1204,15 @@ g_scanner_get_token_ll  (GScanner       *scanner,
                         guint          *line_p,
                         guint          *position_p)
 {
-  register GScannerConfig *config;
-  register GTokenType     token;
-  register gboolean       in_comment_multi;
-  register gboolean       in_comment_single;
-  register gboolean       in_string_sq;
-  register gboolean       in_string_dq;
-  register GString       *gstring;
-  GTokenValue             value;
-  guchar                  ch;
+  GScannerConfig *config;
+  GTokenType      token;
+  gboolean        in_comment_multi;
+  gboolean        in_comment_single;
+  gboolean        in_string_sq;
+  gboolean        in_string_dq;
+  GString        *gstring;
+  GTokenValue     value;
+  guchar          ch;
   
   config = scanner->config;
   (*value_p).v_int = 0;
@@ -1163,7 +1232,7 @@ g_scanner_get_token_ll    (GScanner       *scanner,
   
   do /* while (ch != 0) */
     {
-      register gboolean                dotted_float = FALSE;
+      gboolean dotted_float = FALSE;
       
       ch = g_scanner_get_char (scanner, line_p, position_p);
       
@@ -1180,13 +1249,13 @@ g_scanner_get_token_ll  (GScanner       *scanner,
       
       switch (ch)
        {
-       case  0:
+       case 0:
          token = G_TOKEN_EOF;
          (*position_p)++;
          /* ch = 0; */
          break;
          
-       case  '/':
+       case '/':
          if (!config->scan_comment_multi ||
              g_scanner_peek_next_char (scanner) != '*')
            goto default_case;
@@ -1208,7 +1277,7 @@ g_scanner_get_token_ll    (GScanner       *scanner,
          ch = 0;
          break;
          
-       case  '\'':
+       case '\'':
          if (!config->scan_string_sq)
            goto default_case;
          token = G_TOKEN_STRING;
@@ -1227,7 +1296,7 @@ g_scanner_get_token_ll    (GScanner       *scanner,
          ch = 0;
          break;
          
-       case  '"':
+       case '"':
          if (!config->scan_string_dq)
            goto default_case;
          token = G_TOKEN_STRING;
@@ -1247,44 +1316,44 @@ g_scanner_get_token_ll  (GScanner       *scanner,
                      ch = g_scanner_get_char (scanner, line_p, position_p);
                      switch (ch)
                        {
-                         register guint        i;
-                         register guint        fchar;
+                         guint i;
+                         guint fchar;
                          
-                       case  0:
+                       case 0:
                          break;
                          
-                       case  '\\':
+                       case '\\':
                          gstring = g_string_append_c (gstring, '\\');
                          break;
                          
-                       case  'n':
+                       case 'n':
                          gstring = g_string_append_c (gstring, '\n');
                          break;
                          
-                       case  't':
+                       case 't':
                          gstring = g_string_append_c (gstring, '\t');
                          break;
                          
-                       case  'r':
+                       case 'r':
                          gstring = g_string_append_c (gstring, '\r');
                          break;
                          
-                       case  'b':
+                       case 'b':
                          gstring = g_string_append_c (gstring, '\b');
                          break;
                          
-                       case  'f':
+                       case 'f':
                          gstring = g_string_append_c (gstring, '\f');
                          break;
                          
-                       case  '0':
-                       case  '1':
-                       case  '2':
-                       case  '3':
-                       case  '4':
-                       case  '5':
-                       case  '6':
-                       case  '7':
+                       case '0':
+                       case '1':
+                       case '2':
+                       case '3':
+                       case '4':
+                       case '5':
+                       case '6':
+                       case '7':
                          i = ch - '0';
                          fchar = g_scanner_peek_next_char (scanner);
                          if (fchar >= '0' && fchar <= '7')
@@ -1313,7 +1382,7 @@ g_scanner_get_token_ll    (GScanner       *scanner,
          ch = 0;
          break;
          
-       case  '.':
+       case '.':
          if (!config->scan_float)
            goto default_case;
          token = G_TOKEN_FLOAT;
@@ -1321,14 +1390,14 @@ g_scanner_get_token_ll  (GScanner       *scanner,
          ch = g_scanner_get_char (scanner, line_p, position_p);
          goto number_parsing;
          
-       case  '$':
+       case '$':
          if (!config->scan_hex_dollar)
            goto default_case;
          token = G_TOKEN_HEX;
          ch = g_scanner_get_char (scanner, line_p, position_p);
          goto number_parsing;
          
-       case  '0':
+       case '0':
          if (config->scan_octal)
            token = G_TOKEN_OCTAL;
          else
@@ -1377,18 +1446,18 @@ g_scanner_get_token_ll  (GScanner       *scanner,
          else
            ch = '0';
          /* fall through */
-       case  '1':
-       case  '2':
-       case  '3':
-       case  '4':
-       case  '5':
-       case  '6':
-       case  '7':
-       case  '8':
-       case  '9':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
        number_parsing:
        {
-          register gboolean in_number = TRUE;
+          gboolean in_number = TRUE;
          gchar *endptr;
          
          if (token == G_TOKEN_NONE)
@@ -1399,7 +1468,7 @@ g_scanner_get_token_ll    (GScanner       *scanner,
          
          do /* while (in_number) */
            {
-             register gboolean is_E;
+             gboolean is_E;
              
              is_E = token == G_TOKEN_FLOAT && (ch == 'e' || ch == 'E');
              
@@ -1627,8 +1696,8 @@ g_scanner_get_token_ll    (GScanner       *scanner,
     {
       if (config->scan_symbols)
        {
-         register GScannerKey  *key;
-         register guint scope_id;
+         GScannerKey *key;
+         guint scope_id;
          
          scope_id = scanner->scope_id;
          key = g_scanner_lookup_internal (scanner, scope_id, value.v_identifier);