cshape 0.2.2__tar.gz → 0.2.3__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.
- {cshape-0.2.2 → cshape-0.2.3}/PKG-INFO +1 -1
- {cshape-0.2.2 → cshape-0.2.3}/cshape.egg-info/PKG-INFO +1 -1
- {cshape-0.2.2 → cshape-0.2.3}/cshape.py +60 -57
- {cshape-0.2.2 → cshape-0.2.3}/pyproject.toml +1 -1
- {cshape-0.2.2 → cshape-0.2.3}/tests/test_smoke.py +20 -2
- {cshape-0.2.2 → cshape-0.2.3}/LICENSE +0 -0
- {cshape-0.2.2 → cshape-0.2.3}/README.md +0 -0
- {cshape-0.2.2 → cshape-0.2.3}/cshape.egg-info/SOURCES.txt +0 -0
- {cshape-0.2.2 → cshape-0.2.3}/cshape.egg-info/dependency_links.txt +0 -0
- {cshape-0.2.2 → cshape-0.2.3}/cshape.egg-info/top_level.txt +0 -0
- {cshape-0.2.2 → cshape-0.2.3}/setup.cfg +0 -0
|
@@ -247,11 +247,12 @@ class CTypeFunction(CType):
|
|
|
247
247
|
|
|
248
248
|
|
|
249
249
|
class CTypeStruct(CType):
|
|
250
|
-
def __init__(self, fields, tag, specifiers=None):
|
|
250
|
+
def __init__(self, fields, tag, specifiers=None, attributes=None):
|
|
251
251
|
super().__init__()
|
|
252
252
|
self.fields = fields
|
|
253
253
|
self.tag = tag
|
|
254
254
|
self.specifiers = specifiers if specifiers != None else []
|
|
255
|
+
self.attributes = attributes
|
|
255
256
|
self.precedence = 0
|
|
256
257
|
|
|
257
258
|
def to_str(self, text='', with_qualifiers=True):
|
|
@@ -282,7 +283,13 @@ class CTypeStruct(CType):
|
|
|
282
283
|
else:
|
|
283
284
|
sstr += 'uint8_t __placeholder;'
|
|
284
285
|
indent_down()
|
|
285
|
-
sstr += str_nl_indent(nl_end) + '}'
|
|
286
|
+
sstr += str_nl_indent(nl_end) + '}'
|
|
287
|
+
# атрибуты типа печатаем после закрывающей скобки, а не перед
|
|
288
|
+
# декларацией: в префиксной позиции компилятор их у struct/union
|
|
289
|
+
# игнорирует ("attribute is ignored, place it after struct"),
|
|
290
|
+
# а эта работает всюду - и в определении, и в typedef, и у поля
|
|
291
|
+
sstr += with_space(str_gcc_attributes(self.attributes).strip())
|
|
292
|
+
sstr += with_space(text)
|
|
286
293
|
return sstr
|
|
287
294
|
|
|
288
295
|
|
|
@@ -386,6 +393,14 @@ class KV():
|
|
|
386
393
|
self.key = key
|
|
387
394
|
self.value = value
|
|
388
395
|
self.nl = nl
|
|
396
|
+
self.mark = None
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
def str_kv(x):
|
|
400
|
+
sstr = ".%s = %s" % (x.key, str_cvalue(x.value))
|
|
401
|
+
if x.mark != None:
|
|
402
|
+
sstr = '/*%s*/' % x.mark + sstr
|
|
403
|
+
return sstr
|
|
389
404
|
|
|
390
405
|
|
|
391
406
|
class CValue():
|
|
@@ -535,7 +550,7 @@ class CValueStruct(CValue):
|
|
|
535
550
|
if item.nl == 0:
|
|
536
551
|
s_items += " "
|
|
537
552
|
s_items += str_nl_indent(item.nl)
|
|
538
|
-
s_items +=
|
|
553
|
+
s_items += str_kv(item)
|
|
539
554
|
i += 1
|
|
540
555
|
|
|
541
556
|
indent_down()
|
|
@@ -1090,7 +1105,10 @@ class CValueStringConcat(CValue):
|
|
|
1090
1105
|
def str_cvalue(v, ext_precedence=0):
|
|
1091
1106
|
assert(isinstance(v, CValue))
|
|
1092
1107
|
y = str(v)
|
|
1093
|
-
|
|
1108
|
+
# (!) mark сам по себе скобок не ставит. Комментарий в C лексически
|
|
1109
|
+
# прозрачен, а скобки - нет: отладочная пометка, меняющая
|
|
1110
|
+
# сгенерированный код, перестает быть наблюдением за ним
|
|
1111
|
+
sstr = wrap_if(y, v.precedence < ext_precedence)
|
|
1094
1112
|
if v.mark != None:
|
|
1095
1113
|
sstr = '/*%s*/' % v.mark + sstr
|
|
1096
1114
|
return sstr
|
|
@@ -1101,15 +1119,13 @@ def str_cvalue(v, ext_precedence=0):
|
|
|
1101
1119
|
|
|
1102
1120
|
def str_cstmt(x):
|
|
1103
1121
|
assert(x != None)
|
|
1104
|
-
|
|
1105
|
-
#
|
|
1106
|
-
#
|
|
1107
|
-
|
|
1108
|
-
#sstr += str_nl_indent(x.nl)
|
|
1109
|
-
sstr += str(x)
|
|
1122
|
+
# (!) перевод строки и отступ печатает обертка, а не сам узел: пометка
|
|
1123
|
+
# относится к коду, а не к пустому месту перед ним, и должна встать
|
|
1124
|
+
# между отступом и кодом - иначе она уезжает в конец предыдущей строки
|
|
1125
|
+
sstr = str_nl_indent(x.nl)
|
|
1110
1126
|
if x.mark != None:
|
|
1111
|
-
sstr
|
|
1112
|
-
return sstr
|
|
1127
|
+
sstr += '/*%s*/' % x.mark
|
|
1128
|
+
return sstr + str(x)
|
|
1113
1129
|
|
|
1114
1130
|
|
|
1115
1131
|
class CStmt():
|
|
@@ -1129,7 +1145,6 @@ class CStmtLineComment(CStmt):
|
|
|
1129
1145
|
|
|
1130
1146
|
def __str__(self):
|
|
1131
1147
|
sstr = ''
|
|
1132
|
-
sstr += str_nl_indent(self.nl)
|
|
1133
1148
|
n = len(self.lines)
|
|
1134
1149
|
i = 0
|
|
1135
1150
|
while i < n:
|
|
@@ -1149,8 +1164,7 @@ class CStmtBlockComment(CStmt):
|
|
|
1149
1164
|
self.nl = 1
|
|
1150
1165
|
|
|
1151
1166
|
def __str__(self):
|
|
1152
|
-
sstr =
|
|
1153
|
-
sstr += "/*%s*/" % self.text
|
|
1167
|
+
sstr = "/*%s*/" % self.text
|
|
1154
1168
|
return sstr
|
|
1155
1169
|
|
|
1156
1170
|
|
|
@@ -1182,8 +1196,7 @@ class CStmtExpr(CStmt):
|
|
|
1182
1196
|
self.nl = 1
|
|
1183
1197
|
|
|
1184
1198
|
def __str__(self):
|
|
1185
|
-
|
|
1186
|
-
return sstr + str_cvalue(self.value) + ';'
|
|
1199
|
+
return str_cvalue(self.value) + ';'
|
|
1187
1200
|
|
|
1188
1201
|
|
|
1189
1202
|
class CStmtAssignment(CStmt):
|
|
@@ -1195,8 +1208,7 @@ class CStmtAssignment(CStmt):
|
|
|
1195
1208
|
self.rvalue = rvalue
|
|
1196
1209
|
|
|
1197
1210
|
def __str__(self):
|
|
1198
|
-
|
|
1199
|
-
return sstr + "%s = %s;" % (str_cvalue(self.lvalue), str_cvalue(self.rvalue))
|
|
1211
|
+
return "%s = %s;" % (str_cvalue(self.lvalue), str_cvalue(self.rvalue))
|
|
1200
1212
|
|
|
1201
1213
|
|
|
1202
1214
|
class CStmtIncrement(CStmt):
|
|
@@ -1206,7 +1218,7 @@ class CStmtIncrement(CStmt):
|
|
|
1206
1218
|
self.value = value
|
|
1207
1219
|
|
|
1208
1220
|
def __str__(self):
|
|
1209
|
-
return
|
|
1221
|
+
return "++%s;" % str_cvalue(self.value)
|
|
1210
1222
|
|
|
1211
1223
|
|
|
1212
1224
|
class CStmtDecrement(CStmt):
|
|
@@ -1216,7 +1228,7 @@ class CStmtDecrement(CStmt):
|
|
|
1216
1228
|
self.value = value
|
|
1217
1229
|
|
|
1218
1230
|
def __str__(self):
|
|
1219
|
-
return
|
|
1231
|
+
return "--%s;" % str_cvalue(self.value)
|
|
1220
1232
|
|
|
1221
1233
|
|
|
1222
1234
|
class CStmtDeclType(CStmt):
|
|
@@ -1227,8 +1239,7 @@ class CStmtDeclType(CStmt):
|
|
|
1227
1239
|
self.attributes = attributes
|
|
1228
1240
|
|
|
1229
1241
|
def __str__(self):
|
|
1230
|
-
sstr =
|
|
1231
|
-
sstr += str_gcc_attributes(self.attributes)
|
|
1242
|
+
sstr = str_gcc_attributes(self.attributes)
|
|
1232
1243
|
sstr += str_ctype(self.type) + ';'
|
|
1233
1244
|
return sstr
|
|
1234
1245
|
|
|
@@ -1243,8 +1254,7 @@ class CStmtDefType(CStmt):
|
|
|
1243
1254
|
self.attributes = attributes
|
|
1244
1255
|
|
|
1245
1256
|
def __str__(self):
|
|
1246
|
-
sstr =
|
|
1247
|
-
sstr += str_gcc_attributes(self.attributes)
|
|
1257
|
+
sstr = str_gcc_attributes(self.attributes)
|
|
1248
1258
|
sstr += 'typedef %s;' % self.type.to_str(text=self.id)
|
|
1249
1259
|
return sstr
|
|
1250
1260
|
|
|
@@ -1264,11 +1274,10 @@ class CStmtDefVar(CStmt):
|
|
|
1264
1274
|
self.attributes = attributes
|
|
1265
1275
|
|
|
1266
1276
|
def __str__(self):
|
|
1267
|
-
sstr =
|
|
1268
|
-
sstr += str_gcc_attributes(self.attributes)
|
|
1277
|
+
sstr = str_gcc_attributes(self.attributes)
|
|
1269
1278
|
if self.storage not in (None, ''):
|
|
1270
1279
|
sstr += self.storage + ' '
|
|
1271
|
-
|
|
1280
|
+
|
|
1272
1281
|
sstr += str_ctype(self.type, text=self.id)
|
|
1273
1282
|
if self.initializer != None:
|
|
1274
1283
|
sstr += ' = %s' % str_cvalue(self.initializer)
|
|
@@ -1292,8 +1301,7 @@ class CStmtDefFunc(CStmt):
|
|
|
1292
1301
|
self.nl = 2
|
|
1293
1302
|
|
|
1294
1303
|
def __str__(self):
|
|
1295
|
-
sstr =
|
|
1296
|
-
sstr += str_gcc_attributes(self.attributes)
|
|
1304
|
+
sstr = str_gcc_attributes(self.attributes)
|
|
1297
1305
|
if self.storage not in (None, ''):
|
|
1298
1306
|
sstr += self.storage + ' '
|
|
1299
1307
|
sstr += self.type.to_str(text=self.id)
|
|
@@ -1320,13 +1328,12 @@ class CStmtIf(CStmt):
|
|
|
1320
1328
|
self.else_block = else_block
|
|
1321
1329
|
|
|
1322
1330
|
def __str__(self):
|
|
1323
|
-
sstr =
|
|
1324
|
-
sstr += "if (%s)" % str_cvalue(self.condition)
|
|
1331
|
+
sstr = "if (%s)" % str_cvalue(self.condition)
|
|
1325
1332
|
if styleguide['LINE_BREAK_BEFORE_BLOCK_BRACE']:
|
|
1326
1333
|
sstr += str_nl_indent()
|
|
1327
1334
|
else:
|
|
1328
1335
|
sstr += ' '
|
|
1329
|
-
sstr +=
|
|
1336
|
+
sstr += str_cstmt(self.then_block)
|
|
1330
1337
|
if self.else_block != None:
|
|
1331
1338
|
if styleguide['LINE_BREAK_BEFORE_BLOCK_BRACE']:
|
|
1332
1339
|
sstr += str_nl_indent()
|
|
@@ -1337,7 +1344,7 @@ class CStmtIf(CStmt):
|
|
|
1337
1344
|
sstr += str_nl_indent()
|
|
1338
1345
|
else:
|
|
1339
1346
|
sstr += ' '
|
|
1340
|
-
sstr +=
|
|
1347
|
+
sstr += str_cstmt(self.else_block)
|
|
1341
1348
|
return sstr
|
|
1342
1349
|
|
|
1343
1350
|
|
|
@@ -1350,13 +1357,12 @@ class CStmtWhile(CStmt):
|
|
|
1350
1357
|
self.block = block
|
|
1351
1358
|
|
|
1352
1359
|
def __str__(self):
|
|
1353
|
-
sstr =
|
|
1354
|
-
sstr += "while (%s)" % str_cvalue(self.condition)
|
|
1360
|
+
sstr = "while (%s)" % str_cvalue(self.condition)
|
|
1355
1361
|
if styleguide['LINE_BREAK_BEFORE_BLOCK_BRACE']:
|
|
1356
1362
|
sstr += str_nl_indent()
|
|
1357
1363
|
else:
|
|
1358
1364
|
sstr += ' '
|
|
1359
|
-
sstr +=
|
|
1365
|
+
sstr += str_cstmt(self.block)
|
|
1360
1366
|
return sstr
|
|
1361
1367
|
|
|
1362
1368
|
|
|
@@ -1368,8 +1374,7 @@ class CStmtReturn(CStmt):
|
|
|
1368
1374
|
self.return_value = return_value
|
|
1369
1375
|
|
|
1370
1376
|
def __str__(self):
|
|
1371
|
-
sstr =
|
|
1372
|
-
sstr += 'return'
|
|
1377
|
+
sstr = 'return'
|
|
1373
1378
|
if self.return_value != None:
|
|
1374
1379
|
sstr += ' ' + str_cvalue(self.return_value)
|
|
1375
1380
|
return sstr + ";"
|
|
@@ -1381,8 +1386,7 @@ class CStmtBreak(CStmt):
|
|
|
1381
1386
|
pass
|
|
1382
1387
|
|
|
1383
1388
|
def __str__(self):
|
|
1384
|
-
sstr =
|
|
1385
|
-
sstr += "break;"
|
|
1389
|
+
sstr = "break;"
|
|
1386
1390
|
return sstr
|
|
1387
1391
|
|
|
1388
1392
|
|
|
@@ -1392,8 +1396,7 @@ class CStmtContinue(CStmt):
|
|
|
1392
1396
|
pass
|
|
1393
1397
|
|
|
1394
1398
|
def __str__(self):
|
|
1395
|
-
sstr =
|
|
1396
|
-
sstr += "continue;"
|
|
1399
|
+
sstr = "continue;"
|
|
1397
1400
|
return sstr
|
|
1398
1401
|
|
|
1399
1402
|
|
|
@@ -1415,8 +1418,7 @@ class CStmtInlineAsm(CStmt):
|
|
|
1415
1418
|
|
|
1416
1419
|
|
|
1417
1420
|
def __str__(self):
|
|
1418
|
-
sstr =
|
|
1419
|
-
sstr += "__asm__ volatile ("
|
|
1421
|
+
sstr = "__asm__ volatile ("
|
|
1420
1422
|
sstr += '"%s" ' % self.text.replace('\n', '\\n\\\n')
|
|
1421
1423
|
|
|
1422
1424
|
sstr += ":"
|
|
@@ -1446,6 +1448,7 @@ class CStmtInlineAsm(CStmt):
|
|
|
1446
1448
|
class CRawText(CStmt):
|
|
1447
1449
|
def __init__(self, text):
|
|
1448
1450
|
super().__init__()
|
|
1451
|
+
self.nl = 0 # сырой текст печатается как есть, без отступа
|
|
1449
1452
|
self.text = text
|
|
1450
1453
|
pass
|
|
1451
1454
|
|
|
@@ -1465,8 +1468,7 @@ class CMacroDef():
|
|
|
1465
1468
|
self.mark = None
|
|
1466
1469
|
|
|
1467
1470
|
def __str__(self):
|
|
1468
|
-
sstr =
|
|
1469
|
-
sstr += "#define %s" % (self.id)
|
|
1471
|
+
sstr = "#define %s" % (self.id)
|
|
1470
1472
|
if self.text:
|
|
1471
1473
|
sstr += ' ' + self.text
|
|
1472
1474
|
return sstr
|
|
@@ -1483,9 +1485,8 @@ class CMacroDefValue():
|
|
|
1483
1485
|
self.mark = None
|
|
1484
1486
|
|
|
1485
1487
|
def __str__(self):
|
|
1486
|
-
sstr = str_nl_indent(self.nl)
|
|
1487
1488
|
set_nl_symbol(" \\\n")
|
|
1488
|
-
sstr
|
|
1489
|
+
sstr = "#define %s %s" % (self.id, str_cvalue(self.value, ext_precedence=valuePrecedenceMax))
|
|
1489
1490
|
set_nl_symbol("\n")
|
|
1490
1491
|
return sstr
|
|
1491
1492
|
|
|
@@ -1499,8 +1500,7 @@ class CMacroUndef():
|
|
|
1499
1500
|
self.mark = None
|
|
1500
1501
|
|
|
1501
1502
|
def __str__(self):
|
|
1502
|
-
sstr =
|
|
1503
|
-
sstr += "#undef %s" % (self.text)
|
|
1503
|
+
sstr = "#undef %s" % (self.text)
|
|
1504
1504
|
return sstr
|
|
1505
1505
|
|
|
1506
1506
|
|
|
@@ -1515,20 +1515,22 @@ class CInclude():
|
|
|
1515
1515
|
self.mark = None
|
|
1516
1516
|
|
|
1517
1517
|
def __str__(self):
|
|
1518
|
-
#sstr = str_nl_indent(self.nl)
|
|
1519
1518
|
if self.is_system:
|
|
1520
|
-
return "
|
|
1521
|
-
return "
|
|
1519
|
+
return "#include <%s>" % self.text
|
|
1520
|
+
return "#include \"%s\"" % self.text
|
|
1522
1521
|
|
|
1523
1522
|
|
|
1524
1523
|
def str_cdef(x):
|
|
1525
|
-
|
|
1526
|
-
|
|
1524
|
+
sstr = str_nl_indent(x.nl)
|
|
1525
|
+
if x.mark != None:
|
|
1526
|
+
sstr += '/*%s*/' % x.mark
|
|
1527
|
+
return sstr + str(x)
|
|
1527
1528
|
|
|
1528
1529
|
|
|
1529
1530
|
# pairs = ("macro text", [<defs>])
|
|
1530
1531
|
class CConditionalRegion():
|
|
1531
1532
|
def __init__(self, pairs, _else=None):
|
|
1533
|
+
self.nl = 1
|
|
1532
1534
|
self.pairs = pairs
|
|
1533
1535
|
self._else = _else
|
|
1534
1536
|
self.mark = None
|
|
@@ -1540,7 +1542,8 @@ class CConditionalRegion():
|
|
|
1540
1542
|
# if directive == '#if':
|
|
1541
1543
|
# ss = pair[0].split('()')
|
|
1542
1544
|
# print(ss)
|
|
1543
|
-
|
|
1545
|
+
# ведущий перевод строки печатает обертка, как и у всех узлов
|
|
1546
|
+
sstr += "%s%s %s" % ('' if sstr == '' else '\n', directive, pair[0])
|
|
1544
1547
|
# if len(pair[1]) > 5:
|
|
1545
1548
|
# sstr += "\n"
|
|
1546
1549
|
for xd in pair[1]:
|
|
@@ -2,8 +2,8 @@ import unittest
|
|
|
2
2
|
|
|
3
3
|
from cshape import (
|
|
4
4
|
CField, CStmtBlock, CStmtDefFunc, CStmtDefVar, CStmtReturn, CTypeArray,
|
|
5
|
-
CTypeFunction, CTypeIdentifier, CValueAdd, CValueArray,
|
|
6
|
-
CValueInteger, render,
|
|
5
|
+
CTypeFunction, CTypeIdentifier, CTypeStruct, CValueAdd, CValueArray,
|
|
6
|
+
CValueIdentifier, CValueInteger, render,
|
|
7
7
|
)
|
|
8
8
|
|
|
9
9
|
|
|
@@ -52,6 +52,24 @@ class SmokeTest(unittest.TestCase):
|
|
|
52
52
|
'int numbers[] = {\n\t1, 2\n};',
|
|
53
53
|
)
|
|
54
54
|
|
|
55
|
+
def test_struct_attributes_follow_the_closing_brace(self):
|
|
56
|
+
# a struct attribute is only read after the body: before the
|
|
57
|
+
# declaration the compiler ignores it
|
|
58
|
+
packed = CStmtDefVar(
|
|
59
|
+
id='',
|
|
60
|
+
type=CTypeStruct(
|
|
61
|
+
fields=[CField(id='tag', type=CTypeIdentifier('uint8_t')),
|
|
62
|
+
CField(id='len', type=CTypeIdentifier('uint32_t'))],
|
|
63
|
+
tag='struct header',
|
|
64
|
+
attributes={'packed': {}},
|
|
65
|
+
),
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
self.assertEqual(
|
|
69
|
+
render(packed).strip(),
|
|
70
|
+
'struct header {uint8_t tag; uint32_t len;} __attribute__((packed));',
|
|
71
|
+
)
|
|
72
|
+
|
|
55
73
|
|
|
56
74
|
if __name__ == '__main__':
|
|
57
75
|
unittest.main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|