mavtemplate.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 '''
3 simple templating system for mavlink generator
4 
5 Copyright Andrew Tridgell 2011
6 Released under GNU GPL version 3 or later
7 '''
8 
9 from builtins import object
10 
11 from .mavparse import MAVParseError
12 
13 class MAVTemplate(object):
14  '''simple templating system'''
15  def __init__(self,
16  start_var_token="${",
17  end_var_token="}",
18  start_rep_token="${{",
19  end_rep_token="}}",
20  trim_leading_lf=True,
21  checkmissing=True):
22  self.start_var_token = start_var_token
23  self.end_var_token = end_var_token
24  self.start_rep_token = start_rep_token
25  self.end_rep_token = end_rep_token
26  self.trim_leading_lf = trim_leading_lf
27  self.checkmissing = checkmissing
28 
29  def find_end(self, text, start_token, end_token, ignore_end_token=None):
30  '''find the of a token.
31  Returns the offset in the string immediately after the matching end_token'''
32  if not text.startswith(start_token):
33  raise MAVParseError("invalid token start")
34  offset = len(start_token)
35  nesting = 1
36  while nesting > 0:
37  idx1 = text[offset:].find(start_token)
38  idx2 = text[offset:].find(end_token)
39  # Check for false positives due to another similar token
40  # For example, make sure idx2 points to the second '}' in ${{field: ${name}}}
41  if ignore_end_token:
42  combined_token = ignore_end_token + end_token
43  if text[offset+idx2:offset+idx2+len(combined_token)] == combined_token:
44  idx2 += len(ignore_end_token)
45  if idx1 == -1 and idx2 == -1:
46  raise MAVParseError("token nesting error")
47  if idx1 == -1 or idx1 > idx2:
48  offset += idx2 + len(end_token)
49  nesting -= 1
50  else:
51  offset += idx1 + len(start_token)
52  nesting += 1
53  return offset
54 
55  def find_var_end(self, text):
56  '''find the of a variable'''
57  return self.find_end(text, self.start_var_token, self.end_var_token)
58 
59  def find_rep_end(self, text):
60  '''find the of a repitition'''
61  return self.find_end(text, self.start_rep_token, self.end_rep_token, ignore_end_token=self.end_var_token)
62 
63  def substitute(self, text, subvars={},
64  trim_leading_lf=None, checkmissing=None):
65  '''substitute variables in a string'''
66 
67  if trim_leading_lf is None:
68  trim_leading_lf = self.trim_leading_lf
69  if checkmissing is None:
70  checkmissing = self.checkmissing
71 
72  # handle repititions
73  while True:
74  subidx = text.find(self.start_rep_token)
75  if subidx == -1:
76  break
77  endidx = self.find_rep_end(text[subidx:])
78  if endidx == -1:
79  raise MAVParseError("missing end macro in %s" % text[subidx:])
80  part1 = text[0:subidx]
81  part2 = text[subidx+len(self.start_rep_token):subidx+(endidx-len(self.end_rep_token))]
82  part3 = text[subidx+endidx:]
83  a = part2.split(':')
84  field_name = a[0]
85  rest = ':'.join(a[1:])
86  v = None
87  if isinstance(subvars, dict):
88  v = subvars.get(field_name, None)
89  else:
90  v = getattr(subvars, field_name, None)
91  if v is None:
92  raise MAVParseError('unable to find field %s' % field_name)
93  t1 = part1
94  for f in v:
95  t1 += self.substitute(rest, f, trim_leading_lf=False, checkmissing=False)
96  if len(v) != 0 and t1[-1] in ["\n", ","]:
97  t1 = t1[:-1]
98  t1 += part3
99  text = t1
100 
101  if trim_leading_lf:
102  if text[0] == '\n':
103  text = text[1:]
104  while True:
105  idx = text.find(self.start_var_token)
106  if idx == -1:
107  return text
108  endidx = text[idx:].find(self.end_var_token)
109  if endidx == -1:
110  raise MAVParseError('missing end of variable: %s' % text[idx:idx+10])
111  varname = text[idx+2:idx+endidx]
112  if isinstance(subvars, dict):
113  if not varname in subvars:
114  if checkmissing:
115  raise MAVParseError("unknown variable in '%s%s%s'" % (
116  self.start_var_token, varname, self.end_var_token))
117  return text[0:idx+endidx] + self.substitute(text[idx+endidx:], subvars,
118  trim_leading_lf=False, checkmissing=False)
119  value = subvars[varname]
120  else:
121  value = getattr(subvars, varname, None)
122  if value is None:
123  if checkmissing:
124  raise MAVParseError("unknown variable in '%s%s%s'" % (
125  self.start_var_token, varname, self.end_var_token))
126  return text[0:idx+endidx] + self.substitute(text[idx+endidx:], subvars,
127  trim_leading_lf=False, checkmissing=False)
128  text = text.replace("%s%s%s" % (self.start_var_token, varname, self.end_var_token), str(value))
129  return text
130 
131  def write(self, file, text, subvars={}, trim_leading_lf=True):
132  '''write to a file with variable substitution'''
133  file.write(self.substitute(text, subvars=subvars, trim_leading_lf=trim_leading_lf))


mavlink
Author(s): Lorenz Meier
autogenerated on Sun Apr 7 2019 02:06:02