* elf64-ppc.c (dec_dynrel_count): Don't error when elf_gc_sweep_symbol
[external/binutils.git] / sim / ppc / tree.c
index 856e90b..5d20bf4 100644 (file)
@@ -1,10 +1,10 @@
 /*  This file is part of the program psim.
 
-    Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
+    Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
 
     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 2 of the License, or
+    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,
@@ -13,8 +13,7 @@
     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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+    along with this program; if not, see <http://www.gnu.org/licenses/>.
  
     */
 
@@ -45,6 +44,7 @@
 
 #include <ctype.h>
 
+#include "libiberty.h"
 
 /* manipulate/lookup device names */
 
@@ -463,6 +463,7 @@ parse_address(device *current,
              const char *chp,
              device_unit *address)
 {
+  ASSERT(device_nr_address_cells(bus) > 0);
   if (device_decode_unit(bus, chp, address) < 0)
     device_error(current, "invalid unit address in %s", chp);
   return skip_token(chp);
@@ -485,6 +486,7 @@ parse_size(device *current,
   /* parse the numeric list */
   size->nr_cells = device_nr_size_cells(bus);
   nr = 0;
+  ASSERT(size->nr_cells > 0);
   while (1) {
     char *next;
     size->cells[nr] = strtoul(curr, &next, 0);
@@ -521,9 +523,11 @@ parse_reg_property(device *current,
   int reg_nr;
   reg_property_spec *regs;
   const char *chp;
+  device *bus = device_parent(current);
 
   /* determine the number of reg entries by counting tokens */
-  nr_regs = count_entries(current, property_name, property_value, 2);
+  nr_regs = count_entries(current, property_name, property_value,
+                         1 + (device_nr_size_cells(bus) > 0));
 
   /* create working space */
   regs = zalloc(nr_regs * sizeof(*regs));
@@ -531,17 +535,18 @@ parse_reg_property(device *current,
   /* fill it in */
   chp = property_value;
   for (reg_nr = 0; reg_nr < nr_regs; reg_nr++) {
-    chp = parse_address(current, device_parent(current),
-                       chp, &regs[reg_nr].address);
-    chp = parse_size(current, device_parent(current),
-                    chp, &regs[reg_nr].size);
+    chp = parse_address(current, bus, chp, &regs[reg_nr].address);
+    if (device_nr_size_cells(bus) > 0)
+      chp = parse_size(current, bus, chp, &regs[reg_nr].size);
+    else
+      memset(&regs[reg_nr].size, 0, sizeof (&regs[reg_nr].size));
   }
 
   /* create it */
   device_add_reg_array_property(current, property_name,
                                regs, nr_regs);
 
-  zfree(regs);
+  free(regs);
 }
 
 
@@ -578,7 +583,7 @@ parse_ranges_property(device *current,
   /* create it */
   device_add_range_array_property(current, property_name, ranges, nr_ranges);
 
-  zfree(ranges);
+  free(ranges);
 }
 
 
@@ -614,12 +619,56 @@ parse_integer_property(device *current,
     for (i = 0; i < nr_entries; i++) {
       H2BE(words[i]);
     }
-    /* perhaphs integer array property is better */
+    /* perhaps integer array property is better */
     device_add_array_property(current, property_name, words,
                               sizeof(words[0]) * nr_entries);
   }
 }
 
+/* PROPERTY_VALUE is a raw property value.  Quote it as required by
+   parse_string_property.  It is the caller's responsibility to free
+   the memory returned.  */
+
+EXTERN_TREE\
+(char *)
+tree_quote_property(const char *property_value)
+{
+  char *p;
+  char *ret;
+  const char *chp;
+  int quotees;
+
+  /* Count characters needing quotes in PROPERTY_VALUE.  */
+  quotees = 0;
+  for (chp = property_value; *chp; ++chp)
+    if (*chp == '\\' || *chp == '"')
+      ++quotees;
+  
+  ret = (char *) xmalloc (strlen (property_value) 
+                         + 2 /* quotes */
+                         + quotees
+                         + 1 /* terminator */);
+
+  p = ret;
+  /* Add the opening quote.  */
+  *p++ = '"';
+  /* Copy the value.  */
+  for (chp = property_value; *chp; ++chp)
+    if (*chp == '\\' || *chp == '"')
+      {
+       /* Quote this character.  */ 
+       *p++ = '\\';
+       *p++ = *chp;
+      }
+    else
+      *p++ = *chp;
+  /* Add the closing quote.  */
+  *p++ = '"';
+  /* Terminate the string.  */
+  *p++ = '\0';
+
+  return ret;
+}
 
 /* <string> ... */
 
@@ -720,9 +769,9 @@ parse_string_property(device *current,
   /* flush the created string */
   while (nr_strings > 0) {
     nr_strings--;
-    zfree(strings[nr_strings]);
+    free(strings[nr_strings]);
   }
-  zfree(strings);
+  free(strings);
 }
 
 
@@ -735,26 +784,11 @@ parse_ihandle_property(device *current,
                       const char *value)
 {
   ihandle_runtime_property_spec ihandle;
-  const char *chp;
-  name_specifier ihandle_spec;
 
-  /* copy over the full path */
+  /* pass the full path */
   ihandle.full_path = value;
 
-  /* copy over the args (if present) */
-  chp = strchr(value, '\0');
-  while (chp > value && *chp != '/' && *chp != ':')
-    chp--;
-  if (*chp == ':') {
-    chp += 1;
-    ihandle.args = chp;
-  }
-  else {
-    ihandle.args = NULL;
-  }
-  
   /* save this ready for the ihandle create */
-  ihandle.phandle = split_fill_path(current, ihandle.full_path, &ihandle_spec);
   device_add_ihandle_runtime_property(current, property,
                                      &ihandle);
 }
@@ -1052,8 +1086,6 @@ print_properties(device *me)
            ihandle_runtime_property_spec spec;
            device_find_ihandle_runtime_property(me, property->name, &spec);
            printf_filtered(" *%s", spec.full_path);
-           if (spec.args != NULL)
-             printf_filtered(":%s", spec.args);
          }
        }
        break;