⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 edg-decode.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
                                     a_boolean                  base_name_only,                                     a_template_param_block_ptr temp_par_info,                                     a_decode_control_block_ptr dctl)/*Demangle the type name at ptr and output the demangled form.  Return a pointerto the character position following what was demangled.  The name can bea simple type name or a nested type name, or the name of a namespace.If base_name_only is TRUE, do not put out any nested type qualifiers,e.g., put out "A::x" as simply "x".  When temp_par_info != NULL, itpoints to a block that controls output of extra information on templateparameters.  Note that this routine is called for namespaces too(the mangling is the same as for class names; you can't actually tellthe difference in a mangled name).  See demangle_type_name for aninterface to this routine for the simple case.*/{  char          *p = ptr;  unsigned long nquals;  if (*p == 'Q') {    /* A nested type name has the form         Q2_5outer5inner   (outer::inner)            ^-----^--------Names from outermost to innermost          ^----------------Number of levels of qualification.       Note that the levels in the qualifier can be class names or namespace       names. */    p = get_number(p+1, &nquals, dctl);    p = advance_past_underscore(p, dctl);    /* Handle each level of qualification. */    for (; nquals > 0; nquals--) {      if (dctl->err_in_id) break;  /* Avoid infinite loops on errors. */      /* Do not put out the nested type qualifiers if base_name_only is         TRUE. */      if (base_name_only && nquals != 1) dctl->suppress_id_output++;      p = demangle_simple_type_name(p, temp_par_info, dctl);      if (nquals != 1) write_id_str("::", dctl);      if (base_name_only && nquals != 1) dctl->suppress_id_output--;    }  /* for */  } else {#ifndef WRS_ORIG					/* WRS LOCAL */    a_template_param_block ctdt_temp_par_info;    if (base_name_only)      {	/* Also need to suppress template parameters when printing these! */	temp_par_info = &ctdt_temp_par_info;	clear_template_param_block(temp_par_info);	temp_par_info->base_name_only = TRUE;      }    /* N.B. when base_name_only is true, temp_par_info is also NULL.	We need it to pass down base_name_only, so we create a blank one	at this level. But note, we don't preserve temp_par_info so if you	add code that needs the old one, also add code to save/restore it. */#endif    /* A simple (non-nested) type name. */    p = demangle_simple_type_name(p, temp_par_info, dctl);  }  /* if */  return p;}  /* full_demangle_type_name */static char *demangle_vtbl_class_name(char                       *ptr,                                      a_decode_control_block_ptr dctl)/*Demangle a class or base class name that is one component of a virtualfunction table name.  Such names are mangled mostly as types, but witha few special quirks.*/{  char      *p = ptr;  a_boolean nested_name_case = FALSE;  /* If the name begins with a number, "Q", and another number, assume     it's a name with a form like "7Q2_1A1B", which is used to encode     A::B as the complete object class name component of a virtual     function table name.  This doesn't have any particular sense to     it; it's just what cfront does (and EDG's front end does the same     at ABI versions >= 2.30 in cfront compatibility mode).  This could     fail if the user actually has a class with a name that begins     like "Q2_", but there's not much we can do about that. */  if (isdigit((unsigned char)*p)) {    do { p++; } while (isdigit((unsigned char)*p));    if (*p == 'Q') {      char *save_p = p;      p++;      if (isdigit((unsigned char)*p)) {        do { p++; } while (isdigit((unsigned char)*p));        if (*p == '_') {          /* Yes, this is the strange nested name case.  Start the demangling             at the "Q". */          nested_name_case = TRUE;          p = save_p;        }  /* if */      }  /* if */    }  /* if */  }  /* if */  if (!nested_name_case) p = ptr;  /* Now use the normal routine to demangle the class name. */  p = demangle_type_name(p, dctl);  return p;}  /* demangle_vtbl_class_name */static char *demangle_type_qualifiers(                                     char                       *ptr,                                     a_boolean                  trailing_space,                                     a_decode_control_block_ptr dctl)/*Demangle any type qualifiers (const/volatile) at the indicated location.Return a pointer to the character position following what was demangled.If trailing_space is TRUE, add a space at the end if any qualifiers wereput out.*/{  char      *p = ptr;  a_boolean any_quals = FALSE;  for (;; p++) {    if (*p == 'C') {      if (any_quals) write_id_ch(' ', dctl);      write_id_str("const", dctl);    } else if (*p == 'V') {      if (any_quals) write_id_ch(' ', dctl);      write_id_str("volatile", dctl);    } else {      break;    }  /* if */    any_quals = TRUE;  }  /* for */  if (any_quals && trailing_space) write_id_ch(' ', dctl);  return p;}  /* demangle_type_qualifiers */static char *demangle_type_specifier(char                       *ptr,                                     a_decode_control_block_ptr dctl)/*Demangle the type at ptr and output the specifier part.  Return a pointerto the character position following what was demangled.*/{  char *p = ptr, *s;  /* Process type qualifiers. */  p = demangle_type_qualifiers(p, /*trailing_space=*/TRUE, dctl);  if (isdigit((unsigned char)*p) || *p == 'Q' || *p == 'Z') {    /* Named type, like class or enum, e.g., "3abc". */    p = demangle_type_name(p, dctl);  } else {    /* Builtin type. */    /* Handle signed and unsigned. */    if (*p == 'S') {      write_id_str("signed ", dctl);      p++;    } else if (*p == 'U') {      write_id_str("unsigned ", dctl);      p++;    }  /* if */    switch (*p++) {      case 'v':        s = "void";        break;      case 'c':        s = "char";        break;      case 'w':        s = "wchar_t";        break;      case 'b':        s = "bool";        break;      case 's':        s = "short";        break;      case 'i':        s = "int";        break;      case 'l':        s = "long";        break;      case 'L':        s = "long long";        break;      case 'f':        s = "float";        break;      case 'd':        s = "double";        break;      case 'r':        s = "long double";        break;      case 'm':        /* Microsoft intrinsic __intN types (Visual C++ 6.0 and later). */        switch (*p++) {          case '1':            s = "__int8";            break;          case '2':            s = "__int16";            break;          case '4':            s = "__int32";            break;          case '8':            s = "__int64";            break;          default:            bad_mangled_name(dctl);            s = "";        }  /* switch */        break;      default:        bad_mangled_name(dctl);        s = "";    }  /* switch */    write_id_str(s, dctl);  }  /* if */  return p;}  /* demangle_type_specifier */static char *demangle_function_parameters(char                       *ptr,                                          a_decode_control_block_ptr dctl)/*Demangle the parameter list beginning at ptr and output the demangled form.Return a pointer to the character position following what was demangled.*/{  char      *p = ptr;  char      *param_pos[10];  unsigned  long curr_param_num, param_num, nreps;  a_boolean any_params = FALSE;  write_id_ch('(', dctl);  if (*p == 'v') {    /* Void parameter list. */    p++;  } else {    any_params = TRUE;    /* Loop for each parameter. */    curr_param_num = 1;    for (;;) {      if (dctl->err_in_id) break;  /* Avoid infinite loops on errors. */      if (*p == 'T' || *p == 'N') {        /* Tn means repeat the type of parameter "n". */        /* Nmn means "m" repetitions of the type of parameter "n".  "m"           is a one-digit number. */        /* "n" is also treated as a single-digit number; the front end enforces           that (in non-cfront object code compatibility mode).  cfront does           not, which leads to some ambiguities when "n" is followed by           a class name. */        if (*p++ == 'N') {          /* Get the number of repetitions. */          p = get_single_digit_number(p, &nreps, dctl);        } else {          nreps = 1;        }  /* if */        /* Get the parameter number. */        p = get_single_digit_number(p, &param_num, dctl);        if (param_num < 1 || param_num >= curr_param_num ||            param_pos[param_num] == NULL) {          /* Parameter number out of range. */          bad_mangled_name(dctl);          goto end_of_routine;        }  /* if */        /* Produce "nreps" copies of parameter "param_num". */        for (; nreps > 0; nreps--) {          if (dctl->err_in_id) break;  /* Avoid infinite loops on errors. */          if (curr_param_num < 10) param_pos[curr_param_num] = NULL;          (void)demangle_type(param_pos[param_num], dctl);          if (nreps != 1) write_id_str(", ", dctl);          curr_param_num++;        }  /* if */      } else {        /* A normal parameter. */        if (curr_param_num < 10) param_pos[curr_param_num] = p;        p = demangle_type(p, dctl);        curr_param_num++;      }  /* if */      /* Stop after the last parameter. */      if (*p == '\0' || *p == 'e' || *p == '_') break;      write_id_str(", ", dctl);    }  /* for */  }  /* if */  if (*p == 'e') {    /* Ellipsis. */    if (any_params) write_id_str(", ", dctl);    write_id_str("...", dctl);    p++;  }  /* if */  write_id_ch(')', dctl);end_of_routine:  return p;}  /* demangle_function_parameters */static char *skip_extern_C_indication(char *ptr)/*ptr points to the character after the "F" of a function type.  Skip overand ignore an indication of extern "C" following the "F", if one is present.Return a pointer to the character following the extern "C" indication.There's no syntax for representing the extern "C" in the function type, sojust ignore it.*/{  if (*ptr == 'K') ptr++;  return ptr;}  /* skip_extern_C_indication */static char *demangle_type_first_part(                               char                       *ptr,                               a_boolean                  under_lhs_declarator,                               a_boolean                  need_trailing_space,                               a_decode_control_block_ptr dctl)/*Demangle the type at ptr and output the specifier part and the part of thedeclarator that precedes the name.  Return a pointer to the characterposition following what was demangled.  If under_lhs_declarator is TRUE,this type is directly under a type that uses a left-side declarator,e.g., a pointer type.  (That's used to control use of parentheses aroundparts of the declarator.)  If need_trailing_space is TRUE, put a spaceat the end of the specifiers part (needed if the declarator part isnot empty, because it contains a name or a derived type).*/{  char *p = ptr, *qualp = p;  char kind;  /* Remove type qualifiers. */  while (is_immediate_type_qualifier(p)) p++;  kind = *p;  if (kind == 'P' || kind == 'R') {    /* Pointer or reference type, e.g., "Pc" is pointer to char. */    p = demangle_type_first_part(p+1, /*under_lhs_declarator=*/TRUE,                                 /*need_trailing_space=*/TRUE, dctl);    /* Output "*" or "&" for pointer or reference. */    if (kind == 'R') {      write_id_ch('&', dctl);    } else {      write_id_ch('*', dctl);    }  /* if */    /* Output the type qualifiers on the pointer, if any. */    (void)demangle_type_qualifiers(qualp, /*trailing_space=*/TRUE, dctl);  } else if (kind == 'M') {    /* Pointer-to-member type, e.g., "M1Ai" is pointer to member of A of       type int. */    char *classp = p+1;    /* Skip over the class name. */    dctl->suppress_id_output++;    p = demangle_type_name(classp, dctl);    dctl->suppress_id_output--;    p = demangle_type_first_part(p, /*under_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -