lbkit 0.5.3__tar.gz → 0.5.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. {lbkit-0.5.3/lbkit.egg-info → lbkit-0.5.5}/PKG-INFO +1 -1
  2. lbkit-0.5.5/lbkit/__init__.py +2 -0
  3. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/codegen/codegen.py +2 -1
  4. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/codegen/idf_interface.py +51 -5
  5. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/codegen/template/public.c.mako +9 -0
  6. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/codegen/template/public.h.mako +3 -1
  7. lbkit-0.5.5/lbkit/codegen/template/server.c.mako +357 -0
  8. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/component/build.py +21 -2
  9. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/component/template/conanbase.mako +22 -0
  10. lbkit-0.5.5/lbkit/component/template/deploy.mako +42 -0
  11. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/misc.py +3 -1
  12. {lbkit-0.5.3 → lbkit-0.5.5/lbkit.egg-info}/PKG-INFO +1 -1
  13. lbkit-0.5.3/lbkit/__init__.py +0 -2
  14. lbkit-0.5.3/lbkit/codegen/template/server.c.mako +0 -113
  15. lbkit-0.5.3/lbkit/component/template/deploy.mako +0 -20
  16. {lbkit-0.5.3 → lbkit-0.5.5}/AUTHORS +0 -0
  17. {lbkit-0.5.3 → lbkit-0.5.5}/LICENSE +0 -0
  18. {lbkit-0.5.3 → lbkit-0.5.5}/MANIFEST.in +0 -0
  19. {lbkit-0.5.3 → lbkit-0.5.5}/README.md +0 -0
  20. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/ci_robot/__init__.py +0 -0
  21. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/ci_robot/gitee.py +0 -0
  22. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/cli.py +0 -0
  23. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/codegen/__init__.py +0 -0
  24. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/codegen/ctype_defination.py +0 -0
  25. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/codegen/renderer.py +0 -0
  26. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/codegen/template/client.c.mako +0 -0
  27. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/codegen/template/client.h.mako +0 -0
  28. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/codegen/template/interface.c.mako +0 -0
  29. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/codegen/template/interface.introspect.xml.mako +0 -0
  30. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/codegen/template/server.h.mako +0 -0
  31. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/component/__init__.py +0 -0
  32. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/component/arg_parser.py +0 -0
  33. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/component/test.py +0 -0
  34. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/errors.py +0 -0
  35. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/helper.py +0 -0
  36. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/integration/__init__.py +0 -0
  37. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/integration/build_manifest.py +0 -0
  38. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/integration/build_prepare.py +0 -0
  39. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/integration/build_rootfs.py +0 -0
  40. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/integration/config.py +0 -0
  41. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/integration/task.py +0 -0
  42. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/integration/template/conanfile.py.mako +0 -0
  43. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/lbkit.py +0 -0
  44. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/log.py +0 -0
  45. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit/tools.py +0 -0
  46. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit.egg-info/SOURCES.txt +0 -0
  47. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit.egg-info/dependency_links.txt +0 -0
  48. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit.egg-info/entry_points.txt +0 -0
  49. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit.egg-info/requires.txt +0 -0
  50. {lbkit-0.5.3 → lbkit-0.5.5}/lbkit.egg-info/top_level.txt +0 -0
  51. {lbkit-0.5.3 → lbkit-0.5.5}/setup.cfg +0 -0
  52. {lbkit-0.5.3 → lbkit-0.5.5}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lbkit
3
- Version: 0.5.3
3
+ Version: 0.5.5
4
4
  Summary: Tools provided by litebmc.com
5
5
  Home-page: https://www.litebmc.com
6
6
  Author: xuhj@litebmc.com
@@ -0,0 +1,2 @@
1
+
2
+ __version__ = '0.5.5'
@@ -16,6 +16,7 @@ from lbkit.misc import SmartFormatter
16
16
  lb_cwd = os.path.split(os.path.realpath(__file__))[0]
17
17
  log = Logger("codegen")
18
18
 
19
+ __version__=1
19
20
 
20
21
  class CodeGen(object):
21
22
  def __init__(self, args):
@@ -66,7 +67,7 @@ class CodeGen(object):
66
67
  sys.exit(-1)
67
68
  outdir = cfg.get("outdir", os.getcwd())
68
69
  self._gen(file, outdir)
69
- return
70
+ return
70
71
 
71
72
  parser = argparse.ArgumentParser(description=self.run.__doc__,
72
73
  prog="lbkit gen",
@@ -66,7 +66,8 @@ STRU_NAME_REGEX = METHOD_NAME_REGEX
66
66
  ENUM_NAME_REGEX = METHOD_NAME_REGEX
67
67
  DICT_NAME_REGEX = METHOD_NAME_REGEX
68
68
 
69
- CTYPE_REGEX = "boolean|byte|int16|uint16|int32|uint32|int64|uint64|size|ssize|double|string|object_path|signature|unixfd|variant"
69
+ CTYPE_BASE_REG = "boolean|byte|int16|uint16|int32|uint32|int64|uint64|size|ssize|double|string|object_path|signature|unixfd"
70
+ CTYPE_REGEX = CTYPE_BASE_REG + "|variant"
70
71
 
71
72
  CTYPE_SIGNATURE_MAP = {
72
73
  "boolean": "b",
@@ -136,7 +137,7 @@ class IdfCtypeRender():
136
137
  def declare(self):
137
138
  """变量申明,用于结构体(接口类、方法请求和响应、信号消息等)申明"""
138
139
  log.debug(f"Get declare info, name: {self.name}, ctype: {self.ctype}")
139
- match = re.match(f"^array\[({CTYPE_REGEX})\]$", self.ctype)
140
+ match = re.match(f"^array\[({CTYPE_BASE_REG})\]$", self.ctype)
140
141
  if match:
141
142
  ctype_obj = CTYPE_OBJS.get(self.ctype)
142
143
  return ctype_obj.declare
@@ -176,7 +177,7 @@ class IdfCtypeRender():
176
177
  def free_func(self):
177
178
  """生成释放数据的C函数,如果是结构体、字典需要生成对象的释放函数"""
178
179
  log.debug(f"Get free function info, name: {self.name}, ctype: {self.ctype}")
179
- match = re.match(f"^array\[({CTYPE_REGEX})\]$", self.ctype)
180
+ match = re.match(f"^array\[({CTYPE_BASE_REG})\]$", self.ctype)
180
181
  if match:
181
182
  ctype_obj = CTYPE_OBJS.get(self.ctype)
182
183
  return ctype_obj.free_func
@@ -205,7 +206,7 @@ class IdfCtypeRender():
205
206
 
206
207
  def encode_func(self):
207
208
  log.debug(f"Get encode function info, name: {self.name}, ctype: {self.ctype}")
208
- match = re.match(f"^array\[({CTYPE_REGEX})\]$", self.ctype)
209
+ match = re.match(f"^array\[({CTYPE_BASE_REG})\]$", self.ctype)
209
210
  if match:
210
211
  ctype_obj = CTYPE_OBJS.get(self.ctype)
211
212
  return ctype_obj.encode_func
@@ -238,7 +239,7 @@ class IdfCtypeRender():
238
239
 
239
240
  def decode_func(self):
240
241
  log.debug(f"Get decode info, name: {self.name}, ctype: {self.ctype}")
241
- match = re.match(f"^array\[({CTYPE_REGEX})\]$", self.ctype)
242
+ match = re.match(f"^array\[({CTYPE_BASE_REG})\]$", self.ctype)
242
243
  if match:
243
244
  ctype_obj = CTYPE_OBJS.get(self.ctype)
244
245
  return ctype_obj.decode_func
@@ -268,6 +269,47 @@ class IdfCtypeRender():
268
269
  else:
269
270
  return [f"<arg_in> = {stru_name}_decode(<arg_name>)"]
270
271
 
272
+ def odf_load_func(self):
273
+ log.debug(f"Get odf_load function, name: {self.name}, ctype: {self.ctype}")
274
+ # odf不支持gariant
275
+ match = re.match(f"^array\[(variant)\]$", self.ctype)
276
+ if match:
277
+ return None
278
+ match = re.match(f"^variant$", self.ctype)
279
+ if match:
280
+ return None
281
+ # 字符串数组由结束NULL表示,不需要长度
282
+ match = re.match(f"^array\[(string|object_path|signature)\]$", self.ctype)
283
+ if match:
284
+ return "<arg_name> = load_odf_as_" + match.group(1) + "_v(doc, <node>)"
285
+ match = re.match(f"^array\[({CTYPE_BASE_REG})\]$", self.ctype)
286
+ if match:
287
+ return "<arg_name> = load_odf_as_" + match.group(1) + "_v(doc, <node>, &n_<arg_name>)"
288
+ match = re.match(f"^({CTYPE_REGEX})$", self.ctype)
289
+ if match:
290
+ return "<arg_name> = load_odf_as_" + match.group(1) + "(doc, <node>)"
291
+ # 非基础类型
292
+ is_array = False
293
+ ctype = self.ctype
294
+ match = re.match(f"^array\[(.*)\]$", ctype)
295
+ if match:
296
+ is_array = True
297
+ ctype = match.group(1)
298
+ match = re.match(f"^(struct|enum|dict)\[(.*)\]$", ctype)
299
+ _, stru_name = get_intfname_and_ctype(match.group(2))
300
+ if match.group(1) == "enum":
301
+ if is_array:
302
+ # 入参为二级指针
303
+ return f"<arg_name> = _load_odf_as_{stru_name}_v(doc, <node>, &n_<arg_name>)"
304
+ else:
305
+ return f"<arg_name> = _load_odf_as_{stru_name}(doc, <node>)"
306
+ else:
307
+ if is_array:
308
+ # 入参为二级指针
309
+ return f"<arg_name> = _load_odf_as_{stru_name}_v(doc, <node>)"
310
+ else:
311
+ return f"<arg_name> = _load_odf_as_{stru_name}(doc, <node>)"
312
+
271
313
  class IdfProperty(IdfCtypeRender):
272
314
  def __init__(self, intf: IdfInterfaceBase, prop_data):
273
315
  self.intf = intf
@@ -278,8 +320,12 @@ class IdfProperty(IdfCtypeRender):
278
320
  self.annotations: list[IdfAnnotation] = []
279
321
  self.description = prop_data.get("description", "")
280
322
  flags = prop_data.get("flags", "").split(",")
323
+ self.flags = flags
281
324
  self.private = True if ("private" in flags) else False
282
325
  self.deprecated = True if ("deprecated" in flags) else False
326
+ # refobj的ctype只能是s或as
327
+ if "refobj" in flags and self.ctype != "string" and self.ctype != "array[string]":
328
+ raise IDFException(f"property {self.name} with refobj flag but type is neither s nor as")
283
329
  for k, v in ACCESS_MAP.items():
284
330
  if k in flags:
285
331
  self.access = v
@@ -140,6 +140,14 @@ static const gchar *_${name}StrMap[] = {
140
140
  % endfor
141
141
  };
142
142
 
143
+ const gchar *${name}_as_string(${name} value)
144
+ {
145
+ if (value >= _${name}Invalid) {
146
+ return "com.litebmc.Errors.Enum.Invalid";
147
+ }
148
+ return _${name}StrMap[value];
149
+ }
150
+
143
151
  /* ${name}枚举类型序列化(enum转string)函数 */
144
152
  GVariant *${name}_encode(${name} value)
145
153
  {
@@ -165,6 +173,7 @@ ${name} ${name}_decode(GVariant *in)
165
173
  }
166
174
  return _${name}Invalid;
167
175
  }
176
+
168
177
  /* ${name}枚举类型序列化(enum转string)函数 */
169
178
  GVariant *${name}_encode_v(const ${name} *values, gsize n)
170
179
  {
@@ -50,6 +50,8 @@ enum _${name} {
50
50
  _${name}Invalid,
51
51
  };
52
52
 
53
+ const gchar *${name}_as_string(${name} value);
54
+
53
55
  % endfor
54
56
  % for name, dictionary in intf.dictionaries.items():
55
57
 
@@ -82,7 +84,7 @@ ${name} *${name}_new(void);
82
84
 
83
85
  ## 定义结构体编解码和释放函数
84
86
  % for name, stru in intf.structures.items():
85
- /* ${name} dictionary object */
87
+ /* ${name} structure object */
86
88
  /* START: 结构体${name}及其数组类型的序列化、反序列化、释放函数 */
87
89
  GVariant *${name}_encode(const ${name} *value);
88
90
  ${name} *${name}_decode(GVariant *in);
@@ -0,0 +1,357 @@
1
+ #include "gcl_base.h"
2
+ #include "${intf.name}.h"
3
+
4
+ <%
5
+ class_name = intf.alias
6
+ properties = "_" + class_name + "_properties"
7
+ signal_processer = "_" + class_name + "_signals"
8
+ %>\
9
+ ## 定义结构体ODF加载函数
10
+ % for name, stru in intf.structures.items():
11
+ /* ${name} structure object */
12
+ /* START: 结构体${name}及其数组类型的ODF加载函数 */
13
+ ${name} *_load_odf_as_${name}(yaml_document_t *doc, yaml_node_t *node);
14
+ ${name} **_load_odf_as_${name}_v(yaml_document_t *doc, yaml_node_t *node);
15
+
16
+ % endfor
17
+ ## 定义枚举ODF加载函数
18
+ % for name, enum in intf.enumerations.items():
19
+ /* START: 枚举${name}及其数组类型的ODF加载函数 */
20
+ ${name} _load_odf_as_${name}(yaml_document_t *doc, yaml_node_t *node);
21
+ ${name} *_load_odf_as_${name}_v(yaml_document_t *doc, yaml_node_t *node, gsize *n);
22
+
23
+ % endfor
24
+ ## 定义字典ODF加载函数
25
+ % for name, dictionary in intf.dictionaries.items():
26
+ /* START: 字典${name}及其数组类型的ODF加载函数 */
27
+ ${name} *_load_odf_as_${name}(yaml_document_t *doc, yaml_node_t *node);
28
+ ${name} **_load_odf_as_${name}_v(yaml_document_t *doc, yaml_node_t *node);
29
+
30
+ % endfor
31
+ ## 定义结构体ODF加载函数
32
+ % for name, stru in intf.structures.items():
33
+ /* ${name} structure object */
34
+ /* START: 结构体${name}及其数组类型的ODF加载函数 */
35
+
36
+ ${name} *_load_odf_as_${name}(yaml_document_t *doc, yaml_node_t *node)
37
+ {
38
+ <% cnt = 0 %>\
39
+ % for prop in stru.values.parameters:
40
+ % if prop.odf_load_func() is not None:
41
+ <% cnt = cnt + 1 %>\
42
+ % endif
43
+ % endfor
44
+ % if cnt == 0:
45
+ return g_new0(${name}, 1);
46
+ % else:
47
+ yaml_node_t *val;
48
+ ${name} *output = g_new0(${name}, 1);
49
+ GHashTable *prop_table = load_yaml_mapping_to_hash_table(doc, node);
50
+ % for prop in stru.values.parameters:
51
+ % if prop.odf_load_func() is not None:
52
+ /* process ${prop.name} */
53
+ val = g_hash_table_lookup(prop_table, "${prop.name}");
54
+ if (val)
55
+ ${prop.odf_load_func().replace("n_<arg_name>", "output->n_" + prop.name).replace("<arg_name>", "output->" + prop.name).replace("<node>", "val")};
56
+ % endif
57
+ % endfor
58
+
59
+ g_hash_table_destroy(prop_table);
60
+ return output;
61
+ % endif
62
+ }
63
+
64
+ ${name} **_load_odf_as_${name}_v(yaml_document_t *doc, yaml_node_t *node)
65
+ {
66
+ yaml_node_t *val;
67
+ gint i = 0;
68
+ if (node->type != YAML_SEQUENCE_NODE) {
69
+ log_warn("Load array ${name} failed because node type error, need type 1(sequence), get type %d", node->type);
70
+ return g_new0(${name} *, 1);
71
+ }
72
+ yaml_node_item_t *top = node->data.sequence.items.top;
73
+ yaml_node_item_t *start = node->data.sequence.items.start;
74
+ gsize cnt = ((gsize)top - (gsize)start) / sizeof(yaml_node_item_t);
75
+ ${name} **output = g_new0(${name} *, cnt + 1);
76
+
77
+ for (yaml_node_item_t *item = start; item < top; item++) {
78
+ val = yaml_document_get_node(doc, *item);
79
+ output[i++] = _load_odf_as_${name}(doc, val);
80
+ }
81
+ return output;
82
+ }
83
+
84
+ % endfor
85
+ ## 定义枚举ODF加载函数
86
+ % for name, enum in intf.enumerations.items():
87
+
88
+ ${name} _load_odf_as_${name}(yaml_document_t *doc, yaml_node_t *node)
89
+ {
90
+ g_assert(node->type == YAML_SCALAR_NODE);
91
+ if (node->type != YAML_SCALAR_NODE) {
92
+ return _${name}Invalid;
93
+ }
94
+
95
+ for (int i = 0; i <= ${len(enum.values.parameters)}; i++) {
96
+ if (g_strcmp0(node->data.scalar.value, ${name}_as_string(i)) == 0) {
97
+ return (${name})i;
98
+ }
99
+ }
100
+ return _${name}Invalid;
101
+ }
102
+
103
+ ${name} *_load_odf_as_${name}_v(yaml_document_t *doc, yaml_node_t *node, gsize *n)
104
+ {
105
+ g_assert(doc && node && n);
106
+ yaml_node_t *val;
107
+ gint i = 0;
108
+ if (node->type != YAML_SEQUENCE_NODE) {
109
+ log_warn("Load array ${name} failed because node type error, need type 1(sequence), get type %d", node->type);
110
+ return g_new0(${name}, 1);
111
+ }
112
+ yaml_node_item_t *top = node->data.sequence.items.top;
113
+ yaml_node_item_t *start = node->data.sequence.items.start;
114
+ *n = ((gsize)top - (gsize)start) / sizeof(yaml_node_item_t);
115
+ ${name} *output = g_new0(${name}, *n);
116
+
117
+ for (yaml_node_item_t *item = start; item < top; item++) {
118
+ val = yaml_document_get_node(doc, *item);
119
+ output[i++] = _load_odf_as_${name}(doc, val);
120
+ }
121
+ return output;
122
+ }
123
+
124
+ % endfor
125
+ ## 定义字典ODF加载函数
126
+ % for name, dictionary in intf.dictionaries.items():
127
+
128
+ ${name} *_load_odf_as_${name}(yaml_document_t *doc, yaml_node_t *node)
129
+ {
130
+ GHashTable *prop_table = NULL;
131
+ yaml_node_t *val = NULL;
132
+ ${name} *dict = ${name}_new();
133
+ yaml_node_item_t *top = node->data.sequence.items.top;
134
+ yaml_node_item_t *start = node->data.sequence.items.start;
135
+ for (yaml_node_item_t *item = start; item < top; item++) {
136
+ val = yaml_document_get_node(doc, *item);
137
+ ## 转换成hash表以获取key和properties
138
+ prop_table = load_yaml_mapping_to_hash_table(doc, val);
139
+ yaml_node_t *key = g_hash_table_lookup(prop_table, "key");
140
+ yaml_node_t *properties = g_hash_table_lookup(prop_table, "properties");
141
+ g_hash_table_destroy(prop_table);
142
+
143
+ ${", ".join(dictionary.key_obj.declare()).replace("<arg_name>", "key_val").replace("<const>", "")};
144
+ ${dictionary.key_obj.odf_load_func().replace("<arg_name>", "key_val").replace("<node>", "key")};
145
+
146
+ ## 创建一个新的字典成员
147
+ ${name}${dictionary.key} *item = g_new0(${name}${dictionary.key}, 1);
148
+ ## 转换成hash表
149
+ prop_table = load_yaml_mapping_to_hash_table(doc, properties);
150
+ ## 迭代所有成员并从odf中还原数据
151
+ % for prop in dictionary.values.parameters:
152
+ % if prop.odf_load_func() is not None:
153
+ val = g_hash_table_lookup(prop_table, "${prop.name}");
154
+ if (val)
155
+ ${prop.odf_load_func().replace("n_<arg_name>", "item->n_" + prop.name).replace("<arg_name>", "item->" + prop.name).replace("<node>", "val")};
156
+ % endif
157
+ % endfor
158
+ g_hash_table_destroy(prop_table);
159
+ dict->insert(dict, key_val, &item);
160
+ % for line in dictionary.key_obj.free_func():
161
+ ${line.replace("<arg_name>", "key_val")};
162
+ % endfor
163
+ }
164
+ return dict;
165
+ }
166
+
167
+ ${name} **_load_odf_as_${name}_v(yaml_document_t *doc, yaml_node_t *node)
168
+ {
169
+ yaml_node_t *val;
170
+ gint i = 0;
171
+ if (node->type != YAML_SEQUENCE_NODE) {
172
+ log_warn("Load array ${name} failed because node type error, need type 1(sequence), get type %d", node->type);
173
+ return g_new0(${name} *, 1);
174
+ }
175
+ yaml_node_item_t *top = node->data.sequence.items.top;
176
+ yaml_node_item_t *start = node->data.sequence.items.start;
177
+ gsize cnt = ((gsize)top - (gsize)start) / sizeof(yaml_node_item_t);
178
+ ${name} **output = g_new0(${name} *, cnt + 1);
179
+
180
+ for (yaml_node_item_t *item = start; item < top; item++) {
181
+ val = yaml_document_get_node(doc, *item);
182
+ output[i++] = _load_odf_as_${name}(doc, val);
183
+ }
184
+ return output;
185
+ }
186
+
187
+ % endfor
188
+ static ${class_name}_Properties ${properties};
189
+ static const ${class_name}_Signals *${signal_processer} = NULL;
190
+
191
+ % for prop in intf.properties:
192
+ /* ${prop.description} */
193
+ % if prop.deprecated:
194
+ __attribute__((__deprecated__)) void ${class_name}_set_${prop.name}(const ${class_name} *object,
195
+ ${", ".join(prop.declare()).replace("<arg_name>", "value").replace("<const>", "const ")})
196
+ % else:
197
+ void ${class_name}_set_${prop.name}(const ${class_name} *object,
198
+ ${", ".join(prop.declare()).replace("<arg_name>", "value").replace("<const>", "const ")})
199
+ % endif
200
+ {
201
+ GVariant *tmp = NULL;
202
+ % for line in prop.encode_func():
203
+ ${line.replace("<arg_out>", "tmp").replace("n_<arg_name>", "n_value").replace("<arg_name>", "value")};
204
+ % endfor
205
+ gcl_set_value((GclObject *)object, &_${class_name}_properties.${prop.name}, tmp);
206
+ g_variant_unref(tmp);
207
+ }
208
+
209
+ % endfor
210
+ % for signal in intf.signals:
211
+ /*
212
+ * Signal: ${signal.name}
213
+ * ${signal.description}
214
+ */
215
+ % if signal.deprecated:
216
+ __attribute__((__deprecated__)) gboolean ${class_name}_${signal.name}_Signal(const ${class_name} *object,
217
+ const gchar *destination, const ${class_name}_${signal.name}_Msg *msg, GError **error)
218
+ % else:
219
+ gboolean ${class_name}_${signal.name}_Signal(const ${class_name} *object, const gchar *destination,
220
+ const ${class_name}_${signal.name}_Msg *msg, GError **error)
221
+ % endif
222
+ {
223
+ if (error == NULL) {
224
+ log_error("Emit ${signal.name} with parameter error, error is NULL");
225
+ return FALSE;
226
+ }
227
+ if (object == NULL) {
228
+ *error = g_error_new(G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Emit ${signal.name} with parameter error, object is NULL");
229
+ return FALSE;
230
+ }
231
+ return gcl_impl.emit_signal((GclObject *)object, destination,
232
+ (const GclSignal *)&${signal_processer}->${signal.name}, msg, error);
233
+ }
234
+
235
+ % endfor
236
+ static GclObject *_${class_name}_create(const gchar *obj_name, gpointer opaque);
237
+ static void _load_from_odf(yaml_document_t *doc, yaml_node_t *node, GclObject *gcl_obj,
238
+ property_reference_loaded ref_loaded, gpointer user_data);
239
+ /*
240
+ * interface: ${intf.name}
241
+ % for c in intf.description.split("\n"):
242
+ * ${c}
243
+ % endfor
244
+ */
245
+ static GclInterface _${class_name}_interface = {
246
+ .create = _${intf.alias}_create,
247
+ .load_from_odf = (object_load_from_odf)_load_from_odf,
248
+ .is_remote = 0,
249
+ .name = "${intf.name}",
250
+ .properties = (GclProperty *)&${properties},
251
+ .interface = NULL, /* load from usr/share/dbus-1/interfaces/${intf.name} by gcl_init */
252
+ };
253
+
254
+ % for prop in intf.properties:
255
+ static void _load_odf_as_prop_${prop.name}(yaml_document_t *doc, GHashTable *prop_table,
256
+ ${class_name} *obj, property_reference_loaded ref_loaded, gpointer user_data)
257
+ {
258
+ const gchar *flags = NULL;
259
+ yaml_node_t *val = g_hash_table_lookup(prop_table, "_${prop.name}_flags");
260
+ if (val && val->type == YAML_SCALAR_NODE) {
261
+ flags = val->data.scalar.value;
262
+ }
263
+ val = g_hash_table_lookup(prop_table, "${prop.name}");
264
+ if (!val) {
265
+ if (flags) {
266
+ ref_loaded(obj, &${properties}.${prop.name}, NULL, NULL, user_data, flags);
267
+ }
268
+ return;
269
+ }
270
+ % if "refobj" in prop.flags:
271
+ ref_loaded(obj, &${properties}.${prop.name}, doc, val, user_data, flags);
272
+ % else:
273
+ if (val->type == YAML_SCALAR_NODE && val->data.scalar.value[0] == '$' &&
274
+ g_regex_match(gcl_ref_prop_regex(), val->data.scalar.value, 0, NULL)) {
275
+ ref_loaded(obj, &${properties}.${prop.name}, doc, val, user_data, flags);
276
+ } else {
277
+ % if prop.odf_load_func() is not None:
278
+ ${prop.odf_load_func().replace("n_<arg_name>", "obj->n_" + prop.name).replace("<arg_name>", "obj->" + prop.name).replace("<node>", "val")};
279
+ % endif
280
+ if (flags) {
281
+ ref_loaded(obj, &${properties}.${prop.name}, NULL, NULL, user_data, flags);
282
+ }
283
+ }
284
+ % endif
285
+ }
286
+
287
+ % endfor
288
+ static void _load_from_odf(yaml_document_t *doc, yaml_node_t *node, GclObject *gcl_obj,
289
+ property_reference_loaded ref_loaded, gpointer user_data)
290
+ {
291
+ g_assert(doc && node && gcl_obj);
292
+ if (!gcl_obj) {
293
+ return;
294
+ }
295
+ <% cnt = 0 %>\
296
+ % for prop in intf.properties:
297
+ % if prop.odf_load_func() is not None:
298
+ <% cnt = cnt + 1 %>\
299
+ % endif
300
+ % endfor
301
+ % if cnt == 0:
302
+ return;
303
+ % else:
304
+ ${class_name} *obj = (${class_name} *)gcl_obj;
305
+ ${class_name}_clean(obj);
306
+ GHashTable *prop_table = load_yaml_mapping_to_hash_table(doc, node);
307
+ % for prop in intf.properties:
308
+ _load_odf_as_prop_${prop.name}(doc, prop_table, obj, ref_loaded, user_data);
309
+ % endfor
310
+
311
+ g_hash_table_destroy(prop_table);
312
+ % endif
313
+ }
314
+
315
+ /**
316
+ * @brief 分配对象
317
+ *
318
+ * @param obj_name 对象名,需要由调用者分配内存
319
+ * @param opaque 上层应用需要写入对象的用户数据,由上层应用使用
320
+ */
321
+ GclObject *_${class_name}_create(const gchar *obj_name, gpointer opaque)
322
+ {
323
+ ${class_name} *obj = g_new0(${class_name}, 1);
324
+ memcpy(obj->_base.magic, GCL_MAGIC, strlen(GCL_MAGIC) + 1);
325
+ obj->_base.lock = g_new0(GRecMutex, 1);
326
+ g_rec_mutex_init(obj->_base.lock);
327
+ obj->_base.name = obj_name;
328
+ obj->_base.intf = &_${class_name}_interface;
329
+ obj->_base.opaque = opaque;
330
+ return (GclObject *)obj;
331
+ }
332
+
333
+ GclInterface *${class_name}_interface(void)
334
+ {
335
+ return &_${class_name}_interface;
336
+ }
337
+
338
+ ${class_name}_Properties *${class_name}_properties(void)
339
+ {
340
+ return &${properties};
341
+ }
342
+
343
+ static void __attribute__((constructor(150))) ${class_name}_register(void)
344
+ {
345
+
346
+ // 从公共库中复制信号处理函数
347
+ ${signal_processer} = ${class_name}_signals();
348
+ // 从公共库中复制方法处理函数
349
+ _${class_name}_interface.methods = (GclMethod *)${class_name}_methods();
350
+ _${class_name}_interface.signals = (GclSignal *)${class_name}_signals();
351
+
352
+ // 从公共库中复制属性信息
353
+ memcpy(&${properties}, ${class_name}_properties_const(), sizeof(${properties}));
354
+ gcl_interface_register(&_${class_name}_interface,
355
+ "${intf.introspect_xml_sha256}",
356
+ "/usr/share/dbus-1/interfaces/${intf.name}.xml");
357
+ }
@@ -53,6 +53,7 @@ class BuildComponent():
53
53
  shutil.rmtree(self.rootfs_dir, ignore_errors=True)
54
54
  os.makedirs(self.rootfs_dir, exist_ok=True)
55
55
 
56
+ self.pkg = None
56
57
  self.gen_conaninfo()
57
58
  self.base_cmd = f" --user {self.user} --channel {self.channel}"
58
59
  self.base_cmd += f" -pr {self.profile} -s build_type={self.build_type} -r " + self.options.remote
@@ -108,6 +109,7 @@ class BuildComponent():
108
109
  # 构建命令未指定channel时从package.yml中读取
109
110
  pkg["channel"] = self.channel
110
111
  pkg["version"] = self.get_package_version()
112
+ self.pkg = pkg
111
113
  # 从package.yml加载基础信息
112
114
  self.name = pkg.get("name")
113
115
  self.version = pkg.get("version")
@@ -156,7 +158,7 @@ class BuildComponent():
156
158
  # 生成部署deploy命令
157
159
  lookup = TemplateLookup(directories=os.path.join(lb_cwd, "template"))
158
160
  template = lookup.get_template("deploy.mako")
159
- deploy = template.render(lookup=lookup, packages=self.runtime_packages)
161
+ deploy = template.render(lookup=lookup, pkg=self.pkg, packages=self.runtime_packages)
160
162
  dir = os.path.join(cwd, ".temp", "deploy")
161
163
  # 创建临时目录并写入conanfile.py文件
162
164
  os.makedirs(dir, exist_ok=True)
@@ -178,7 +180,7 @@ class BuildComponent():
178
180
  template = lookup.get_template("deploy.mako")
179
181
  packages = self.runtime_packages
180
182
  packages.append(self.package)
181
- deploy = template.render(lookup=lookup, packages=packages)
183
+ deploy = template.render(lookup=lookup, pkg=self.pkg, packages=packages)
182
184
  dir = os.path.join(cwd, ".temp", "deploy")
183
185
  # 创建临时目录并写入conanfile.py文件
184
186
  os.makedirs(dir, exist_ok=True)
@@ -202,7 +204,24 @@ class BuildComponent():
202
204
  # 设置ROOTFS_DIR环境变量,为DT测试提供相对路径
203
205
  os.environ["ROOTFS_DIR"] = self.rootfs_dir
204
206
 
207
+ def _validate_odf_files(self):
208
+ odf_dirs = self.pkg.get("odf_dirs", [])
209
+ for dir in odf_dirs:
210
+ for filename in os.listdir(dir):
211
+ filename = os.path.join(dir, filename)
212
+ if not os.path.isfile(filename):
213
+ continue
214
+ if not filename.endswith(".yaml"):
215
+ log.debug(f"file {filename} not endswith .yaml, skip validate")
216
+ continue
217
+
218
+ log.info(f"start validate {filename}")
219
+ validate_yml_with_json_schema(filename, "/usr/share/litebmc/schema/odf.v1.json")
220
+
205
221
  def run(self):
222
+ # start validate all odf(Object Description file) files
223
+ self._validate_odf_files()
224
+
206
225
  cmd = f"conan remove {self.package} -c"
207
226
  tools.exec(cmd)
208
227
  gen = CodeGen([])
@@ -114,6 +114,28 @@ class LiteBmcConan(ConanFile):
114
114
  % endif
115
115
  pass
116
116
 
117
+ def configure(self):
118
+ % if len(pkg.get("requires", {})) > 0:
119
+ % for conan in pkg["requires"].get("compile", []):
120
+ % if conan.get("option") is not None:
121
+ % for k, v in conan.get("option").items():
122
+ self.options["${conan.get("conan").split("/")[0]}"].${k} = ${("\"" + v + "\"") if isinstance(v, str) else str(v)}
123
+ % endfor
124
+ % endif
125
+ % endfor
126
+ <%test_requires=pkg["requires"].get("test", [])%>\
127
+ % if len(test_requires):
128
+ % for conan in test_requires:
129
+ % if conan.get("option") is not None:
130
+ % for k, v in conan.get("option").items():
131
+ self.options["${conan.get("conan").split("/")[0]}"].${k} = ${("\"" + v + "\"") if isinstance(v, str) else str(v)}
132
+ % endfor
133
+ % endif
134
+ % endfor
135
+ % endif
136
+ % endif
137
+ pass
138
+
117
139
  def _append_default_flags(self):
118
140
  flags = []
119
141
  if self.options.gcov:
@@ -0,0 +1,42 @@
1
+ from conan import ConanFile
2
+
3
+
4
+ class DeployConan(ConanFile):
5
+ name = "deploy"
6
+ settings = "os", "arch", "compiler", "build_type"
7
+ description = "部署组件"
8
+ url = "https://litebmc.com"
9
+ homepage = ""
10
+ generators = "CMakeDeps"
11
+ package_type = "application"
12
+ version = "0.0.1"
13
+ license = "MulanPSL v2"
14
+
15
+ def requirements(self):
16
+ % for package in packages:
17
+ self.requires("${package}")
18
+ % endfor
19
+ pass
20
+
21
+ def configure(self):
22
+ % if len(pkg.get("requires", {})) > 0:
23
+ % for conan in pkg["requires"].get("compile", []):
24
+ % if conan.get("option") is not None:
25
+ % for k, v in conan.get("option").items():
26
+ self.options["${conan.get("conan").split("/")[0]}"].${k} = ${("\"" + v + "\"") if isinstance(v, str) else str(v)}
27
+ % endfor
28
+ % endif
29
+ % endfor
30
+ <%test_requires=pkg["requires"].get("test", [])%>\
31
+ % if len(test_requires):
32
+ % for conan in test_requires:
33
+ % if conan.get("option") is not None:
34
+ % for k, v in conan.get("option").items():
35
+ self.options["${conan.get("conan").split("/")[0]}"].${k} = ${("\"" + v + "\"") if isinstance(v, str) else str(v)}
36
+ % endfor
37
+ % endif
38
+ % endfor
39
+ % endif
40
+ % endif
41
+ pass
42
+
@@ -78,4 +78,6 @@ def validate_yml_with_json_schema(yml_file, default_json_schema_file):
78
78
  data = yaml.safe_load(fp)
79
79
  validate(data, schema)
80
80
  except ValidationError as exc:
81
- raise PackageConfigException(f"validate {yml_file} failed, schema file is {schema_file}, message: {exc.message}")
81
+ raise PackageConfigException(f"validate {yml_file} failed, schema file is {schema_file}, "
82
+ f"message: {exc.message}\n"
83
+ "installing redhat.vscode-yaml plugin in vscode will help you write odf files")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lbkit
3
- Version: 0.5.3
3
+ Version: 0.5.5
4
4
  Summary: Tools provided by litebmc.com
5
5
  Home-page: https://www.litebmc.com
6
6
  Author: xuhj@litebmc.com
@@ -1,2 +0,0 @@
1
-
2
- __version__ = '0.5.3'
@@ -1,113 +0,0 @@
1
- #include "gcl_base.h"
2
- #include "${intf.name}.h"
3
-
4
- <%
5
- class_name = intf.alias
6
- properties = "_" + class_name + "_properties"
7
- signal_processer = "_" + class_name + "_signals"
8
- %>\
9
- static ${class_name}_Properties ${properties};
10
- static const ${class_name}_Signals *${signal_processer} = NULL;
11
-
12
- % for prop in intf.properties:
13
- /* ${prop.description} */
14
- % if prop.deprecated:
15
- __attribute__((__deprecated__)) void ${class_name}_set_${prop.name}(const ${class_name} *object,
16
- ${", ".join(prop.declare()).replace("<arg_name>", "value").replace("<const>", "const ")})
17
- % else:
18
- void ${class_name}_set_${prop.name}(const ${class_name} *object,
19
- ${", ".join(prop.declare()).replace("<arg_name>", "value").replace("<const>", "const ")})
20
- % endif
21
- {
22
- GVariant *tmp = NULL;
23
- % for line in prop.encode_func():
24
- ${line.replace("<arg_out>", "tmp").replace("n_<arg_name>", "n_value").replace("<arg_name>", "value")};
25
- % endfor
26
- gcl_set_value((GclObject *)object, &_${class_name}_properties.${prop.name}, tmp);
27
- g_variant_unref(tmp);
28
- }
29
-
30
- % endfor
31
- % for signal in intf.signals:
32
- /*
33
- * Signal: ${signal.name}
34
- * ${signal.description}
35
- */
36
- % if signal.deprecated:
37
- __attribute__((__deprecated__)) gboolean ${class_name}_${signal.name}_Signal(const ${class_name} *object,
38
- const gchar *destination, const ${class_name}_${signal.name}_Msg *msg, GError **error)
39
- % else:
40
- gboolean ${class_name}_${signal.name}_Signal(const ${class_name} *object, const gchar *destination,
41
- const ${class_name}_${signal.name}_Msg *msg, GError **error)
42
- % endif
43
- {
44
- if (error == NULL) {
45
- log_error("Emit ${signal.name} with parameter error, error is NULL");
46
- return FALSE;
47
- }
48
- if (object == NULL) {
49
- *error = g_error_new(G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Emit ${signal.name} with parameter error, object is NULL");
50
- return FALSE;
51
- }
52
- return gcl_impl.emit_signal((GclObject *)object, destination,
53
- (const GclSignal *)&${signal_processer}->${signal.name}, msg, error);
54
- }
55
-
56
- % endfor
57
- static GclObject *_${class_name}_create(const gchar *obj_name, gpointer opaque);
58
- /*
59
- * interface: ${intf.name}
60
- % for c in intf.description.split("\n"):
61
- * ${c}
62
- % endfor
63
- */
64
- static GclInterface _${class_name}_interface = {
65
- .create = _${intf.alias}_create,
66
- .is_remote = 0,
67
- .name = "${intf.name}",
68
- .properties = (GclProperty *)&${properties},
69
- .interface = NULL, /* load from usr/share/dbus-1/interfaces/${intf.name} by gcl_init */
70
- };
71
-
72
- /**
73
- * @brief 分配对象
74
- *
75
- * @param obj_name 对象名,需要由调用者分配内存
76
- * @param opaque 上层应用需要写入对象的用户数据,由上层应用使用
77
- */
78
- GclObject *_${class_name}_create(const gchar *obj_name, gpointer opaque)
79
- {
80
- ${class_name} *obj = g_new0(${class_name}, 1);
81
- memcpy(obj->_base.magic, GCL_MAGIC, strlen(GCL_MAGIC) + 1);
82
- obj->_base.lock = g_new0(GRecMutex, 1);
83
- g_rec_mutex_init(obj->_base.lock);
84
- obj->_base.name = obj_name;
85
- obj->_base.intf = &_${class_name}_interface;
86
- obj->_base.opaque = opaque;
87
- return (GclObject *)obj;
88
- }
89
-
90
- GclInterface *${class_name}_interface(void)
91
- {
92
- return &_${class_name}_interface;
93
- }
94
-
95
- ${class_name}_Properties *${class_name}_properties(void)
96
- {
97
- return &${properties};
98
- }
99
-
100
- static void __attribute__((constructor(150))) ${class_name}_register(void)
101
- {
102
- // 从公共库中复制信号处理函数
103
- ${signal_processer} = ${class_name}_signals();
104
- // 从公共库中复制方法处理函数
105
- _${class_name}_interface.methods = (GclMethod *)${class_name}_methods();
106
- _${class_name}_interface.signals = (GclSignal *)${class_name}_signals();
107
-
108
- // 从公共库中复制属性信息
109
- memcpy(&${properties}, ${class_name}_properties_const(), sizeof(${properties}));
110
- gcl_interface_register(&_${class_name}_interface,
111
- "${intf.introspect_xml_sha256}",
112
- "/usr/share/dbus-1/interfaces/${intf.name}.xml");
113
- }
@@ -1,20 +0,0 @@
1
- from conan import ConanFile
2
-
3
-
4
- class DeployConan(ConanFile):
5
- name = "deploy"
6
- settings = "os", "arch", "compiler", "build_type"
7
- description = "部署组件"
8
- url = "https://litebmc.com"
9
- homepage = ""
10
- generators = "CMakeDeps"
11
- package_type = "application"
12
- version = "0.0.1"
13
- license = "MulanPSL v2"
14
-
15
- def requirements(self):
16
- % for package in packages:
17
- self.requires("${package}")
18
- % endfor
19
- pass
20
-
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes