+def _c_wr_stringlist(indent, strlist):
+ '''
+ Writes the given list of strings to the source file.
+ Each line is prepended by the indent string
+ '''
+ for str in strlist:
+ _c("%s%s", indent, str)
+
+
+class PreCode(object):
+ '''
+ For pre-code generated by expression generation
+ (for example, the for-loop of a sumof)
+ This has to account for recursiveness of the expression
+ generation, i.e., there may be pre-code for pre-code.
+ Therefore this is implemented as a stack of lists of lines.
+
+ If redirection is switched on, then all output is collected in
+ self.redirect_code and self.redirect_tempvars instead of
+ being sent to the output via _h und _c.
+ '''
+ def __init__(self):
+ self.nesting_level = 0
+ self.tempvars = []
+ self.codelines = []
+ self.redirect_code = None
+ self.redirect_tempvars = None
+ self.indent_str = ' '
+ self.indent_stack = []
+ self.tempvar_num = 0
+
+
+ # start and end of pre-code blocks
+ def start(self):
+ self.nesting_level += 1
+
+ def end(self):
+ self.nesting_level -= 1
+ if self.nesting_level == 0:
+ # lowest pre-code level is finished -> output to source
+ if self.redirect_tempvars is None:
+ _c_wr_stringlist('', self.tempvars)
+ self.tempvars = []
+ else:
+ self.redirect_tempvars.extend(self.tempvars)
+ self.tempvars = []
+ if self.redirect_code == None:
+ _c_wr_stringlist('', self.codelines)
+ self.codelines = []
+ else:
+ self.redirect_code.extend(self.codelines)
+ self.codelines = []
+
+
+ def output_tempvars(self):
+ if self.redirect_code == None:
+ _c_wr_stringlist('', self.tempvars)
+ self.tempvars = []
+
+ # output to precode
+ def code(self, fmt, *args):
+ self.codelines.append(self.indent_str + fmt % args)
+
+ def tempvar(self, fmt, *args):
+ self.tempvars.append(' ' + (fmt % args))
+
+ # get a unique name for a temporary variable
+ def get_tempvarname(self):
+ self.tempvar_num += 1
+ return "xcb_pre_tmp_%d" % self.tempvar_num
+
+ # indentation
+
+ def push_indent(self, indentstr):
+ self.indent_stack.append(self.indent_str)
+ self.indent_str = indentstr
+
+ def push_addindent(self, indent_add_str):
+ self.push_indent(self.indent_str + indent_add_str)
+
+ def indent(self):
+ self.push_addindent(' ')
+
+ def pop_indent(self):
+ self.indent_str = self.indent_stack.pop()
+
+ # redirection to lists
+ def redirect_start(self, redirect_code, redirect_tempvars=None):
+ self.redirect_code = redirect_code
+ self.redirect_tempvars = redirect_tempvars
+ if redirect_tempvars is not None:
+ self.tempvar_num = 0
+
+ def redirect_end(self):
+ self.redirect_code = None
+ self.redirect_tempvars = None
+
+# global PreCode handler
+_c_pre = PreCode()
+
+