#include "defs.h"
#include <ctype.h>
#include "gdb_string.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "value.h"
#include "gdbcmd.h"
#include "expression.h"
#include "language.h"
#include "target.h"
#include "parser-defs.h"
#include "jv-lang.h"
extern void _initialize_language (void);
static void show_language_command (char *, int);
static void set_language_command (char *, int);
static void show_type_command (char *, int);
static void set_type_command (char *, int);
static void show_range_command (char *, int);
static void set_range_command (char *, int);
static void show_case_command (char *, int);
static void set_case_command (char *, int);
static void set_case_str (void);
static void set_range_str (void);
static void set_type_str (void);
static void set_lang_str (void);
static void unk_lang_error (char *);
static int unk_lang_parser (void);
static void show_check (char *, int);
static void set_check (char *, int);
static void set_type_range_case (void);
static void unk_lang_emit_char (int c, struct ui_file *stream, int quoter);
static void unk_lang_printchar (int c, struct ui_file *stream);
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 (struct objfile *, int);
static void unk_lang_print_type (struct type *, char *, struct ui_file *,
int, int);
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 (struct value *, struct ui_file *, int, enum val_prettyprint);
extern const struct language_defn unknown_language_defn;
enum range_mode range_mode = range_mode_auto;
enum range_check range_check = range_check_off;
enum type_mode type_mode = type_mode_auto;
enum type_check type_check = type_check_off;
enum case_mode case_mode = case_mode_auto;
enum case_sensitivity case_sensitivity = case_sensitive_on;
const struct language_defn *current_language = &unknown_language_defn;
enum language_mode language_mode = language_mode_auto;
const struct language_defn *expected_language;
static const struct language_defn **languages;
static unsigned languages_size;
static unsigned languages_allocsize;
#define DEFAULT_ALLOCSIZE 4
static char *language;
static char *type;
static char *range;
static char *case_sensitive;
char lang_frame_mismatch_warn[] =
"Warning: the current language does not match this frame.";
static void
show_language_command (char *ignore, int from_tty)
{
enum language flang;
flang = get_frame_language ();
if (flang != language_unknown &&
language_mode == language_mode_manual &&
current_language->la_language != flang)
printf_filtered ("%s\n", lang_frame_mismatch_warn);
}
static void
set_language_command (char *ignore, int from_tty)
{
int i;
enum language flang;
char *err_lang;
if (!language || !language[0])
{
printf_unfiltered ("The currently understood settings are:\n\n");
printf_unfiltered ("local or auto Automatic setting based on source file\n");
for (i = 0; i < languages_size; ++i)
{
if (languages[i]->la_language == language_unknown
|| languages[i]->la_language == language_auto)
continue;
printf_unfiltered ("%-16s Use the %c%s language\n",
languages[i]->la_name,
toupper (languages[i]->la_name[0]),
languages[i]->la_name + 1);
}
set_language (current_language->la_language);
return;
}
for (i = 0; i < languages_size; i++)
{
if (STREQ (languages[i]->la_name, language))
{
if (languages[i]->la_language == language_auto)
{
language_mode = language_mode_auto;
flang = get_frame_language ();
if (flang != language_unknown)
set_language (flang);
expected_language = current_language;
return;
}
else
{
language_mode = language_mode_manual;
current_language = languages[i];
set_type_range_case ();
set_lang_str ();
expected_language = current_language;
return;
}
}
}
err_lang = savestring (language, strlen (language));
make_cleanup (xfree, err_lang);
set_language (current_language->la_language);
error ("Unknown language `%s'.", err_lang);
}
static void
show_type_command (char *ignore, int from_tty)
{
if (type_check != current_language->la_type_check)
printf_unfiltered (
"Warning: the current type check setting does not match the language.\n");
}
static void
set_type_command (char *ignore, int from_tty)
{
if (STREQ (type, "on"))
{
type_check = type_check_on;
type_mode = type_mode_manual;
}
else if (STREQ (type, "warn"))
{
type_check = type_check_warn;
type_mode = type_mode_manual;
}
else if (STREQ (type, "off"))
{
type_check = type_check_off;
type_mode = type_mode_manual;
}
else if (STREQ (type, "auto"))
{
type_mode = type_mode_auto;
set_type_range_case ();
return;
}
else
{
warning ("Unrecognized type check setting: \"%s\"", type);
}
set_type_str ();
show_type_command ((char *) NULL, from_tty);
}
static void
show_range_command (char *ignore, int from_tty)
{
if (range_check != current_language->la_range_check)
printf_unfiltered (
"Warning: the current range check setting does not match the language.\n");
}
static void
set_range_command (char *ignore, int from_tty)
{
if (STREQ (range, "on"))
{
range_check = range_check_on;
range_mode = range_mode_manual;
}
else if (STREQ (range, "warn"))
{
range_check = range_check_warn;
range_mode = range_mode_manual;
}
else if (STREQ (range, "off"))
{
range_check = range_check_off;
range_mode = range_mode_manual;
}
else if (STREQ (range, "auto"))
{
range_mode = range_mode_auto;
set_type_range_case ();
return;
}
else
{
warning ("Unrecognized range check setting: \"%s\"", range);
}
set_range_str ();
show_range_command ((char *) 0, from_tty);
}
static void
show_case_command (char *ignore, int from_tty)
{
if (case_sensitivity != current_language->la_case_sensitivity)
printf_unfiltered(
"Warning: the current case sensitivity setting does not match the language.\n");
}
static void
set_case_command (char *ignore, int from_tty)
{
if (STREQ (case_sensitive, "on"))
{
case_sensitivity = case_sensitive_on;
case_mode = case_mode_manual;
}
else if (STREQ (case_sensitive, "off"))
{
case_sensitivity = case_sensitive_off;
case_mode = case_mode_manual;
}
else if (STREQ (case_sensitive, "auto"))
{
case_mode = case_mode_auto;
set_type_range_case ();
return;
}
else
{
warning ("Unrecognized case-sensitive setting: \"%s\"", case_sensitive);
}
set_case_str();
show_case_command ((char *) NULL, from_tty);
}
static void
set_type_range_case (void)
{
if (range_mode == range_mode_auto)
range_check = current_language->la_range_check;
if (type_mode == type_mode_auto)
type_check = current_language->la_type_check;
if (case_mode == case_mode_auto)
case_sensitivity = current_language->la_case_sensitivity;
set_type_str ();
set_range_str ();
set_case_str ();
}
enum language
set_language (enum language lang)
{
int i;
enum language prev_language;
prev_language = current_language->la_language;
for (i = 0; i < languages_size; i++)
{
if (languages[i]->la_language == lang)
{
current_language = languages[i];
set_type_range_case ();
set_lang_str ();
break;
}
}
return prev_language;
}
static void
set_lang_str (void)
{
char *prefix = "";
if (language)
xfree (language);
if (language_mode == language_mode_auto)
prefix = "auto; currently ";
language = concat (prefix, current_language->la_name, NULL);
}
static void
set_type_str (void)
{
char *tmp = NULL, *prefix = "";
if (type)
xfree (type);
if (type_mode == type_mode_auto)
prefix = "auto; currently ";
switch (type_check)
{
case type_check_on:
tmp = "on";
break;
case type_check_off:
tmp = "off";
break;
case type_check_warn:
tmp = "warn";
break;
default:
error ("Unrecognized type check setting.");
}
type = concat (prefix, tmp, NULL);
}
static void
set_range_str (void)
{
char *tmp, *pref = "";
if (range_mode == range_mode_auto)
pref = "auto; currently ";
switch (range_check)
{
case range_check_on:
tmp = "on";
break;
case range_check_off:
tmp = "off";
break;
case range_check_warn:
tmp = "warn";
break;
default:
error ("Unrecognized range check setting.");
}
if (range)
xfree (range);
range = concat (pref, tmp, NULL);
}
static void
set_case_str()
{
char *tmp = NULL, *prefix = "";
if (case_mode==case_mode_auto)
prefix = "auto; currently ";
switch (case_sensitivity)
{
case case_sensitive_on:
tmp = "on";
break;
case case_sensitive_off:
tmp = "off";
break;
default:
error ("Unrecognized case-sensitive setting.");
}
xfree (case_sensitive);
case_sensitive = concat (prefix, tmp, NULL);
}
void
language_info (int quietly)
{
if (quietly && expected_language == current_language)
return;
expected_language = current_language;
printf_unfiltered ("Current language: %s\n", language);
show_language_command ((char *) 0, 1);
if (!quietly)
{
printf_unfiltered ("Type checking: %s\n", type);
show_type_command ((char *) 0, 1);
printf_unfiltered ("Range checking: %s\n", range);
show_range_command ((char *) 0, 1);
printf_unfiltered ("Case sensitivity: %s\n", case_sensitive);
show_case_command ((char *) 0, 1);
}
}
#if 0
struct type *
binop_result_type (struct value *v1, struct value *v2)
{
int size, uns;
struct type *t1 = check_typedef (VALUE_TYPE (v1));
struct type *t2 = check_typedef (VALUE_TYPE (v2));
int l1 = TYPE_LENGTH (t1);
int l2 = TYPE_LENGTH (t2);
switch (current_language->la_language)
{
case language_c:
case language_cplus:
case language_objc:
case language_objcplus:
if (TYPE_CODE (t1) == TYPE_CODE_FLT)
return TYPE_CODE (t2) == TYPE_CODE_FLT && l2 > l1 ?
VALUE_TYPE (v2) : VALUE_TYPE (v1);
else if (TYPE_CODE (t2) == TYPE_CODE_FLT)
return TYPE_CODE (t1) == TYPE_CODE_FLT && l1 > l2 ?
VALUE_TYPE (v1) : VALUE_TYPE (v2);
else if (TYPE_UNSIGNED (t1) && l1 > l2)
return VALUE_TYPE (v1);
else if (TYPE_UNSIGNED (t2) && l2 > l1)
return VALUE_TYPE (v2);
else
return l1 > l2 ? VALUE_TYPE (v1) : VALUE_TYPE (v2);
break;
case language_m2:
return l1 > l2 ? VALUE_TYPE (v1) : VALUE_TYPE (v2);
break;
case language_chill:
error ("Missing Chill support in function binop_result_check.");
}
internal_error (__FILE__, __LINE__, "failed internal consistency check");
return (struct type *) 0;
}
#endif
char *
local_hex_format_custom (char *pre)
{
static char form[50];
strcpy (form, local_hex_format_prefix ());
strcat (form, "%");
strcat (form, pre);
strcat (form, local_hex_format_specifier ());
strcat (form, local_hex_format_suffix ());
return form;
}
char *
local_hex_string (unsigned long num)
{
static char res[50];
sprintf (res, local_hex_format (), num);
return res;
}
char *
longest_local_hex_string (LONGEST num)
{
return longest_local_hex_string_custom (num, "l");
}
char *
local_hex_string_custom (unsigned long num, char *pre)
{
static char res[50];
sprintf (res, local_hex_format_custom (pre), num);
return res;
}
char *
longest_local_hex_string_custom (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;
int pad_on_left;
char *parse_ptr;
char temp_nbr_buf[RESULT_BUF_LEN];
#endif
#ifndef CC_HAS_LONG_LONG
return local_hex_string_custom ((unsigned long) num, width);
#elif defined (PRINTF_HAS_LONG_LONG)
strcpy (format, local_hex_format_prefix ());
strcat (format, "%");
strcat (format, width);
strcat (format, "l");
strcat (format, local_hex_format_specifier ());
strcat (format, local_hex_format_suffix ());
sprintf (res2, format, num);
return res2;
#else
strcpy (temp_nbr_buf, phex_nz (num, sizeof (num)));
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";
}
field_width = atoi (parse_ptr);
num_len = strlen (temp_nbr_buf);
num_pad_chars = field_width - strlen (temp_nbr_buf);
if (strlen (local_hex_format_prefix ()) + num_len + num_pad_chars
>= RESULT_BUF_LEN)
internal_error (__FILE__, __LINE__,
"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
}
char *
local_octal_format_custom (char *pre)
{
static char form[50];
strcpy (form, local_octal_format_prefix ());
strcat (form, "%");
strcat (form, pre);
strcat (form, local_octal_format_specifier ());
strcat (form, local_octal_format_suffix ());
return form;
}
char *
local_decimal_format_custom (char *pre)
{
static char form[50];
strcpy (form, local_decimal_format_prefix ());
strcat (form, "%");
strcat (form, pre);
strcat (form, local_decimal_format_specifier ());
strcat (form, local_decimal_format_suffix ());
return form;
}
#if 0
int
simple_type (struct type *type)
{
CHECK_TYPEDEF (type);
switch (TYPE_CODE (type))
{
case TYPE_CODE_INT:
case TYPE_CODE_CHAR:
case TYPE_CODE_ENUM:
case TYPE_CODE_FLT:
case TYPE_CODE_RANGE:
case TYPE_CODE_BOOL:
return 1;
default:
return 0;
}
}
int
ordered_type (struct type *type)
{
CHECK_TYPEDEF (type);
switch (TYPE_CODE (type))
{
case TYPE_CODE_INT:
case TYPE_CODE_CHAR:
case TYPE_CODE_ENUM:
case TYPE_CODE_FLT:
case TYPE_CODE_RANGE:
return 1;
default:
return 0;
}
}
int
same_type (struct type *arg1, struct type *arg2)
{
CHECK_TYPEDEF (type);
if (structured_type (arg1) ? !structured_type (arg2) : structured_type (arg2))
return 0;
else if (structured_type (arg1) && structured_type (arg2))
return arg1 == arg2;
else if (numeric_type (arg1) && numeric_type (arg2))
return (TYPE_CODE (arg2) == TYPE_CODE (arg1)) &&
(TYPE_UNSIGNED (arg1) == TYPE_UNSIGNED (arg2))
? 1 : 0;
else
return arg1 == arg2;
}
int
integral_type (struct type *type)
{
CHECK_TYPEDEF (type);
switch (current_language->la_language)
{
case language_c:
case language_cplus:
case language_objc:
case language_objcplus:
return (TYPE_CODE (type) != TYPE_CODE_INT) &&
(TYPE_CODE (type) != TYPE_CODE_ENUM) ? 0 : 1;
case language_m2:
case language_pascal:
return TYPE_CODE (type) != TYPE_CODE_INT ? 0 : 1;
case language_chill:
error ("Missing Chill support in function integral_type.");
default:
error ("Language not supported.");
}
}
int
numeric_type (struct type *type)
{
CHECK_TYPEDEF (type);
switch (TYPE_CODE (type))
{
case TYPE_CODE_INT:
case TYPE_CODE_FLT:
return 1;
default:
return 0;
}
}
int
character_type (struct type *type)
{
CHECK_TYPEDEF (type);
switch (current_language->la_language)
{
case language_chill:
case language_m2:
case language_pascal:
return TYPE_CODE (type) != TYPE_CODE_CHAR ? 0 : 1;
case language_c:
case language_cplus:
case language_objc:
case language_objcplus:
return (TYPE_CODE (type) == TYPE_CODE_INT) &&
TYPE_LENGTH (type) == sizeof (char)
? 1 : 0;
default:
return (0);
}
}
int
string_type (struct type *type)
{
CHECK_TYPEDEF (type);
switch (current_language->la_language)
{
case language_chill:
case language_m2:
case language_pascal:
return TYPE_CODE (type) != TYPE_CODE_STRING ? 0 : 1;
case language_c:
case language_cplus:
case language_objc:
case language_objcplus:
return (0);
default:
return (0);
}
}
int
boolean_type (struct type *type)
{
CHECK_TYPEDEF (type);
if (TYPE_CODE (type) == TYPE_CODE_BOOL)
return 1;
switch (current_language->la_language)
{
case language_c:
case language_cplus:
case language_objc:
case language_objcplus:
if (TYPE_CODE (type) == TYPE_CODE_INT)
return 1;
default:
break;
}
return 0;
}
int
float_type (struct type *type)
{
CHECK_TYPEDEF (type);
return TYPE_CODE (type) == TYPE_CODE_FLT;
}
int
pointer_type (struct type *type)
{
return TYPE_CODE (type) == TYPE_CODE_PTR ||
TYPE_CODE (type) == TYPE_CODE_REF;
}
int
structured_type (struct type *type)
{
CHECK_TYPEDEF (type);
switch (current_language->la_language)
{
case language_c:
case language_cplus:
case language_objc:
case language_objcplus:
return (TYPE_CODE (type) == TYPE_CODE_STRUCT) ||
(TYPE_CODE (type) == TYPE_CODE_UNION) ||
(TYPE_CODE (type) == TYPE_CODE_ARRAY);
case language_pascal:
return (TYPE_CODE(type) == TYPE_CODE_STRUCT) ||
(TYPE_CODE(type) == TYPE_CODE_UNION) ||
(TYPE_CODE(type) == TYPE_CODE_SET) ||
(TYPE_CODE(type) == TYPE_CODE_ARRAY);
case language_m2:
return (TYPE_CODE (type) == TYPE_CODE_STRUCT) ||
(TYPE_CODE (type) == TYPE_CODE_SET) ||
(TYPE_CODE (type) == TYPE_CODE_ARRAY);
case language_chill:
error ("Missing Chill support in function structured_type.");
default:
return (0);
}
}
#endif
struct type *
lang_bool_type (void)
{
struct symbol *sym;
struct type *type;
switch (current_language->la_language)
{
case language_chill:
return builtin_type_chill_bool;
case language_fortran:
sym = lookup_symbol ("logical", NULL, VAR_NAMESPACE, NULL, NULL);
if (sym)
{
type = SYMBOL_TYPE (sym);
if (type && TYPE_CODE (type) == TYPE_CODE_BOOL)
return type;
}
return builtin_type_f_logical_s2;
case language_cplus:
case language_pascal:
if (current_language->la_language==language_cplus)
{sym = lookup_symbol ("bool", NULL, VAR_NAMESPACE, NULL, NULL);}
else
{sym = lookup_symbol ("boolean", NULL, VAR_NAMESPACE, NULL, NULL);}
if (sym)
{
type = SYMBOL_TYPE (sym);
if (type && TYPE_CODE (type) == TYPE_CODE_BOOL)
return type;
}
return builtin_type_bool;
case language_java:
sym = lookup_symbol ("boolean", NULL, VAR_NAMESPACE, NULL, NULL);
if (sym)
{
type = SYMBOL_TYPE (sym);
if (type && TYPE_CODE (type) == TYPE_CODE_BOOL)
return type;
}
return java_boolean_type;
default:
return builtin_type_int;
}
}
int
value_true (struct value *val)
{
return !value_logical_not (val);
}
#if 0
void
binop_type_check (struct value *arg1, struct value *arg2, int op)
{
struct type *t1, *t2;
if (!STRICT_TYPE)
return;
t1 = VALUE_TYPE (arg1);
if (arg2 != NULL)
t2 = VALUE_TYPE (arg2);
else
t2 = NULL;
switch (op)
{
case BINOP_ADD:
case BINOP_SUB:
if ((numeric_type (t1) && pointer_type (t2)) ||
(pointer_type (t1) && numeric_type (t2)))
{
warning ("combining pointer and integer.\n");
break;
}
case BINOP_MUL:
case BINOP_LSH:
case BINOP_RSH:
if (!numeric_type (t1) || !numeric_type (t2))
type_op_error ("Arguments to %s must be numbers.", op);
else if (!same_type (t1, t2))
type_op_error ("Arguments to %s must be of the same type.", op);
break;
case BINOP_LOGICAL_AND:
case BINOP_LOGICAL_OR:
if (!boolean_type (t1) || !boolean_type (t2))
type_op_error ("Arguments to %s must be of boolean type.", op);
break;
case BINOP_EQUAL:
if ((pointer_type (t1) && !(pointer_type (t2) || integral_type (t2))) ||
(pointer_type (t2) && !(pointer_type (t1) || integral_type (t1))))
type_op_error ("A pointer can only be compared to an integer or pointer.", op);
else if ((pointer_type (t1) && integral_type (t2)) ||
(integral_type (t1) && pointer_type (t2)))
{
warning ("combining integer and pointer.\n");
break;
}
else if (!simple_type (t1) || !simple_type (t2))
type_op_error ("Arguments to %s must be of simple type.", op);
else if (!same_type (t1, t2))
type_op_error ("Arguments to %s must be of the same type.", op);
break;
case BINOP_REM:
case BINOP_MOD:
if (!integral_type (t1) || !integral_type (t2))
type_op_error ("Arguments to %s must be of integral type.", op);
break;
case BINOP_LESS:
case BINOP_GTR:
case BINOP_LEQ:
case BINOP_GEQ:
if (!ordered_type (t1) || !ordered_type (t2))
type_op_error ("Arguments to %s must be of ordered type.", op);
else if (!same_type (t1, t2))
type_op_error ("Arguments to %s must be of the same type.", op);
break;
case BINOP_ASSIGN:
if (pointer_type (t1) && !integral_type (t2))
type_op_error ("A pointer can only be assigned an integer.", op);
else if (pointer_type (t1) && integral_type (t2))
{
warning ("combining integer and pointer.");
break;
}
else if (!simple_type (t1) || !simple_type (t2))
type_op_error ("Arguments to %s must be of simple type.", op);
else if (!same_type (t1, t2))
type_op_error ("Arguments to %s must be of the same type.", op);
break;
case BINOP_CONCAT:
if (!(string_type (t1) || character_type (t1) || integral_type (t1))
|| !(string_type (t2) || character_type (t2) || integral_type (t2)))
type_op_error ("Arguments to %s must be strings or characters.", op);
break;
case UNOP_LOGICAL_NOT:
if (!boolean_type (t1))
type_op_error ("Argument to %s must be of boolean type.", op);
break;
case UNOP_PLUS:
case UNOP_NEG:
if (!numeric_type (t1))
type_op_error ("Argument to %s must be of numeric type.", op);
break;
case UNOP_IND:
if (integral_type (t1))
{
warning ("combining pointer and integer.\n");
break;
}
else if (!pointer_type (t1))
type_op_error ("Argument to %s must be a pointer.", op);
break;
case UNOP_PREINCREMENT:
case UNOP_POSTINCREMENT:
case UNOP_PREDECREMENT:
case UNOP_POSTDECREMENT:
if (!ordered_type (t1))
type_op_error ("Argument to %s must be of an ordered type.", op);
break;
default:
switch (current_language->la_language)
{
#ifdef _LANG_c
case language_c:
case language_cplus:
case language_objc:
case language_objcplus:
switch (op)
{
case BINOP_DIV:
if (!numeric_type (t1) || !numeric_type (t2))
type_op_error ("Arguments to %s must be numbers.", op);
break;
}
break;
#endif
#ifdef _LANG_m2
case language_m2:
switch (op)
{
case BINOP_DIV:
if (!float_type (t1) || !float_type (t2))
type_op_error ("Arguments to %s must be floating point numbers.", op);
break;
case BINOP_INTDIV:
if (!integral_type (t1) || !integral_type (t2))
type_op_error ("Arguments to %s must be of integral type.", op);
break;
}
#endif
#ifdef _LANG_pascal
case language_pascal:
switch(op)
{
case BINOP_DIV:
if (!float_type(t1) && !float_type(t2))
type_op_error ("Arguments to %s must be floating point numbers.",op);
break;
case BINOP_INTDIV:
if (!integral_type(t1) || !integral_type(t2))
type_op_error ("Arguments to %s must be of integral type.",op);
break;
}
#endif
#ifdef _LANG_chill
case language_chill:
error ("Missing Chill support in function binop_type_check.");
#endif
}
}
}
#endif
void
op_error (char *fmt, enum exp_opcode op, int fatal)
{
if (fatal)
error (fmt, op_string (op));
else
{
warning (fmt, op_string (op));
}
}
void
type_error (const char *string,...)
{
va_list args;
va_start (args, string);
switch (type_check)
{
case type_check_warn:
vwarning (string, args);
break;
case type_check_on:
verror (string, args);
break;
case type_check_off:
vfprintf_filtered (gdb_stderr, string, args);
fprintf_filtered (gdb_stderr, "\n");
break;
default:
internal_error (__FILE__, __LINE__, "bad switch");
}
va_end (args);
}
void
range_error (const char *string,...)
{
va_list args;
va_start (args, string);
switch (range_check)
{
case range_check_warn:
vwarning (string, args);
break;
case range_check_on:
verror (string, args);
break;
case range_check_off:
vfprintf_filtered (gdb_stderr, string, args);
fprintf_filtered (gdb_stderr, "\n");
break;
default:
internal_error (__FILE__, __LINE__, "bad switch");
}
va_end (args);
}
enum language
language_enum (char *str)
{
int i;
for (i = 0; i < languages_size; i++)
if (STREQ (languages[i]->la_name, str))
return languages[i]->la_language;
return language_unknown;
}
const struct language_defn *
language_def (enum language lang)
{
int i;
for (i = 0; i < languages_size; i++)
{
if (languages[i]->la_language == lang)
{
return languages[i];
}
}
return NULL;
}
char *
language_str (enum language lang)
{
int i;
for (i = 0; i < languages_size; i++)
{
if (languages[i]->la_language == lang)
{
return languages[i]->la_name;
}
}
return "Unknown";
}
static void
set_check (char *ignore, int from_tty)
{
printf_unfiltered (
"\"set check\" must be followed by the name of a check subcommand.\n");
help_list (setchecklist, "set check ", -1, gdb_stdout);
}
static void
show_check (char *ignore, int from_tty)
{
cmd_show_list (showchecklist, from_tty, "");
}
void
add_language (const struct language_defn *lang)
{
if (lang->la_magic != LANG_MAGIC)
{
fprintf_unfiltered (gdb_stderr, "Magic number of %s language struct wrong\n",
lang->la_name);
internal_error (__FILE__, __LINE__, "failed internal consistency check");
}
if (!languages)
{
languages_allocsize = DEFAULT_ALLOCSIZE;
languages = (const struct language_defn **) xmalloc
(languages_allocsize * sizeof (*languages));
}
if (languages_size >= languages_allocsize)
{
languages_allocsize *= 2;
languages = (const struct language_defn **) xrealloc ((char *) languages,
languages_allocsize * sizeof (*languages));
}
languages[languages_size++] = lang;
}
static int
unk_lang_parser (void)
{
return 1;
}
static void
unk_lang_error (char *msg)
{
error ("Attempted to parse an expression with unknown language");
}
static void
unk_lang_emit_char (register int c, struct ui_file *stream, int quoter)
{
error ("internal error - unimplemented function unk_lang_emit_char called.");
}
static void
unk_lang_printchar (register int c, struct ui_file *stream)
{
error ("internal error - unimplemented function unk_lang_printchar called.");
}
static void
unk_lang_printstr (struct ui_file *stream, char *string, unsigned int length,
int width, int force_ellipses)
{
error ("internal error - unimplemented function unk_lang_printstr called.");
}
static struct type *
unk_lang_create_fundamental_type (struct objfile *objfile, int typeid)
{
error ("internal error - unimplemented function unk_lang_create_fundamental_type called.");
}
static void
unk_lang_print_type (struct type *type, char *varstring, struct ui_file *stream,
int show, int level)
{
error ("internal error - unimplemented function unk_lang_print_type called.");
}
static int
unk_lang_val_print (struct type *type, char *valaddr, int embedded_offset,
CORE_ADDR address, struct ui_file *stream, int format,
int deref_ref, int recurse, enum val_prettyprint pretty)
{
error ("internal error - unimplemented function unk_lang_val_print called.");
}
static int
unk_lang_value_print (struct value *val, struct ui_file *stream, int format,
enum val_prettyprint pretty)
{
error ("internal error - unimplemented function unk_lang_value_print called.");
}
static struct type **const (unknown_builtin_types[]) =
{
0
};
static const struct op_print unk_op_print_tab[] =
{
{NULL, OP_NULL, PREC_NULL, 0}
};
const struct language_defn unknown_language_defn =
{
"unknown",
language_unknown,
&unknown_builtin_types[0],
range_check_off,
type_check_off,
case_sensitive_on,
unk_lang_parser,
unk_lang_error,
evaluate_subexp_standard,
unk_lang_printchar,
unk_lang_printstr,
unk_lang_emit_char,
unk_lang_create_fundamental_type,
unk_lang_print_type,
unk_lang_val_print,
unk_lang_value_print,
{"", "", "", ""},
{"0%lo", "0", "o", ""},
{"%ld", "", "d", ""},
{"0x%lx", "0x", "x", ""},
unk_op_print_tab,
1,
0,
&builtin_type_char,
LANG_MAGIC
};
const struct language_defn auto_language_defn =
{
"auto",
language_auto,
&unknown_builtin_types[0],
range_check_off,
type_check_off,
case_sensitive_on,
unk_lang_parser,
unk_lang_error,
evaluate_subexp_standard,
unk_lang_printchar,
unk_lang_printstr,
unk_lang_emit_char,
unk_lang_create_fundamental_type,
unk_lang_print_type,
unk_lang_val_print,
unk_lang_value_print,
{"", "", "", ""},
{"0%lo", "0", "o", ""},
{"%ld", "", "d", ""},
{"0x%lx", "0x", "x", ""},
unk_op_print_tab,
1,
0,
&builtin_type_char,
LANG_MAGIC
};
const struct language_defn local_language_defn =
{
"local",
language_auto,
&unknown_builtin_types[0],
range_check_off,
type_check_off,
case_sensitive_on,
unk_lang_parser,
unk_lang_error,
evaluate_subexp_standard,
unk_lang_printchar,
unk_lang_printstr,
unk_lang_emit_char,
unk_lang_create_fundamental_type,
unk_lang_print_type,
unk_lang_val_print,
unk_lang_value_print,
{"", "", "", ""},
{"0%lo", "0", "o", ""},
{"%ld", "", "d", ""},
{"0x%lx", "0x", "x", ""},
unk_op_print_tab,
1,
0,
&builtin_type_char,
LANG_MAGIC
};
void
_initialize_language (void)
{
struct cmd_list_element *set, *show;
set = add_set_cmd ("language", class_support, var_string_noescape,
(char *) &language,
"Set the current source language.",
&setlist);
show = add_show_from_set (set, &showlist);
set_cmd_cfunc (set, set_language_command);
set_cmd_cfunc (show, show_language_command);
add_prefix_cmd ("check", no_class, set_check,
"Set the status of the type/range checker.",
&setchecklist, "set check ", 0, &setlist);
add_alias_cmd ("c", "check", no_class, 1, &setlist);
add_alias_cmd ("ch", "check", no_class, 1, &setlist);
add_prefix_cmd ("check", no_class, show_check,
"Show the status of the type/range checker.",
&showchecklist, "show check ", 0, &showlist);
add_alias_cmd ("c", "check", no_class, 1, &showlist);
add_alias_cmd ("ch", "check", no_class, 1, &showlist);
set = add_set_cmd ("type", class_support, var_string_noescape,
(char *) &type,
"Set type checking. (on/warn/off/auto)",
&setchecklist);
show = add_show_from_set (set, &showchecklist);
set_cmd_cfunc (set, set_type_command);
set_cmd_cfunc (show, show_type_command);
set = add_set_cmd ("range", class_support, var_string_noescape,
(char *) &range,
"Set range checking. (on/warn/off/auto)",
&setchecklist);
show = add_show_from_set (set, &showchecklist);
set_cmd_cfunc (set, set_range_command);
set_cmd_cfunc (show, show_range_command);
set = add_set_cmd ("case-sensitive", class_support, var_string_noescape,
(char *) &case_sensitive,
"Set case sensitivity in name search. (on/off/auto)\n\
For Fortran the default is off; for other languages the default is on.",
&setlist);
show = add_show_from_set (set, &showlist);
set_cmd_cfunc (set, set_case_command);
set_cmd_cfunc (show, show_case_command);
add_language (&unknown_language_defn);
add_language (&local_language_defn);
add_language (&auto_language_defn);
language = savestring ("auto", strlen ("auto"));
type = savestring ("auto", strlen ("auto"));
range = savestring ("auto", strlen ("auto"));
case_sensitive = savestring ("auto",strlen ("auto"));
set_language (language_auto);
}