📄 language.c
字号:
return (TYPE_CODE(arg2) == TYPE_CODE(arg1)) && (TYPE_UNSIGNED(arg1) == TYPE_UNSIGNED(arg2)) ? 1 : 0; else return arg1==arg2;}/* Returns non-zero if the type is integral */intintegral_type (type) struct type *type;{ switch(current_language->la_language) { case language_c: case language_cplus: return (TYPE_CODE(type) != TYPE_CODE_INT) && (TYPE_CODE(type) != TYPE_CODE_ENUM) ? 0 : 1; case language_m2: return TYPE_CODE(type) != TYPE_CODE_INT ? 0 : 1; default: error ("Language not supported."); }}/* Returns non-zero if the value is numeric */intnumeric_type (type) struct type *type;{ switch (TYPE_CODE (type)) { case TYPE_CODE_INT: case TYPE_CODE_FLT: return 1; default: return 0; }}/* Returns non-zero if the value is a character type */intcharacter_type (type) struct type *type;{ switch(current_language->la_language) { case language_m2: return TYPE_CODE(type) != TYPE_CODE_CHAR ? 0 : 1; case language_c: case language_cplus: return (TYPE_CODE(type) == TYPE_CODE_INT) && TYPE_LENGTH(type) == sizeof(char) ? 1 : 0; default: return (0); }}/* Returns non-zero if the value is a boolean type */intboolean_type (type) struct type *type;{ switch(current_language->la_language) { case language_m2: return TYPE_CODE(type) != TYPE_CODE_BOOL ? 0 : 1; case language_c: case language_cplus: return TYPE_CODE(type) != TYPE_CODE_INT ? 0 : 1; default: return (0); }}/* Returns non-zero if the value is a floating-point type */intfloat_type (type) struct type *type;{ return TYPE_CODE(type) == TYPE_CODE_FLT;}/* Returns non-zero if the value is a pointer type */intpointer_type(type) struct type *type;{ return TYPE_CODE(type) == TYPE_CODE_PTR || TYPE_CODE(type) == TYPE_CODE_REF;}/* Returns non-zero if the value is a structured type */intstructured_type(type) struct type *type;{ switch(current_language->la_language) { case language_c: case language_cplus: return (TYPE_CODE(type) == TYPE_CODE_STRUCT) || (TYPE_CODE(type) == TYPE_CODE_UNION) || (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); default: return (0); }}/* This page contains functions that return info about (struct value) values used in GDB. *//* Returns non-zero if the value VAL represents a true value. */intvalue_true(val) value val;{ int len, i; struct type *type; LONGEST v; switch (current_language->la_language) { case language_c: case language_cplus: return !value_zerop (val); case language_m2: type = VALUE_TYPE(val); if (TYPE_CODE (type) != TYPE_CODE_BOOL) return 0; /* Not a BOOLEAN at all */ /* Search the fields for one that matches the current value. */ len = TYPE_NFIELDS (type); v = value_as_long (val); for (i = 0; i < len; i++) { QUIT; if (v == TYPE_FIELD_BITPOS (type, i)) break; } if (i >= len) return 0; /* Not a valid BOOLEAN value */ if (!strcmp ("TRUE", TYPE_FIELD_NAME(VALUE_TYPE(val), i))) return 1; /* BOOLEAN with value TRUE */ else return 0; /* BOOLEAN with value FALSE */ break; default: error ("Language not supported."); }}/* Returns non-zero if the operator OP is defined on the values ARG1 and ARG2. */#if 0 /* Currently unused */voidbinop_type_check(arg1,arg2,op) value arg1,arg2; int op;{ struct type *t1, *t2; /* If we're not checking types, always return success. */ if (!STRICT_TYPE) return; t1=VALUE_TYPE(arg1); if (arg2!=(value)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_AND: case BINOP_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: 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; /* Unary checks -- arg2 is null */ case UNOP_ZEROP: 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: /* Ok. The following operators have different meanings in different languages. */ switch(current_language->la_language) {#ifdef _LANG_c case language_c: case language_cplus: 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 } }}#endif /* 0 *//* This page contains functions for the printing out of error messages that occur during type- and range- checking. *//* Prints the format string FMT with the operator as a string corresponding to the opcode OP. If FATAL is non-zero, then this is an error and error () is called. Otherwise, it is a warning and printf() is called. */voidop_error (fmt,op,fatal) char *fmt; enum exp_opcode op; int fatal;{ if (fatal) error (fmt,op_string(op)); else { warning (fmt,op_string(op)); }}/* These are called when a language fails a type- or range-check. The first argument should be a printf()-style format string, and the rest of the arguments should be its arguments. If [type|range]_check is [type|range]_check_on, then return_to_top_level() is called in the style of error (). Otherwise, the message is prefixed by the value of warning_pre_print and we do not return to the top level. */voidtype_error (va_alist) va_dcl{ va_list args; char *string; if (type_check==type_check_warn) fprintf(stderr,warning_pre_print); else target_terminal_ours(); va_start (args); string = va_arg (args, char *); vfprintf (stderr, string, args); fprintf (stderr, "\n"); va_end (args); if (type_check==type_check_on) return_to_top_level();}voidrange_error (va_alist) va_dcl{ va_list args; char *string; if (range_check==range_check_warn) fprintf(stderr,warning_pre_print); else target_terminal_ours(); va_start (args); string = va_arg (args, char *); vfprintf (stderr, string, args); fprintf (stderr, "\n"); va_end (args); if (range_check==range_check_on) return_to_top_level();}/* This page contains miscellaneous functions *//* Return the language as a string */char *language_str(lang) 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 voidset_check (ignore, from_tty) char *ignore; int from_tty;{ printf("\"set check\" must be followed by the name of a check subcommand.\n"); help_list(setchecklist, "set check ", -1, stdout);}static voidshow_check (ignore, from_tty) char *ignore; int from_tty;{ cmd_show_list(showchecklist, from_tty, "");}/* Add a language to the set of known languages. */voidadd_language (lang) const struct language_defn *lang;{ if (lang->la_magic != LANG_MAGIC) { fprintf(stderr, "Magic number of %s language struct wrong\n", lang->la_name); abort(); } 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;}/* Define the language that is no language. */static intunk_lang_parser (){ return 1;}static voidunk_lang_error (msg) char *msg;{ error ("Attempted to parse an expression with unknown language");}static struct type ** const (unknown_builtin_types[]) = { 0 };static const struct op_print unk_op_print_tab[] = { 0 };const struct language_defn unknown_language_defn = { "unknown", language_unknown, &unknown_builtin_types[0], range_check_off, type_check_off, unk_lang_parser, unk_lang_error, &builtin_type_error, /* longest signed integral type */ &builtin_type_error, /* longest unsigned integral type */ &builtin_type_error, /* longest floating point type */ "0x%x", "0x%", "x", /* Hex format, prefix, suffix */ "0%o", "0%", "o", /* Octal format, prefix, suffix */ unk_op_print_tab, /* expression operators for printing */ LANG_MAGIC};/* These two structs define fake entries for the "local" and "auto" options. */const struct language_defn auto_language_defn = { "auto", language_auto, &unknown_builtin_types[0], range_check_off, type_check_off, unk_lang_parser, unk_lang_error, &builtin_type_error, /* longest signed integral type */ &builtin_type_error, /* longest unsigned integral type */ &builtin_type_error, /* longest floating point type */ "0x%x", "0x%", "x", /* Hex format, prefix, suffix */ "0%o", "0%", "o", /* Octal format, prefix, suffix */ unk_op_print_tab, /* expression operators for printing */ LANG_MAGIC};const struct language_defn local_language_defn = { "local", language_auto, &unknown_builtin_types[0], range_check_off, type_check_off, unk_lang_parser, unk_lang_error, &builtin_type_error, /* longest signed integral type */ &builtin_type_error, /* longest unsigned integral type */ &builtin_type_error, /* longest floating point type */ "0x%x", "0x%", "x", /* Hex format, prefix, suffix */ "0%o", "0%", "o", /* Octal format, prefix, suffix */ unk_op_print_tab, /* expression operators for printing */ LANG_MAGIC};/* Initialize the language routines */void_initialize_language(){ struct cmd_list_element *set, *show; /* GDB commands for language specific stuff */ 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->function.cfunc = set_language_command; show->function.cfunc = 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->function.cfunc = set_type_command; show->function.cfunc = 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->function.cfunc = set_range_command; show->function.cfunc = show_range_command; add_language (&unknown_language_defn); add_language (&local_language_defn); 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); set_type_command (NULL, 0); set_range_command (NULL, 0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -