20000-05-18 H.J. Lu (hjl@gnu.org)
[binutils-gdb.git] / gdb / language.c
index d177918a0ac9576627602b4dbe5ef6fd1e2cb739..20d2adb66c022543e4e8174dd48e9dee5a62be91 100644 (file)
@@ -1,5 +1,5 @@
 /* Multiple source language support for GDB.
-   Copyright 1991, 1992 Free Software Foundation, Inc.
+   Copyright 1991, 1992, 2000 Free Software Foundation, Inc.
    Contributed by the Department of Computer Science at the State University
    of New York at Buffalo.
 
@@ -86,27 +86,25 @@ set_check PARAMS ((char *, int));
 static void
 set_type_range PARAMS ((void));
 
-static void
-unk_lang_emit_char PARAMS ((int c, GDB_FILE * stream, int quoter));
+static void unk_lang_emit_char (int c, struct ui_file *stream, int quoter);
 
-static void
-unk_lang_printchar PARAMS ((int c, GDB_FILE * stream));
+static void unk_lang_printchar (int c, struct ui_file *stream);
 
-static void
-unk_lang_printstr PARAMS ((GDB_FILE * stream, char *string, unsigned int length, int width, int force_ellipses));
+static void unk_lang_printstr (struct ui_file * stream, char *string,
+                              unsigned int length, int width,
+                              int force_ellipses);
 
 static struct type *
   unk_lang_create_fundamental_type PARAMS ((struct objfile *, int));
 
-static void
-unk_lang_print_type PARAMS ((struct type *, char *, GDB_FILE *, int, int));
+static void unk_lang_print_type (struct type *, char *, struct ui_file *,
+                                int, int);
 
-static int
-unk_lang_val_print PARAMS ((struct type *, char *, int, CORE_ADDR, GDB_FILE *,
-                           int, int, int, enum val_prettyprint));
+static int unk_lang_val_print (struct type *, char *, int, CORE_ADDR,
+                              struct ui_file *, int, int, int,
+                              enum val_prettyprint);
 
-static int
-unk_lang_value_print PARAMS ((value_ptr, GDB_FILE *, int, enum val_prettyprint));
+static int unk_lang_value_print (value_ptr, struct ui_file *, int, enum val_prettyprint);
 
 /* Forward declaration */
 extern const struct language_defn unknown_language_defn;
@@ -288,6 +286,10 @@ set_type_command (ignore, from_tty)
          did it in set_type_range. */
       return;
     }
+  else
+    {
+      warning ("Unrecognized type check setting: \"%s\"", type);
+    }
   set_type_str ();
   show_type_command ((char *) NULL, from_tty);
 }
@@ -334,6 +336,10 @@ set_range_command (ignore, from_tty)
          did it in set_type_range. */
       return;
     }
+  else
+    {
+      warning ("Unrecognized range check setting: \"%s\"", range);
+    }
   set_range_str ();
   show_range_command ((char *) 0, from_tty);
 }
@@ -388,7 +394,8 @@ set_lang_str ()
 {
   char *prefix = "";
 
-  free (language);
+  if (language)
+    free (language);
   if (language_mode == language_mode_auto)
     prefix = "auto; currently ";
 
@@ -398,9 +405,10 @@ set_lang_str ()
 static void
 set_type_str ()
 {
-  char *tmp, *prefix = "";
+  char *tmp = NULL, *prefix = "";
 
-  free (type);
+  if (type)
+    free (type);
   if (type_mode == type_mode_auto)
     prefix = "auto; currently ";
 
@@ -427,7 +435,6 @@ set_range_str ()
 {
   char *tmp, *pref = "";
 
-  free (range);
   if (range_mode == range_mode_auto)
     pref = "auto; currently ";
 
@@ -446,6 +453,8 @@ set_range_str ()
       error ("Unrecognized range check setting.");
     }
 
+  if (range)
+    free (range);
   range = concat (pref, tmp, NULL);
 }
 
@@ -539,6 +548,30 @@ local_hex_format_custom (pre)
   return form;
 }
 
