Skip to content

Commit

Permalink
Add ability to output JSON formatted info for components
Browse files Browse the repository at this point in the history
closes #47
  • Loading branch information
rjfarmer committed Jan 24, 2024
1 parent 0e8f86a commit 044be19
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 25 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,15 @@ pprint(module['a_variable'])

Accessing the list of all available components can be had via ``module.keys()``.

You can also do:
````python
module = gf.mod_info('file.mod',json=True)
module['a_variable']
````

Then when you access each component the return value will be JSON-formatted. Note you can currently only access each component as JSON not the whole module file as JSON at the moment.


## Contributing

Bug reports are of course welcome and PR's should target the main branch.
Expand Down
5 changes: 3 additions & 2 deletions gfort2py/gfort2py.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,14 @@ def __str__(self):
return f"{self._module.filename}"


def mod_info(mod_file, load_only=False):
def mod_info(mod_file, *,load_only=False, json=False):
"""
Returns a parsed data structure that describes the module
pprint is recommened to help understand the nested structure.
"""
return module(mod_file, load_only=load_only)
return module(mod_file, load_only=load_only, json=json)



def lib_ext():
Expand Down
53 changes: 30 additions & 23 deletions gfort2py/module_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# https://github.com/gcc-mirror/gcc/blob/master/gcc/fortran/module.cc
from cPyparsing import OneOrMore, nestedExpr
from dataclasses import dataclass
from dataclasses_json import dataclass_json
import numpy as np
import gzip
import sys
Expand Down Expand Up @@ -45,7 +46,7 @@ class NotAnArrayError(Exception):

#################################


@dataclass_json
@dataclass
class s_item:
name: str
Expand Down Expand Up @@ -93,7 +94,7 @@ def names(self):

#################################


@dataclass_json
@dataclass
class symbol_ref:
ref: int = -1
Expand All @@ -104,7 +105,7 @@ def __post_init__(self):

#################################


@dataclass_json
@dataclass(init=False)
class c_item:
name: str = ""
Expand All @@ -129,7 +130,7 @@ def __init__(self, *args):

#################################


@dataclass_json
@dataclass(init=False)
class generics:
name: str = ""
Expand Down Expand Up @@ -381,7 +382,7 @@ def dt_type(self):
def dt_components(self):
return self.sym.comp


@dataclass_json
@dataclass(init=False)
class attribute:
flavor: str = ""
Expand All @@ -404,15 +405,15 @@ def __init__(self, *args):
self.attributes = set([string_clean(i) for i in args[7:]])
self.raw = args


@dataclass_json
@dataclass
class namespace:
ref: int = -1

def __post_init__(self):
self.ref = symbol_ref(self.ref)


@dataclass_json
@dataclass
class header:
id: int
Expand All @@ -435,7 +436,7 @@ def mn_name(self):

return f"__{self.module}_MOD_{self.name}"


@dataclass_json
@dataclass(init=False)
class formal_arglist:
symbol: t.List[symbol_ref] = None
Expand All @@ -453,7 +454,7 @@ def __len__(self):
def __iter__(self):
return iter(self.symbol)


@dataclass_json
@dataclass(init=False)
class typebound_proc:
name: str = ""
Expand Down Expand Up @@ -482,7 +483,7 @@ def __init__(self, *args, **kwargs):
self.raw = args
self.kwargs = kwargs


@dataclass_json
@dataclass(init=False)
class derived_ns:
unknown1: str = None
Expand All @@ -499,14 +500,14 @@ def __init__(self, *args, **kwargs):
for i in args[1]:
self.proc.append(typebound_proc(i))


@dataclass_json
@dataclass(init=False)
class actual_arglist:
def __init__(self, *args, **kwargs):
self.raw = args
self.kwargs = kwargs


@dataclass_json
@dataclass(init=False)
class typespec:
type: str = ""
Expand Down Expand Up @@ -548,7 +549,7 @@ def __init__(self, *args):
except (TypeError, IndexError):
self.deferred_cl = False


@dataclass_json
@dataclass(init=False)
class expression:
exp_type: str = ""
Expand Down Expand Up @@ -635,7 +636,7 @@ def value(self):
def value(self, value):
self._resolved_value = value


@dataclass_json
@dataclass(init=False)
class arrayspec:
rank: int = -1
Expand Down Expand Up @@ -683,7 +684,7 @@ def pyshape(self):
def size(self):
return np.prod(self.pyshape)


@dataclass_json
@dataclass(init=False)
class component(utils):
id: int = -1
Expand Down Expand Up @@ -723,7 +724,7 @@ def __init__(self, *args):
# inside the parent utils class
self.sym = self


@dataclass_json
@dataclass(init=False)
class components:
comp: t.List[component] = None
Expand All @@ -741,7 +742,7 @@ def __len__(self):
def __iter__(self):
return iter(self.comp)


@dataclass_json
@dataclass(init=False)
class namelist:
sym_ref: t.List[symbol_ref] = None
Expand All @@ -753,7 +754,7 @@ def __init__(self, *args):
for i in args:
self.sym_ref.append(symbol_ref(i))


@dataclass_json
@dataclass(init=False)
class simd_dec:
args: None
Expand All @@ -763,7 +764,7 @@ def __init__(self, *args, **kwargs):
self.raw = args
self.kwargs = kwargs


@dataclass_json
@dataclass(init=False)
class data:
attr: attribute
Expand Down Expand Up @@ -821,7 +822,7 @@ def __init__(self, *args):
if args[15] is not None:
self.simd = simd_dec(*args[14])


@dataclass_json
@dataclass(init=False)
class symbol(utils):
head: header = None
Expand All @@ -845,8 +846,10 @@ def mangled_name(self):
class module(object):
version = 15

def __init__(self, filename, load_only=False, cache_folder=None):
def __init__(self, filename, load_only=False,
cache_folder=None, json=False):
self.filename = filename
self._json=json

with gzip.open(self.filename) as f:
x = f.read().decode()
Expand Down Expand Up @@ -927,11 +930,15 @@ def __contains__(self, key):

def __getitem__(self, key):
try:
return self.symbols[self.summary[key].id]
x = self.symbols[self.summary[key].id]
except KeyError:
# Not a global variable maybe a function argument?
return self.symbols[key]
x = self.symbols[key]

if self._json:
return x.to_json()
else:
return x

if __name__ == "__main__":
m = module(filename=sys.argv[1])
Expand Down

0 comments on commit 044be19

Please sign in to comment.