1 /**
2  * Inspired by: http://dbus-cplusplus.sourceforge.net/
3  */
4 
5 #include <iostream>
6 #include <cstdlib>
7 #include <map>
8 
9 #include "generator_utils.h"
10 #include "reserved_names.h"
11 
12 
underscorize(const std::string & str)13 std::string underscorize(const std::string& str)
14 {
15     std::string res = str;
16     for (unsigned int i = 0; i < res.length(); ++i)
17     {
18         if (!isalpha(res[i]) && !isdigit(res[i]))
19         {
20             res[i] = '_';
21         }
22     }
23     return res;
24 }
25 
stub_name(const std::string & name)26 std::string stub_name(const std::string& name)
27 {
28     return "_" + underscorize(name) + "_stub";
29 }
30 
atomic_type_to_string(char t)31 const char *atomic_type_to_string(char t)
32 {
33     static std::map<char, const char*> atos
34     {
35             { 'y', "uint8_t" },
36             { 'b', "bool" },
37             { 'n', "int16_t" },
38             { 'q', "uint16_t" },
39             { 'i', "int32_t" },
40             { 'u', "uint32_t" },
41             { 'x', "int64_t" },
42             { 't', "uint64_t" },
43             { 'd', "double" },
44             { 's', "std::string" },
45             { 'o', "sdbus::ObjectPath" },
46             { 'g', "sdbus::Signature" },
47             { 'v', "sdbus::Variant" },
48             { 'h', "sdbus::UnixFd" },
49             { '\0', "" }
50     };
51 
52     if (atos.count(t))
53     {
54         return atos[t];
55     }
56 
57     return nullptr;
58 }
59 
_parse_signature(const std::string & signature,std::string & type,unsigned int & i,bool only_once=false)60 static void _parse_signature(const std::string &signature, std::string &type, unsigned int &i, bool only_once = false)
61 {
62     for (; i < signature.length(); ++i)
63     {
64         switch (signature[i])
65         {
66             case 'a':
67             {
68                 switch (signature[++i])
69                 {
70                     case '{':
71                     {
72                         type += "std::map<";
73                         ++i;
74                         _parse_signature(signature, type, i);
75                         type += ">";
76 
77                         break;
78                     }
79                     case '(':
80                     {
81                         type += "std::vector<sdbus::Struct<";
82                         ++i;
83                         _parse_signature(signature, type, i);
84                         type += ">>";
85 
86                         break;
87                     }
88                     default:
89                     {
90                         type += "std::vector<";
91                         _parse_signature(signature, type, i, true);
92 
93                         type += ">";
94 
95                         break;
96                     }
97                 }
98                 break;
99             }
100             case '(':
101             {
102                 type += "sdbus::Struct<";
103                 ++i;
104 
105                 _parse_signature(signature, type, i);
106 
107                 type += ">";
108                 break;
109             }
110             case ')':
111             case '}':
112             {
113                 return;
114             }
115             default:
116             {
117                 const char *atom = atomic_type_to_string(signature[i]);
118                 if (!atom)
119                 {
120                     std::cerr << "Invalid signature: " << signature << std::endl;
121                     exit(-1);
122                 }
123                 type += atom;
124 
125                 break;
126             }
127         }
128 
129         if (only_once)
130             return;
131 
132         if (i + 1 < signature.length() && signature[i + 1] != ')' && signature[i + 1] != '}')
133         {
134             type += ", ";
135         }
136     }
137 }
138 
signature_to_type(const std::string & signature)139 std::string signature_to_type(const std::string& signature)
140 {
141     std::string type;
142     unsigned int i = 0;
143     _parse_signature(signature, type, i);
144     return type;
145 }
146 
mangle_name(const std::string & name)147 std::string mangle_name(const std::string& name)
148 {
149     if (reserved_names.find(name) != reserved_names.end())
150         return name + "_";
151     else
152         return name;
153 }
154