mavtemplate.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 '''
00003 simple templating system for mavlink generator
00004 
00005 Copyright Andrew Tridgell 2011
00006 Released under GNU GPL version 3 or later
00007 '''
00008 
00009 from .mavparse import MAVParseError
00010 
00011 class MAVTemplate(object):
00012     '''simple templating system'''
00013     def __init__(self,
00014                  start_var_token="${", 
00015                  end_var_token="}", 
00016                  start_rep_token="${{", 
00017                  end_rep_token="}}",
00018                  trim_leading_lf=True,
00019                  checkmissing=True):
00020         self.start_var_token = start_var_token
00021         self.end_var_token = end_var_token
00022         self.start_rep_token = start_rep_token
00023         self.end_rep_token = end_rep_token
00024         self.trim_leading_lf = trim_leading_lf
00025         self.checkmissing = checkmissing
00026 
00027     def find_end(self, text, start_token, end_token, ignore_end_token=None):
00028         '''find the of a token.
00029         Returns the offset in the string immediately after the matching end_token'''
00030         if not text.startswith(start_token):
00031             raise MAVParseError("invalid token start")
00032         offset = len(start_token)
00033         nesting = 1
00034         while nesting > 0:
00035             idx1 = text[offset:].find(start_token)
00036             idx2 = text[offset:].find(end_token)
00037             # Check for false positives due to another similar token
00038             # For example, make sure idx2 points to the second '}' in ${{field: ${name}}}
00039             if ignore_end_token:
00040                 combined_token = ignore_end_token + end_token
00041                 if text[offset+idx2:offset+idx2+len(combined_token)] == combined_token:
00042                     idx2 += len(ignore_end_token)
00043             if idx1 == -1 and idx2 == -1:
00044                 raise MAVParseError("token nesting error")
00045             if idx1 == -1 or idx1 > idx2:
00046                 offset += idx2 + len(end_token)
00047                 nesting -= 1
00048             else:
00049                 offset += idx1 + len(start_token)
00050                 nesting += 1
00051         return offset
00052 
00053     def find_var_end(self, text):
00054         '''find the of a variable'''
00055         return self.find_end(text, self.start_var_token, self.end_var_token)
00056 
00057     def find_rep_end(self, text):
00058         '''find the of a repitition'''
00059         return self.find_end(text, self.start_rep_token, self.end_rep_token, ignore_end_token=self.end_var_token)
00060 
00061     def substitute(self, text, subvars={},
00062                    trim_leading_lf=None, checkmissing=None):
00063         '''substitute variables in a string'''
00064 
00065         if trim_leading_lf is None:
00066             trim_leading_lf = self.trim_leading_lf
00067         if checkmissing is None:
00068             checkmissing = self.checkmissing
00069 
00070         # handle repititions
00071         while True:
00072             subidx = text.find(self.start_rep_token)
00073             if subidx == -1:
00074                 break
00075             endidx = self.find_rep_end(text[subidx:])
00076             if endidx == -1:
00077                 raise MAVParseError("missing end macro in %s" % text[subidx:])
00078             part1 = text[0:subidx]
00079             part2 = text[subidx+len(self.start_rep_token):subidx+(endidx-len(self.end_rep_token))]
00080             part3 = text[subidx+endidx:]
00081             a = part2.split(':')
00082             field_name = a[0]
00083             rest = ':'.join(a[1:])
00084             v = None
00085             if isinstance(subvars, dict):
00086                 v = subvars.get(field_name, None)
00087             else:
00088                 v = getattr(subvars, field_name, None)
00089             if v is None:
00090                 raise MAVParseError('unable to find field %s' % field_name)
00091             t1 = part1
00092             for f in v:
00093                 t1 += self.substitute(rest, f, trim_leading_lf=False, checkmissing=False)
00094             if len(v) != 0 and t1[-1] in ["\n", ","]:
00095                 t1 = t1[:-1]
00096             t1 += part3
00097             text = t1
00098                 
00099         if trim_leading_lf:
00100             if text[0] == '\n':
00101                 text = text[1:]
00102         while True:
00103             idx = text.find(self.start_var_token)
00104             if idx == -1:
00105                 return text
00106             endidx = text[idx:].find(self.end_var_token)
00107             if endidx == -1:
00108                 raise MAVParseError('missing end of variable: %s' % text[idx:idx+10])
00109             varname = text[idx+2:idx+endidx]
00110             if isinstance(subvars, dict):
00111                 if not varname in subvars:
00112                     if checkmissing:
00113                         raise MAVParseError("unknown variable in '%s%s%s'" % (
00114                             self.start_var_token, varname, self.end_var_token))
00115                     return text[0:idx+endidx] + self.substitute(text[idx+endidx:], subvars,
00116                                                                 trim_leading_lf=False, checkmissing=False)
00117                 value = subvars[varname]
00118             else:
00119                 value = getattr(subvars, varname, None)
00120                 if value is None:
00121                     if checkmissing:
00122                         raise MAVParseError("unknown variable in '%s%s%s'" % (
00123                             self.start_var_token, varname, self.end_var_token))
00124                     return text[0:idx+endidx] + self.substitute(text[idx+endidx:], subvars,
00125                                                                 trim_leading_lf=False, checkmissing=False)
00126             text = text.replace("%s%s%s" % (self.start_var_token, varname, self.end_var_token), str(value))
00127         return text
00128 
00129     def write(self, file, text, subvars={}, trim_leading_lf=True):
00130         '''write to a file with variable substitution'''
00131         file.write(self.substitute(text, subvars=subvars, trim_leading_lf=trim_leading_lf))


mavlink
Author(s): Lorenz Meier
autogenerated on Sun May 22 2016 04:05:43