Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
T
taste-model-checker
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
TASTE
taste-model-checker
Commits
0441d625
Commit
0441d625
authored
Dec 01, 2019
by
Maxime Perrotin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Work on the new iterator generator in python
parent
aacae1a9
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
416 additions
and
5 deletions
+416
-5
asn1-iterators/src/taste-asn1-iterators.py
asn1-iterators/src/taste-asn1-iterators.py
+416
-5
No files found.
asn1-iterators/src/taste-asn1-iterators.py
View file @
0441d625
...
...
@@ -13,10 +13,338 @@
"""
__version__
=
"3.0.0"
import
signal
import
argparse
import
traceback
import
logging
from
typing
import
List
LOG
=
logging
.
getLogger
(
__name__
)
import
opengeode.Asn1scc
as
asn1scc
import
opengeode.ogParser
as
parser
LF
=
'
\n
'
def
indent
(
nb
:
int
,
phrase
:
List
[
str
],
sep
=
""
):
# offer indenting of multiple line strings when referenced inside f-strings
result
=
LF
.
join
(
phrase
)
return
(
sep
+
LF
+
nb
*
" "
).
join
(
result
.
splitlines
())
def
adb_template
(
packages
:
List
[
str
])
->
str
:
''' Top-level template to generate the .adb file '''
return
f'''-- This file was generated by TASTE: DO NOT EDIT
with Ada.Strings,
Ada.Strings.Fixed,
Ada.Srings.Unbounded,
Ada.Characters.Handling;
use Ada.Strings,
Ada.Strings.Fixed,
Ada.Strings.Unbounded,
Ada.Characters.Handling;
package body ASN1_Ada_Iterators.Iterators is
{
indent
(
3
,
packages
)
}
end ASN1_Ada_Iterators.Iterators;
'''
def
unsigned_int_adb_template
(
sort
:
str
,
minR
:
int
,
maxR
:
int
)
->
str
:
''' Template for iterating on an unsigned integer '''
return
f'''package body
{
sort
}
_Pkg is
procedure To_ASN1 (From : Interfaces.Unsigned_64;
To : out asn1Scc
{
sort
}
) is
begin
To := From;
end To_ASN1;
function Image (Elm : asn1Scc
{
sort
}
) return String is
(Ada.Strings.Fixed.Trim (Elm'Img, Both));
end
{
sort
}
_Pkg;'''
def
signed_int_adb_template
(
sort
:
str
,
minR
:
int
,
maxR
:
int
)
->
str
:
''' Template for iterating on a signed integer '''
return
f'''package body
{
sort
}
_Pkg is
procedure To_ASN1 (From : Interfaces.Integer_64;
To : out asn1Scc
{
sort
}
) is
begin
To := From;
end To_ASN1;
function Image (Elm : asn1Scc
{
sort
}
) return String is
(Ada.Strings.Fixed.Trim (Elm'Img, Both));
end
{
sort
}
_Pkg;'''
def
seq_of_adb_template
(
sort
:
str
,
inner
:
str
,
minR
:
int
,
maxR
:
int
)
->
str
:
''' Template for iterating on an array '''
if
minR
==
maxR
:
return
f'''package body
{
sort
}
_Pkg is
procedure To_ASN1 (From : Inner.
{
sort
}
;
To : out asn1Scc
{
sort
}
) is
begin
for Idx in 1 .. From.Length loop
To.Data (Idx) := From.Data (Idx);
end loop;
end To_ASN1;
function Image (Elm : asn1Scc
{
sort
}
) return String is
Res : Unbounded_String;
begin
if Elm.Data'Length >= 1 then
Res := To_Unbounded_String (Image (Elm.Data (1)));
end if;
if Elm.Data'Length > 1 then
for Idx in 2 .. Elm.Data'Length loop
Res := Res & ", " & Image (Elm.Data (Idx));
end loop;
end if;
return To_String ("
{
" & Res & "
}
");
end Image;
end
{
sort
}
_Pkg;'''
else
:
# Variable-size sequence of
return
f'''package body
{
sort
}
_Pkg is
procedure To_ASN1 (From : Inner.
{
sort
}
;
To : out asn1Scc
{
sort
}
) is
begin
for Idx in 1 .. From.Length loop
To.Data (Idx) := From.Data (Idx);
end loop;
To.Length := From.Length;
end To_ASN1;
function Image (Elm : asn1Scc
{
sort
}
) return String is
function Image_Rec (Elm : ASN1_Type) return String is
(if Elm.Length > 0 then
(Image (Elm.Data (1))
& (if Elm.Length > 1 then ", "
& Image_Rec (ASN1_Type'(Length => Elm.Length-1,
Data => Elm.Data(2 .. Elm.Length) &
Elm.Data(1 .. Elm.Data'Length - Elm.Length + 1)))
else ""))
else "");
begin
return "
{
" & Image_Rec (Elm) & "
}
";
end Image;
end
{
sort
}
_Pkg;'''
def
enum_adb_template
(
sort
:
str
)
->
str
:
''' Template for iterating on an enumerated '''
return
f'''package body
{
sort
}
_Pkg is
function Image (Elm : asn1Scc
{
sort
}
) return String is
(Delete (To_Lower (Elm'Img), From => 1, Through => 7)); -- remove "asn1scc" prefix
end Image;
end
{
sort
}
_Pkg;'''
def
fields_adb_init
(
fields
:
dict
)
->
List
[
str
]:
'''
Template for the fields of a sequence used in the Initialize function
'''
result
=
[]
for
name
in
fields
.
keys
():
result
.
append
(
f"Container.
{
name
}
_it := P_
{
name
}
.Iterator (Container.
{
name
}
_val.Iterate);"
)
return
result
def
sequence_adb_template
(
sort
:
str
,
fields
:
dict
)
->
str
:
''' Template for iterating on a record '''
return
f'''package body
{
sort
}
_Pkg is
procedure Initialize (Container : in out
{
sort
}
) is
begin
{
indent
(
6
,
fields_adb_init
(
fields
))
}
end Initialize;
function Has_Element (Position : Cursor) return Boolean is
(P_
{
fields_first
(
fields
)
}
(Position.
{
fields_first
(
fields
)
}
_it.Get_Cursor));
function Iterate (Container :
{
sort
}
) return
{
sort
}
_It'Class is
begin
return I:
{
sort
}
_It do
I.Position := Self'Unrestricted_Access;
end return;
end Iterate;
function First (Item :
{
sort
}
_It) return Cursor is
{
indent
(
6
,
fields_adb_first
(
fields
))
}
begin
return Item.Position;
end First;
function Next (Item :
{
sort
}
_It;
Position : Cursor) return Cursor is
pragma Unreferenced (Item);
{
indent
(
6
,
fields_adb_next
(
fields
))
}
begin
-- Iterate on the last field then on the previous ones
{
indent
(
6
,
fields_adb_iterate
(
fields
))
}
return Position;
end Next;
function Image (Elm : asn1Scc
{
sort
}
) return String is
begin
return "
{
"
{
fields_adb_image
(
13
,
fields
)
}
&
"
}
";
end Image;
end
{
sort
}
_Pkg;'''
def
ads_template
(
packages
:
List
[
str
])
->
str
:
''' Top-level template to generate the .ads file '''
return
f'''-- This file was generated by TASTE: DO NOT EDIT
with Ada.Iterator_Interfaces,
Ada.Finalization,
Interfaces,
ASN1_Ada_Iterators,
ASN1_Iterators.Generic_Integer,
ASN1_Iterators.Generic_Unsigned_Integer,
ASN1_Iterators.Generic_Enumerated,
ASN1_Iterators.Generic_SeqOf;
pragma Unreferenced (ASN1_Ada_Iterators);
use Ada.Finalization,
Interfaces,
ASN1_Iterators;
package ASN1_Ada_Iterators.Iterators is
{
indent
(
3
,
packages
)
}
end ASN1_Ada_Iterators.Iterators;
'''
def
unsigned_int_ads_template
(
sort
:
str
,
minR
:
int
,
maxR
:
int
)
->
str
:
''' Template for iterating on an unsigned integer '''
return
f'''package
{
sort
}
_Pkg is
package Inner is new Generic_Unsigned_Integer (Min =>
{
minR
}
,
Max =>
{
maxR
}
);
package It renames Inner.It;
procedure To_ASN1 (From : Interfaces.Unsigned_64;
To : out asn1Scc
{
sort
}
);
subtype Instance is Inner.Instance;
function Image (Elm : asn1Scc
{
sort
}
) return String;
end
{
sort
}
_Pkg;'''
def
signed_int_ads_template
(
sort
:
str
,
minR
:
int
,
maxR
:
int
)
->
str
:
''' Template for iterating on an signed integer '''
return
f'''package
{
sort
}
_Pkg is
package Inner is new Generic_Integer (Min =>
{
minR
}
,
Max =>
{
maxR
}
);
package It renames Inner.It;
procedure To_ASN1 (From : Interfaces.Integer_64;
To : out asn1Scc
{
sort
}
);
subtype Instance is Inner.Instance;
function Image (Elm : asn1Scc
{
sort
}
) return String;
end
{
sort
}
_Pkg;'''
def
seq_of_ads_template
(
sort
:
str
,
inner
:
str
,
minR
:
int
,
maxR
:
int
)
->
str
:
''' Template for iterating on an array '''
return
f'''package
{
sort
}
_Pkg is
package Inner is new Generic_SeqOf (Min =>
{
minR
}
,
Max =>
{
maxR
}
,
Basic =>
{
inner
}
_Pkg.It);
use
{
inner
}
_Pkg;
procedure To_ASN1 (From : Inner.
{
sort
}
;
To : out asn1Scc
{
sort
}
);
subtype Instance is Inner.Instance;
function Image (Elm : asn1Scc
{
sort
}
) return String;
end
{
sort
}
_Pkg;'''
def
enum_ads_template
(
sort
:
str
)
->
str
:
''' Template for iterating on an enumerated '''
return
f'''package
{
sort
}
_Pkg is
package Inner is new Generic_Enumerated (Sort => asn1Scc
{
sort
}
);
package It renames Inner.It;
subtype Instance is Inner.Instance;
function Image (Elm : asn1Scc
{
sort
}
) return String;
end
{
sort
}
_Pkg;'''
def
fields_ads_pkg
(
fields
:
dict
)
->
List
[
str
]:
''' for each field of a sequence, do a package renaming :
package P_<field> renames <Sort>_Pkg.It
This makes further code more readable '''
result
=
[]
for
name
,
sort
in
fields
.
items
():
result
.
append
(
f"package P_
{
name
}
renames
{
sort
}
_Pkg.It;"
)
return
result
def
fields_ads_record
(
fields
:
dict
)
->
List
[
str
]:
''' Declare the fields for iteration in an ASN.1 SEQUENCE type '''
result
=
[]
for
field
in
fields
.
keys
():
result
.
append
(
f"
{
field
}
_val : P_
{
field
}
.Basic_ASN1_Iterator;"
)
result
.
append
(
f"
{
field
}
_it : P_
{
field
}
.Iterator;"
)
return
result
def
fields_ads_value
(
fields
:
dict
)
->
List
[
str
]:
''' Code that return the value of an ASN.1 SEQUENCE type '''
result
=
[]
for
field
in
fields
.
keys
():
result
.
append
(
f"
{
field
}
=> Container.
{
field
}
_val.Elem_Value (Container.
{
field
}
_it.Position)"
)
return
result
def
sequence_ads_template
(
sort
:
str
,
fields
:
dict
)
->
str
:
''' Template for iterating on a record '''
return
f'''package
{
sort
}
_Pkg is
{
indent
(
3
,
fields_ads_pkg
(
fields
))
}
type
{
sort
}
_It;
type
{
sort
}
is new Controlled with record
{
indent
(
6
,
fields_ads_record
(
fields
))
}
end record
with Default_Iterator => Iterate,
Iterator_Element => asn1Scc
{
sort
}
,
Constant_Indexing => Element;
type Cursor is access all
{
sort
}
;
-- Constructor (called automatically)
procedure Initialize (Container : in out
{
sort
}
);
function Has_Element (Position : Cursor) return Boolean;
package Iterators_
{
sort
}
is
new Ada.Iterator_Interfaces (Cursor, Has_Element);
type
{
sort
}
_It is new Iterators_
{
sort
}
.Forward_Iterator with record
Position : Cursor;
end record;
overriding function First (Item :
{
sort
}
_It) return Cursor;
overriding function Next (Item :
{
sort
}
_It;
Position : Cursor) return Cursor;
function Iterate (Container :
{
sort
}
) return
{
sort
}
_It'Class;
function Element (Container :
{
sort
}
;
Position : Cursor) return asn1Scc
{
sort
}
is
(
{
indent
(
7
,
fields_ads_value
(
fields
),
sep
=
","
)
}
);
subtype Instance is
{
sort
}
;
function Image (Elm : asn1Scc
{
sort
}
) return String;
end
{
sort
}
_Pkg;'''
from
opengeode
import
Asn1scc
def
init_logging
(
options
):
''' Initialize logging '''
...
...
@@ -43,23 +371,106 @@ def parse_args():
help
=
'Display debug information'
)
parser
.
add_argument
(
'files'
,
metavar
=
'
dataview-uniq
.asn'
,
metavar
=
'
file
.asn'
,
type
=
str
,
nargs
=
'*'
,
help
=
'ASN.1 file(s)'
)
return
parser
.
parse_args
()
def
run
(
options
):
asn1_files
=
options
.
files
if
not
asn1_files
:
LOG
.
error
(
"You must specify at least one ASN.1 file"
)
return
try
:
ast
=
asn1scc
.
parse_asn1
(
asn1_files
,
ast_version
=
asn1scc
.
ASN1
.
UniqueEnumeratedNames
,
rename_policy
=
asn1scc
.
ASN1
.
NoRename
,
flags
=
[
asn1scc
.
ASN1
.
AstOnly
],
pretty_print
=
False
)
except
(
ImportError
,
NameError
,
TypeError
)
as
err
:
LOG
.
error
(
str
(
err
))
LOG
.
error
(
"ASN.1 Parsing error (run with -g for debug infomation)"
)
LOG
.
debug
(
traceback
.
format_exc
())
return
modules
=
[]
packages_ads
,
packages_adb
=
[],
[]
# Parse the ASN.1 AST to know the types and generate the corresponding code
sorts
=
{}
for
module
,
types
in
ast
.
exportedTypes
.
items
():
modules
.
append
(
module
)
for
sort
in
types
:
sort_def
=
ast
.
types
[
sort
]
basic
=
parser
.
find_basic_type
(
sort_def
.
type
)
sorts
[
sort
.
replace
(
"-"
,
"_"
)]
=
basic
for
name
,
basic
in
sorts
.
items
():
if
basic
.
kind
==
"IntegerType"
and
int
(
basic
.
Min
)
>=
0
:
packages_ads
.
append
(
unsigned_int_ads_template
(
name
,
int
(
basic
.
Min
),
int
(
basic
.
Max
)))
packages_adb
.
append
(
unsigned_int_adb_template
(
name
,
int
(
basic
.
Min
),
int
(
basic
.
Max
)))
elif
basic
.
kind
==
"IntegerType"
and
int
(
basic
.
Min
<
0
):
packages_ads
.
append
(
signed_int_ads_template
(
name
,
int
(
basic
.
Min
),
int
(
basic
.
Max
)))
packages_adb
.
append
(
signed_int_adb_template
(
name
,
int
(
basic
.
Min
),
int
(
basic
.
Max
)))
elif
basic
.
kind
==
"EnumeratedType"
:
packages_ads
.
append
(
enum_ads_template
(
name
))
packages_adb
.
append
(
enum_adb_template
(
name
))
elif
basic
.
kind
==
"SequenceOfType"
:
inner
=
basic
.
type
.
ReferencedTypeName
.
replace
(
"-"
,
"_"
)
packages_ads
.
append
(
seq_of_ads_template
(
name
,
inner
,
int
(
basic
.
Min
),
int
(
basic
.
Max
)))
packages_adb
.
append
(
seq_of_adb_template
(
name
,
inner
,
int
(
basic
.
Min
),
int
(
basic
.
Max
)))
elif
basic
.
kind
==
"SequenceType"
:
fields
=
{}
for
child
in
basic
.
Children
.
values
():
fields
[
child
.
AdaName
]
=
\
child
.
type
.
ReferencedTypeName
.
replace
(
"-"
,
"_"
)
packages_ads
.
append
(
sequence_ads_template
(
name
,
fields
))
packages_adb
.
append
(
sequence_adb_template
(
name
,
fields
))
else
:
LOG
.
error
(
"Unsupported type name: "
+
basic
.
kind
)
return
ads
=
ads_template
(
packages_ads
)
adb
=
adb_template
(
packages_adb
)
# Write the .ads
with
open
(
"asn1_ada_iterators-iterators.ads"
,
"wb"
)
as
source
:
source
.
write
(
ads
.
encode
(
'latin1'
))
with
open
(
"asn1_ada_iterators-iterators.adb"
,
"wb"
)
as
source
:
source
.
write
(
adb
.
encode
(
'latin1'
))
def
main
():
''' Tool entry point '''
# Catch Ctrl-C to stop the app from the console
signal
.
signal
(
signal
.
SIGINT
,
signal
.
SIG_DFL
)
options
=
parse_args
()
init_logging
(
options
)
asn1scc
.
LOG
=
LOG
LOG
.
info
(
'Ada Iterators for ASN.1 - version '
+
__version__
)
run
(
options
)
if
__name__
==
'__main__'
:
''' Run main application '''
main
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment