synapse 2.155.0__py311-none-any.whl → 2.156.0__py311-none-any.whl
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.
Potentially problematic release.
This version of synapse might be problematic. Click here for more details.
- synapse/cmds/cortex.py +2 -14
- synapse/common.py +1 -28
- synapse/cortex.py +10 -510
- synapse/lib/ast.py +60 -1
- synapse/lib/cell.py +33 -8
- synapse/lib/certdir.py +11 -0
- synapse/lib/cmdr.py +0 -5
- synapse/lib/gis.py +2 -2
- synapse/lib/httpapi.py +1 -43
- synapse/lib/layer.py +64 -201
- synapse/lib/lmdbslab.py +11 -0
- synapse/lib/node.py +1 -3
- synapse/lib/parser.py +10 -0
- synapse/lib/snap.py +121 -21
- synapse/lib/storm.lark +23 -6
- synapse/lib/storm.py +15 -338
- synapse/lib/storm_format.py +5 -0
- synapse/lib/stormlib/gen.py +1 -2
- synapse/lib/stormlib/gis.py +41 -0
- synapse/lib/stormlib/stats.py +21 -2
- synapse/lib/stormlib/storm.py +16 -1
- synapse/lib/stormtypes.py +225 -12
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +96 -21
- synapse/models/inet.py +60 -30
- synapse/models/infotech.py +56 -1
- synapse/models/orgs.py +3 -0
- synapse/models/risk.py +15 -0
- synapse/models/syn.py +0 -38
- synapse/tests/test_cmds_cortex.py +1 -1
- synapse/tests/test_cortex.py +32 -336
- synapse/tests/test_lib_agenda.py +19 -54
- synapse/tests/test_lib_aha.py +97 -0
- synapse/tests/test_lib_ast.py +402 -0
- synapse/tests/test_lib_grammar.py +30 -10
- synapse/tests/test_lib_httpapi.py +0 -46
- synapse/tests/test_lib_layer.py +19 -234
- synapse/tests/test_lib_lmdbslab.py +22 -0
- synapse/tests/test_lib_snap.py +9 -0
- synapse/tests/test_lib_storm.py +16 -309
- synapse/tests/test_lib_stormlib_gis.py +21 -0
- synapse/tests/test_lib_stormlib_stats.py +107 -20
- synapse/tests/test_lib_stormlib_storm.py +25 -0
- synapse/tests/test_lib_stormtypes.py +231 -8
- synapse/tests/test_lib_view.py +6 -13
- synapse/tests/test_model_base.py +1 -1
- synapse/tests/test_model_inet.py +15 -0
- synapse/tests/test_model_infotech.py +60 -0
- synapse/tests/test_model_orgs.py +10 -0
- synapse/tests/test_model_person.py +0 -3
- synapse/tests/test_model_risk.py +20 -0
- synapse/tests/test_model_syn.py +20 -34
- synapse/tests/test_tools_csvtool.py +2 -1
- synapse/tests/test_tools_feed.py +4 -30
- synapse/tools/csvtool.py +2 -1
- {synapse-2.155.0.dist-info → synapse-2.156.0.dist-info}/METADATA +3 -3
- {synapse-2.155.0.dist-info → synapse-2.156.0.dist-info}/RECORD +60 -62
- {synapse-2.155.0.dist-info → synapse-2.156.0.dist-info}/WHEEL +1 -1
- synapse/cmds/cron.py +0 -726
- synapse/cmds/trigger.py +0 -319
- synapse/tests/test_cmds_cron.py +0 -453
- synapse/tests/test_cmds_trigger.py +0 -176
- {synapse-2.155.0.dist-info → synapse-2.156.0.dist-info}/LICENSE +0 -0
- {synapse-2.155.0.dist-info → synapse-2.156.0.dist-info}/top_level.txt +0 -0
synapse/lib/parser.py
CHANGED
|
@@ -113,10 +113,13 @@ terminalEnglishMap = {
|
|
|
113
113
|
'_EDGEN1INIT': '-(',
|
|
114
114
|
'_EDGEN2INIT': '<(',
|
|
115
115
|
'_EDGEN2FINI': ')-',
|
|
116
|
+
'_EDGEN1JOINFINI': ')+>',
|
|
117
|
+
'_EDGEN2JOININIT': '<+(',
|
|
116
118
|
'_ELSE': 'else',
|
|
117
119
|
'_EMBEDQUERYSTART': '${',
|
|
118
120
|
'_EXPRCOLONNOSPACE': ':',
|
|
119
121
|
'_EMIT': 'emit',
|
|
122
|
+
'_EMPTY': 'empty',
|
|
120
123
|
'_FINI': 'fini',
|
|
121
124
|
'_HASH': '#',
|
|
122
125
|
'_HASHSPACE': '#',
|
|
@@ -131,6 +134,8 @@ terminalEnglishMap = {
|
|
|
131
134
|
'_RIGHTJOIN': '-+>',
|
|
132
135
|
'_RIGHTPIVOT': '->',
|
|
133
136
|
'_STOP': 'stop',
|
|
137
|
+
'_WALKNJOINN1': '--+>',
|
|
138
|
+
'_WALKNJOINN2': '<+--',
|
|
134
139
|
'_WALKNPIVON1': '-->',
|
|
135
140
|
'_WALKNPIVON2': '<--',
|
|
136
141
|
'$END': 'end of input',
|
|
@@ -640,6 +645,7 @@ ruleClassMap = {
|
|
|
640
645
|
'editparens': s_ast.EditParens,
|
|
641
646
|
'emit': s_ast.Emit,
|
|
642
647
|
'initblock': s_ast.InitBlock,
|
|
648
|
+
'emptyblock': s_ast.EmptyBlock,
|
|
643
649
|
'finiblock': s_ast.FiniBlock,
|
|
644
650
|
'formname': s_ast.FormName,
|
|
645
651
|
'editpropdel': lambda astinfo, kids: s_ast.EditPropDel(astinfo, kids[1:]),
|
|
@@ -690,8 +696,12 @@ ruleClassMap = {
|
|
|
690
696
|
'liftbyformtagprop': s_ast.LiftFormTagProp,
|
|
691
697
|
'looklist': s_ast.LookList,
|
|
692
698
|
'lookup': s_ast.Lookup,
|
|
699
|
+
'n1join': lambda astinfo, kids: s_ast.N1Walk(astinfo, kids, isjoin=True),
|
|
700
|
+
'n2join': lambda astinfo, kids: s_ast.N2Walk(astinfo, kids, isjoin=True),
|
|
693
701
|
'n1walk': s_ast.N1Walk,
|
|
694
702
|
'n2walk': s_ast.N2Walk,
|
|
703
|
+
'n1walknjoin': lambda astinfo, kids: s_ast.N1WalkNPivo(astinfo, kids, isjoin=True),
|
|
704
|
+
'n2walknjoin': lambda astinfo, kids: s_ast.N2WalkNPivo(astinfo, kids, isjoin=True),
|
|
695
705
|
'n1walknpivo': s_ast.N1WalkNPivo,
|
|
696
706
|
'n2walknpivo': s_ast.N2WalkNPivo,
|
|
697
707
|
'notcond': s_ast.NotCond,
|
synapse/lib/snap.py
CHANGED
|
@@ -301,11 +301,7 @@ class ProtoNode:
|
|
|
301
301
|
if self.node is not None:
|
|
302
302
|
return self.node.get(name)
|
|
303
303
|
|
|
304
|
-
async def
|
|
305
|
-
|
|
306
|
-
prop = self.form.props.get(name)
|
|
307
|
-
if prop is None:
|
|
308
|
-
return False
|
|
304
|
+
async def _set(self, prop, valu, norminfo=None):
|
|
309
305
|
|
|
310
306
|
if prop.locked:
|
|
311
307
|
mesg = f'Prop {prop.full} is locked due to deprecation.'
|
|
@@ -339,7 +335,7 @@ class ProtoNode:
|
|
|
339
335
|
await self.ctx.snap._raiseOnStrict(s_exc.IsDeprLocked, mesg)
|
|
340
336
|
return False
|
|
341
337
|
|
|
342
|
-
curv = self.get(name)
|
|
338
|
+
curv = self.get(prop.name)
|
|
343
339
|
if curv == valu:
|
|
344
340
|
return False
|
|
345
341
|
|
|
@@ -351,7 +347,20 @@ class ProtoNode:
|
|
|
351
347
|
if self.node is not None:
|
|
352
348
|
await self.ctx.snap.core._callPropSetHook(self.node, prop, valu)
|
|
353
349
|
|
|
354
|
-
self.props[name] = valu
|
|
350
|
+
self.props[prop.name] = valu
|
|
351
|
+
|
|
352
|
+
return valu, norminfo
|
|
353
|
+
|
|
354
|
+
async def set(self, name, valu, norminfo=None):
|
|
355
|
+
prop = self.form.props.get(name)
|
|
356
|
+
if prop is None:
|
|
357
|
+
return False
|
|
358
|
+
|
|
359
|
+
retn = await self._set(prop, valu, norminfo=norminfo)
|
|
360
|
+
if retn is False:
|
|
361
|
+
return False
|
|
362
|
+
|
|
363
|
+
(valu, norminfo) = retn
|
|
355
364
|
|
|
356
365
|
propform = self.ctx.snap.core.model.form(prop.type.name)
|
|
357
366
|
if propform is not None:
|
|
@@ -372,6 +381,37 @@ class ProtoNode:
|
|
|
372
381
|
|
|
373
382
|
return True
|
|
374
383
|
|
|
384
|
+
async def getSetOps(self, name, valu, norminfo=None):
|
|
385
|
+
prop = self.form.props.get(name)
|
|
386
|
+
if prop is None:
|
|
387
|
+
return ()
|
|
388
|
+
|
|
389
|
+
retn = await self._set(prop, valu, norminfo=norminfo)
|
|
390
|
+
if retn is False:
|
|
391
|
+
return ()
|
|
392
|
+
|
|
393
|
+
(valu, norminfo) = retn
|
|
394
|
+
ops = []
|
|
395
|
+
|
|
396
|
+
propform = self.ctx.snap.core.model.form(prop.type.name)
|
|
397
|
+
if propform is not None:
|
|
398
|
+
ops.append(self.ctx.getAddNodeOps(propform.name, valu, norminfo=norminfo))
|
|
399
|
+
|
|
400
|
+
# TODO can we mandate any subs are returned pre-normalized?
|
|
401
|
+
propsubs = norminfo.get('subs')
|
|
402
|
+
if propsubs is not None:
|
|
403
|
+
for subname, subvalu in propsubs.items():
|
|
404
|
+
full = f'{prop.name}:{subname}'
|
|
405
|
+
if self.form.props.get(full) is not None:
|
|
406
|
+
ops.append(self.getSetOps(full, subvalu))
|
|
407
|
+
|
|
408
|
+
propadds = norminfo.get('adds')
|
|
409
|
+
if propadds is not None:
|
|
410
|
+
for addname, addvalu, addinfo in propadds:
|
|
411
|
+
ops.append(self.ctx.getAddNodeOps(addname, addvalu, norminfo=addinfo))
|
|
412
|
+
|
|
413
|
+
return ops
|
|
414
|
+
|
|
375
415
|
class SnapEditor:
|
|
376
416
|
'''
|
|
377
417
|
A SnapEditor allows tracking node edits with subs/deps as a transaction.
|
|
@@ -394,17 +434,12 @@ class SnapEditor:
|
|
|
394
434
|
nodeedits.append(nodeedit)
|
|
395
435
|
return nodeedits
|
|
396
436
|
|
|
397
|
-
async def
|
|
437
|
+
async def _addNode(self, form, valu, props=None, norminfo=None):
|
|
398
438
|
|
|
399
439
|
self.snap.core._checkMaxNodes()
|
|
400
440
|
|
|
401
|
-
form = self.snap.core.model.form(formname)
|
|
402
|
-
if form is None:
|
|
403
|
-
mesg = f'No form named {formname} for valu={valu}.'
|
|
404
|
-
return await self.snap._raiseOnStrict(s_exc.NoSuchForm, mesg)
|
|
405
|
-
|
|
406
441
|
if form.isrunt:
|
|
407
|
-
mesg = f'Cannot make runt nodes: {
|
|
442
|
+
mesg = f'Cannot make runt nodes: {form.name}.'
|
|
408
443
|
return await self.snap._raiseOnStrict(s_exc.IsRuntForm, mesg)
|
|
409
444
|
|
|
410
445
|
if form.locked:
|
|
@@ -417,15 +452,73 @@ class SnapEditor:
|
|
|
417
452
|
except s_exc.BadTypeValu as e:
|
|
418
453
|
e.errinfo['form'] = form.name
|
|
419
454
|
if self.snap.strict: raise e
|
|
420
|
-
await self.snap.warn(f'addNode() BadTypeValu {
|
|
455
|
+
await self.snap.warn(f'addNode() BadTypeValu {form.name}={valu} {e}')
|
|
421
456
|
return None
|
|
422
457
|
|
|
458
|
+
return valu, norminfo
|
|
459
|
+
|
|
460
|
+
async def addNode(self, formname, valu, props=None, norminfo=None):
|
|
461
|
+
|
|
462
|
+
form = self.snap.core.model.form(formname)
|
|
463
|
+
if form is None:
|
|
464
|
+
mesg = f'No form named {formname} for valu={valu}.'
|
|
465
|
+
return await self.snap._raiseOnStrict(s_exc.NoSuchForm, mesg)
|
|
466
|
+
|
|
467
|
+
retn = await self._addNode(form, valu, props=props, norminfo=norminfo)
|
|
468
|
+
if retn is None:
|
|
469
|
+
return None
|
|
470
|
+
|
|
471
|
+
valu, norminfo = retn
|
|
472
|
+
|
|
423
473
|
protonode = await self._initProtoNode(form, valu, norminfo)
|
|
424
474
|
if props is not None:
|
|
425
475
|
[await protonode.set(p, v) for (p, v) in props.items()]
|
|
426
476
|
|
|
427
477
|
return protonode
|
|
428
478
|
|
|
479
|
+
async def getAddNodeOps(self, formname, valu, props=None, norminfo=None):
|
|
480
|
+
|
|
481
|
+
form = self.snap.core.model.form(formname)
|
|
482
|
+
if form is None:
|
|
483
|
+
mesg = f'No form named {formname} for valu={valu}.'
|
|
484
|
+
await self.snap._raiseOnStrict(s_exc.NoSuchForm, mesg)
|
|
485
|
+
return()
|
|
486
|
+
|
|
487
|
+
retn = await self._addNode(form, valu, props=props, norminfo=norminfo)
|
|
488
|
+
if retn is None:
|
|
489
|
+
return ()
|
|
490
|
+
|
|
491
|
+
norm, norminfo = retn
|
|
492
|
+
|
|
493
|
+
ndef = (form.name, norm)
|
|
494
|
+
|
|
495
|
+
protonode = self.protonodes.get(ndef)
|
|
496
|
+
if protonode is not None:
|
|
497
|
+
return ()
|
|
498
|
+
|
|
499
|
+
buid = s_common.buid(ndef)
|
|
500
|
+
node = await self.snap.getNodeByBuid(buid)
|
|
501
|
+
if node is not None:
|
|
502
|
+
return ()
|
|
503
|
+
|
|
504
|
+
protonode = ProtoNode(self, buid, form, norm, node)
|
|
505
|
+
|
|
506
|
+
self.protonodes[ndef] = protonode
|
|
507
|
+
|
|
508
|
+
ops = []
|
|
509
|
+
|
|
510
|
+
subs = norminfo.get('subs')
|
|
511
|
+
if subs is not None:
|
|
512
|
+
for prop, valu in subs.items():
|
|
513
|
+
ops.append(protonode.getSetOps(prop, valu))
|
|
514
|
+
|
|
515
|
+
adds = norminfo.get('adds')
|
|
516
|
+
if adds is not None:
|
|
517
|
+
for addname, addvalu, addinfo in adds:
|
|
518
|
+
ops.append(self.getAddNodeOps(addname, addvalu, norminfo=addinfo))
|
|
519
|
+
|
|
520
|
+
return ops
|
|
521
|
+
|
|
429
522
|
def loadNode(self, node):
|
|
430
523
|
protonode = self.protonodes.get(node.ndef)
|
|
431
524
|
if protonode is None:
|
|
@@ -448,14 +541,25 @@ class SnapEditor:
|
|
|
448
541
|
|
|
449
542
|
self.protonodes[ndef] = protonode
|
|
450
543
|
|
|
544
|
+
ops = collections.deque()
|
|
545
|
+
|
|
451
546
|
subs = norminfo.get('subs')
|
|
452
547
|
if subs is not None:
|
|
453
|
-
|
|
548
|
+
for prop, valu in subs.items():
|
|
549
|
+
ops.append(protonode.getSetOps(prop, valu))
|
|
550
|
+
|
|
551
|
+
while ops:
|
|
552
|
+
oset = ops.popleft()
|
|
553
|
+
ops.extend(await oset)
|
|
454
554
|
|
|
455
555
|
adds = norminfo.get('adds')
|
|
456
556
|
if adds is not None:
|
|
457
557
|
for addname, addvalu, addinfo in adds:
|
|
458
|
-
|
|
558
|
+
ops.append(self.getAddNodeOps(addname, addvalu, norminfo=addinfo))
|
|
559
|
+
|
|
560
|
+
while ops:
|
|
561
|
+
oset = ops.popleft()
|
|
562
|
+
ops.extend(await oset)
|
|
459
563
|
|
|
460
564
|
return protonode
|
|
461
565
|
|
|
@@ -469,8 +573,6 @@ class Snap(s_base.Base):
|
|
|
469
573
|
|
|
470
574
|
Transactions produce the following EventBus events:
|
|
471
575
|
|
|
472
|
-
(...any splice...)
|
|
473
|
-
('log', {'level': 'mesg': })
|
|
474
576
|
('print', {}),
|
|
475
577
|
'''
|
|
476
578
|
tagcachesize = 1000
|
|
@@ -598,7 +700,6 @@ class Snap(s_base.Base):
|
|
|
598
700
|
|
|
599
701
|
yield pode
|
|
600
702
|
|
|
601
|
-
@s_coro.genrhelp
|
|
602
703
|
async def storm(self, text, opts=None, user=None):
|
|
603
704
|
'''
|
|
604
705
|
Execute a storm query and yield (Node(), Path()) tuples.
|
|
@@ -616,7 +717,6 @@ class Snap(s_base.Base):
|
|
|
616
717
|
async for x in runt.execute():
|
|
617
718
|
yield x
|
|
618
719
|
|
|
619
|
-
@s_coro.genrhelp
|
|
620
720
|
async def eval(self, text, opts=None, user=None):
|
|
621
721
|
'''
|
|
622
722
|
Run a storm query and yield Node() objects.
|
synapse/lib/storm.lark
CHANGED
|
@@ -63,10 +63,10 @@ SETTAGOPER: "?"
|
|
|
63
63
|
|
|
64
64
|
// The set of non-edit non-commands in storm
|
|
65
65
|
|
|
66
|
-
_oper: stormfunc | initblock | finiblock | trycatch | subquery | _formpivot | formjoin
|
|
67
|
-
| formjoinin | opervarlist | setitem | setvar | vareval | filtoper
|
|
66
|
+
_oper: stormfunc | initblock | emptyblock | finiblock | trycatch | subquery | _formpivot | formjoin
|
|
67
|
+
| formpivotin | formjoinin | opervarlist | setitem | setvar | vareval | filtoper
|
|
68
68
|
| operrelprop | forloop | whileloop | switchcase | BREAK | CONTINUE | return | emit | stop
|
|
69
|
-
| _liftprop | ifstmt | yieldvalu | n1walk | n2walk | n1walknpivo | n2walknpivo | rawpivot
|
|
69
|
+
| _liftprop | ifstmt | yieldvalu | n1walk | n2walk | n1join | n2join | n1walknpivo | n2walknpivo | n1walknjoin | n2walknjoin | rawpivot
|
|
70
70
|
|
|
71
71
|
BREAK.4: /break(?=[\s\}])/
|
|
72
72
|
CONTINUE.4: /continue(?=[\s\}])/
|
|
@@ -106,6 +106,9 @@ yieldvalu: YIELD _argvalu
|
|
|
106
106
|
_INIT.2: /init(?=[\s\{])/
|
|
107
107
|
initblock: _INIT "{" query "}"
|
|
108
108
|
|
|
109
|
+
_EMPTY.2: /empty(?=[\s\{])/
|
|
110
|
+
emptyblock: _EMPTY "{" query "}"
|
|
111
|
+
|
|
109
112
|
_FINI.2: /fini(?=[\s\{])/
|
|
110
113
|
finiblock: _FINI "{" query "}"
|
|
111
114
|
|
|
@@ -148,7 +151,7 @@ rawpivot: _RIGHTPIVOT "{" query "}"
|
|
|
148
151
|
_RIGHTJOIN.4: "-+>"
|
|
149
152
|
_LEFTJOIN.4: "<+-"
|
|
150
153
|
_RIGHTPIVOT.4: "->"
|
|
151
|
-
_LEFTPIVOT.4:
|
|
154
|
+
_LEFTPIVOT.4: /<\-[^0-9]/
|
|
152
155
|
|
|
153
156
|
_liftprop: liftformtag | liftpropby | liftprop | liftbyarray
|
|
154
157
|
| liftbytagprop | liftbyformtagprop | liftbytag | lifttagtag
|
|
@@ -163,20 +166,33 @@ n1walk: _EDGEN1INIT (walklist | varlist | _varvalu | relpropvalu | univpropvalu
|
|
|
163
166
|
|
|
164
167
|
n2walk: _EDGEN2INIT _valu _EDGEN2FINI _wildprops [ _cmpr _valu ]
|
|
165
168
|
|
|
169
|
+
n1join: _EDGEN1INIT (walklist | varlist | _varvalu | relpropvalu | univpropvalu | tagvalu | tagpropvalu | TRIPLEQUOTEDSTRING | formatstring | VARTOKN | embedquery | baresubquery | NONQUOTEWORD | ABSPROPNOUNIV) _EDGEN1JOINFINI _wildprops [ _cmpr _valu ]
|
|
170
|
+
|
|
171
|
+
n2join: _EDGEN2JOININIT _valu _EDGEN2FINI _wildprops [ _cmpr _valu ]
|
|
172
|
+
|
|
166
173
|
walklist: ("(" (_varvalu | relpropvalu | univpropvalu | tagvalu | tagpropvalu | TRIPLEQUOTEDSTRING | formatstring | VARTOKN | NONQUOTEWORD | ABSPROP) ((",")|("," (_varvalu | relpropvalu | univpropvalu | tagvalu | tagpropvalu | TRIPLEQUOTEDSTRING | formatstring | VARTOKN | NONQUOTEWORD | ABSPROP))+ ","?) ")") -> valulist
|
|
167
174
|
|
|
175
|
+
_WALKNJOINN1.4: "--+>"
|
|
176
|
+
_WALKNJOINN2.4: "<+--"
|
|
177
|
+
|
|
168
178
|
_WALKNPIVON1.4: "-->"
|
|
169
179
|
_WALKNPIVON2.4: "<--"
|
|
170
180
|
|
|
171
181
|
n1walknpivo: _WALKNPIVON1 "*"
|
|
172
182
|
n2walknpivo: _WALKNPIVON2 "*"
|
|
173
183
|
|
|
184
|
+
n1walknjoin: _WALKNJOINN1 "*"
|
|
185
|
+
n2walknjoin: _WALKNJOINN2 "*"
|
|
186
|
+
|
|
174
187
|
_EDGEADDN1INIT.2: "+("
|
|
175
188
|
_EDGEN1INIT.2: "-("
|
|
176
189
|
_EDGEN1FINI: ")>"
|
|
177
190
|
_EDGEADDN2FINI: ")+"
|
|
178
191
|
_EDGEN2FINI: ")-"
|
|
179
192
|
|
|
193
|
+
_EDGEN1JOINFINI: ")+>"
|
|
194
|
+
_EDGEN2JOININIT: "<+("
|
|
195
|
+
|
|
180
196
|
// Regex to check for a matching ')-' or ')+' so we can avoid incorrectly matching
|
|
181
197
|
// comparisons to an expression like '<(2)'
|
|
182
198
|
_EDGEN2INIT: /\<\((?=(?>(?<EDGEN2INITRECUR>\(((?>[^()"'`]+|(?&EDGEN2INITRECUR)|`(?:[^`\\]|\\.)*`|"(?:[^"\\]|\\.)*"|'''.*?'''|'[^']*'(?!'))*)\))|'''.*?'''|`(?:[^`\\]|\\.)*`|"(?:[^"\\]|\\.)*"|'[^']*'(?!')|[^)])*\)[\-\+])/
|
|
@@ -214,7 +230,7 @@ stormcmdargs: _stormcmdarg
|
|
|
214
230
|
_stormcmdarg: _stormcmdarg? ((CMDOPT (EQNOSPACE (argvquery | _argvalu | wordtokn))?) | argvquery | _argvalu | wordtokn)
|
|
215
231
|
|
|
216
232
|
// The name of a storm command
|
|
217
|
-
CMDNAME.2: /(?!(init|fini|function|return|emit|stop|yield|break|continue|for|while|switch|else|elif|if|not|or|and|try|catch|as|reverse)\b)[a-z][a-z0-9.]+(?=[\s\|\}]|$)/
|
|
233
|
+
CMDNAME.2: /(?!(init|empty|fini|function|return|emit|stop|yield|break|continue|for|while|switch|else|elif|if|not|or|and|try|catch|as|reverse)\b)[a-z][a-z0-9.]+(?=[\s\|\}]|$)/
|
|
218
234
|
|
|
219
235
|
CMDOPT.4: /(?<=\s)-[a-zA-Z0-9_-]+(?![:a-zA-Z0-9_><-])/
|
|
220
236
|
|
|
@@ -258,8 +274,9 @@ _MATCHHASHWILD.3: /\#
|
|
|
258
274
|
<\(
|
|
259
275
|
(?=(?>(?<N2MATCHRECUR>\(((?>[^()"'`]+|(?&N2MATCHRECUR)|`(?:[^`\\]|\\.)*`|"(?:[^"\\]|\\.)*"|'''.*?'''|'[^']*'(?!'))*)\))|'''.*?'''|`(?:[^`\\]|\\.)*`|"(?:[^"\\]|\\.)*"|'[^']*'(?!')|[^)])*\)-
|
|
260
276
|
)
|
|
277
|
+
| <(\+|-[^0-9]) # avoid matching joins or pivots
|
|
261
278
|
)
|
|
262
|
-
[@?!<>^~=]+
|
|
279
|
+
[@?!<>^~=]+ # match any cmprs (regex fail)
|
|
263
280
|
)
|
|
264
281
|
)
|
|
265
282
|
/x
|