usb: getting string descriptors, minor improvements
[quarnos.git] / services / unmangler.cpp
blob5f7d5ee19cdb6edf7908107c9ef67dfe4964e6a2
1 /* Quarn OS
3 * Unmangler
5 * Copyright (C) 2009 Pawel Dziepak
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "manes/manec.h"
24 #include "unmangler.h"
26 using namespace services;
28 /* Main unmangling function */
29 string unmangler::unmangle(const string &name) const {
31 if (strncmp(name, "_Z", 2)) {
32 int index = 0;
33 return get_argument(name, index);
36 string symbol;
37 string qualify;
38 int index = 2;
39 int arguments = 0;
41 while (index < name.length()) {
42 if (arguments > 1)
43 symbol += ", ";
44 else if (arguments == 1)
45 symbol += "(";
46 if (index == 2) {
47 if (name[index] == 'K') {
48 qualify += "const";
49 index++;
52 if (name[index] == 'N') {
53 symbol += decode_name(name, index);
54 arguments++;
55 } else if (index != 2) {
56 symbol += get_argument(name, index);
57 arguments++;
60 index++;
63 symbol += (string)") " + qualify;
64 return symbol;
67 /* Unmangle name */
68 string unmangler::decode_name(const string &name, int &index) const {
69 if (name[index] != 'N')
70 return (string)"??";
72 string symbol;
73 index++;
75 do {
76 int length = 0;
77 for (;string::is_digit(name[index]); index++)
78 length = length * 10 + name[index] - '0';
80 char *scope = new char[length + 1];
81 strncpy(scope, &name[index], length);
82 scope[length] = 0;
83 if (symbol.length())
84 symbol += (string)"::";
86 symbol += (string)scope;
88 index += length;
89 } while (name[index] != 'E');
90 return symbol;
93 /* Fundamental types */
94 const int type_number = 14;
95 const char type_short[] = { 'v', 'b', 'c', 'a', 'h', 's', 't', 'i', 'j', 'l', 'm', 'x', 'y', 'f', 'd' };
96 const char* type_long[] = {
97 "void",
98 "bool",
99 "char",
100 "signed char",
101 "unsigned char",
102 "short",
103 "unsigned short",
104 "int",
105 "unsigned int",
106 "long",
107 "unsigned long",
108 "long long",
109 "unsigned long long",
110 "float",
111 "double"
114 /* Unmangle argument */
115 string unmangler::get_argument(const string &name, int &index) const {
116 string addons;
117 /* FIXME: Probably wrong order */
118 if (name[index] == 'K') {
119 addons += (string)" const";
120 index++;
122 if (name[index] == 'V') {
123 addons += (string)" volatile";
124 index++;
126 if (name[index] == 'R') {
127 addons += (string)" &";
128 index++;
129 } else if (name[index] == 'P') {
130 addons += (string)" *";
131 index++;
133 if (name[index] == 'N')
134 return (string)decode_name(name, index) + addons;
135 else if (name[index] == 'F') {
136 index++;
137 string func(get_argument(name,index));
138 func += (string)" (*)(";
139 bool first = true;
140 while (name[index] != 'E') {
141 if (!first)
142 func += (string)", ";
143 first = false;
144 func += get_argument(name,index);
145 index++;
147 func += (string)")";
148 return func;
149 } else
150 for (int i = 0; i < type_number; i++)
151 if (type_short[i] == name[index])
152 return (string)type_long[i] + addons;
153 return (string)"??";
157 void unmangler::register_type() {
158 manes::manec::get()->register_type<unmangler>("unmangler", "service");