+#if 0
+/* FIXME: cagney/2000-03-04: This function does not appear to be used.
+   It can be deleted once 5.0 has been released. */
+/* FIXME: cagney/2000-03-04: This code assumes that the compiler
+   supports ``long long''. */
+/* Converts a number to hexadecimal (without leading "0x") and stores it in a
+   static string.  Returns a pointer to this string. */
+
+char *
+longest_raw_hex_string (num)
+     LONGEST num;
+{
+  static char res_longest_raw_hex_string[50];
+  long long ll = num;          /* MERGEBUG ?? see below */
+  res_longest_raw_hex_string[0] = 0;
+  /* MERGEBUG ?? As a quick fix I am replacing this with sprintf 
+     strcat_address_numeric (num, 0, res_longest_raw_hex_string, 50); 
+   */
+
+  sprintf (res_longest_raw_hex_string, "%llx", ll);
+  return res_longest_raw_hex_string;
+}
+#endif
+
 /* Converts a number to hexadecimal and stores it in a static
    string.  Returns a pointer to this string. */
 char *
@@ -551,6 +584,15 @@ local_hex_string (num)
   return res;
 }
 
+/* Converts a LONGEST number to hexadecimal and stores it in a static
+   string.  Returns a pointer to this string. */
+char *
+longest_local_hex_string (num)
+     LONGEST num;
+{
+  return longest_local_hex_string_custom (num, "l");
+}
+
 /* Converts a number to custom hexadecimal and stores it in a static
    string.  Returns a pointer to this string. */
 char *
@@ -564,6 +606,105 @@ local_hex_string_custom (num, pre)
   return res;
 }
 
+/* Converts a LONGEST number to custom hexadecimal and stores it in a static
+   string.  Returns a pointer to this string. Note that the width parameter
+   should end with "l", e.g. "08l" as with calls to local_hex_string_custom */
+
+char *
+longest_local_hex_string_custom (num, width)
+     LONGEST num;
+     char *width;
+{
+#define RESULT_BUF_LEN 50
+  static char res2[RESULT_BUF_LEN];
+  char format[RESULT_BUF_LEN];
+#if !defined (PRINTF_HAS_LONG_LONG)
+  int field_width;
+  int num_len;
+  int num_pad_chars;
+  char *pad_char;              /* string with one character */
+  int pad_on_left;
+  char *parse_ptr;
+  char temp_nbr_buf[RESULT_BUF_LEN];
+#endif
+
+#ifndef CC_HAS_LONG_LONG
+  /* If there is no long long, then LONGEST should be just long and we
+     can use local_hex_string_custom 
+   */
+  return local_hex_string_custom ((unsigned long) num, width);
+#elif defined (PRINTF_HAS_LONG_LONG)
+  /* Just use printf.  */
+  strcpy (format, local_hex_format_prefix ()); /* 0x */
+  strcat (format, "%");
+  strcat (format, width);      /* e.g. "08l" */
+  strcat (format, "l");                /* need "ll" for long long */
+  strcat (format, local_hex_format_specifier ());      /* "x" */
+  strcat (format, local_hex_format_suffix ()); /* "" */
+  sprintf (res2, format, num);
+  return res2;
+#else /* !defined (PRINTF_HAS_LONG_LONG) */
+  /* Use strcat_address_numeric to print the number into a string, then
+     build the result string from local_hex_format_prefix, padding and 
+     the hex representation as indicated by "width".  */
+
+  temp_nbr_buf[0] = 0;
+  /* With use_local == 0, we don't get the leading "0x" prefix. */
+  /* MERGEBUG ?? As a quick fix I am replacing this call to
+     strcat_address_numeric with sprintf
+     strcat_address_numeric(num, 0, temp_nbr_buf, RESULT_BUF_LEN);
+   */
+
+  {
+    long long ll = num;
+    sprintf (temp_nbr_buf, "%llx", ll);
+  }
+  /* parse width */
+  parse_ptr = width;
+  pad_on_left = 1;
+  pad_char = " ";
+  if (*parse_ptr == '-')
+    {
+      parse_ptr++;
+      pad_on_left = 0;
+    }
+  if (*parse_ptr == '0')
+    {
+      parse_ptr++;
+      if (pad_on_left)
+       pad_char = "0";         /* If padding is on the right, it is blank */
+    }
+  field_width = atoi (parse_ptr);
+  num_len = strlen (temp_nbr_buf);
+  num_pad_chars = field_width - strlen (temp_nbr_buf); /* possibly negative */
+
+  if (strlen (local_hex_format_prefix ()) + num_len + num_pad_chars
+      < RESULT_BUF_LEN)                /* paranoia */
+    internal_error ("longest_local_hex_string_custom: insufficient space to store result");
+
+  strcpy (res2, local_hex_format_prefix ());
+  if (pad_on_left)
+    {
+      while (num_pad_chars > 0)
+       {
+         strcat (res2, pad_char);
+         num_pad_chars--;
+       }
+    }
+  strcat (res2, temp_nbr_buf);
+  if (!pad_on_left)
+    {
+      while (num_pad_chars > 0)
+       {
+         strcat (res2, pad_char);
+         num_pad_chars--;
+       }
+    }
+  return res2;
+#endif
+
+}                              /* longest_local_hex_string_custom */
+
 /* Returns the appropriate printf format for octal
    numbers. */
 char *
@@ -1076,21 +1217,10 @@ op_error (fmt, op, fatal)
    by the value of warning_pre_print and we do not return to the top level. */
 
 void
-#ifdef ANSI_PROTOTYPES
 type_error (char *string,...)
-#else
-type_error (va_alist)
-     va_dcl
-#endif
 {
   va_list args;
-#ifdef ANSI_PROTOTYPES
   va_start (args, string);
-#else
-  char *string;
-  va_start (args);
-  string = va_arg (args, char *);
-#endif
 
   if (type_check == type_check_warn)
     fprintf_filtered (gdb_stderr, warning_pre_print);
@@ -1105,21 +1235,10 @@ type_error (va_alist)
 }
 
 void
-#ifdef ANSI_PROTOTYPES
 range_error (char *string,...)
-#else
-range_error (va_alist)
-     va_dcl
-#endif
 {
   va_list args;
-#ifdef ANSI_PROTOTYPES
   va_start (args, string);
-#else
-  char *string;
-  va_start (args);
-  string = va_arg (args, char *);
-#endif
 
   if (range_check == range_check_warn)
     fprintf_filtered (gdb_stderr, warning_pre_print);
@@ -1250,7 +1369,7 @@ unk_lang_error (msg)
 static void
 unk_lang_emit_char (c, stream, quoter)
      register int c;
-     GDB_FILE *stream;
+     struct ui_file *stream;
      int quoter;
 {
   error ("internal error - unimplemented function unk_lang_emit_char called.");
@@ -1259,14 +1378,14 @@ unk_lang_emit_char (c, stream, quoter)
 static void
 unk_lang_printchar (c, stream)
      register int c;
-     GDB_FILE *stream;
+     struct ui_file *stream;
 {
   error ("internal error - unimplemented function unk_lang_printchar called.");
 }
 
 static void
 unk_lang_printstr (stream, string, length, width, force_ellipses)
-     GDB_FILE *stream;
+     struct ui_file *stream;
      char *string;
      unsigned int length;
      int width;
@@ -1287,7 +1406,7 @@ static void
 unk_lang_print_type (type, varstring, stream, show, level)
      struct type *type;
      char *varstring;
-     GDB_FILE *stream;
+     struct ui_file *stream;
      int show;
      int level;
 {
@@ -1301,7 +1420,7 @@ unk_lang_val_print (type, valaddr, embedded_offset, address, stream, format, der
      char *valaddr;
      int embedded_offset;
      CORE_ADDR address;
-     GDB_FILE *stream;
+     struct ui_file *stream;
      int format;
      int deref_ref;
      int recurse;
@@ -1313,7 +1432,7 @@ unk_lang_val_print (type, valaddr, embedded_offset, address, stream, format, der
 static int
 unk_lang_value_print (val, stream, format, pretty)
      value_ptr val;
-     GDB_FILE *stream;
+     struct ui_file *stream;
      int format;
      enum val_prettyprint pretty;
 {
@@ -1464,12 +1583,11 @@ _initialize_language ()
   add_language (&auto_language_defn);
 
   language = savestring ("auto", strlen ("auto"));
-  range = savestring ("auto", strlen ("auto"));
-  type = savestring ("auto", strlen ("auto"));
-
-  /* Have the above take effect */
-
   set_language_command (language, 0);
+
+  type = savestring ("auto", strlen ("auto"));
   set_type_command (NULL, 0);
+
+  range = savestring ("auto", strlen ("auto"));
   set_range_command (NULL, 0);
 }