1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 """Classes to write good-looking output in different languages:
17 Fortran, C++, etc."""
18
19
20 import re
21 import collections
22 try:
23 import madgraph
24 except ImportError:
25 import internal.misc
26 else:
27 import madgraph.various.misc as misc
28
30 """Generic Writer class. All writers should inherit from this class."""
31
32 supported_preprocessor_commands = ['if']
33 preprocessor_command_re=re.compile(
34 "\s*(?P<command>%s)\s*\(\s*(?P<body>.*)\s*\)\s*{\s*"\
35 %('|'.join(supported_preprocessor_commands)))
36 preprocessor_endif_re=re.compile(\
37 "\s*}\s*(?P<endif>else)?\s*(\((?P<body>.*)\))?\s*(?P<new_block>{)?\s*")
38
40 """Exception raised if an error occurs in the definition
41 or the execution of a Writer."""
42
43 pass
44
46 """Exception raised if an error occurs in the handling of the
47 preprocessor tags '##' in the template file."""
48 pass
49
51 """Initialize file to write to"""
52
53 return file.__init__(self, name, opt)
54
56 """Write a line with proper indent and splitting of long lines
57 for the language in question."""
58
59 pass
60
66
88
89 - def writelines(self, lines, context={}, formatting=True):
90 """Extends the regular file.writeline() function to write out
91 nicely formatted code. When defining a context, then the lines
92 will be preprocessed to apply possible conditional statements on the
93 content of the template depending on the contextual variables specified."""
94
95 splitlines = []
96 if isinstance(lines, list):
97 for line in lines:
98 if not isinstance(line, str):
99 raise self.FileWriterError("%s not string" % repr(line))
100 splitlines.extend(line.split('\n'))
101 elif isinstance(lines, str):
102 splitlines.extend(lines.split('\n'))
103 else:
104 raise self.FileWriterError("%s not string" % repr(lines))
105
106 if len(context)>0:
107 splitlines = self.preprocess_template(splitlines,context=context)
108
109 for line in splitlines:
110 if formatting:
111 res_lines = self.write_line(line)
112 else:
113 res_lines = [line+'\n']
114 for line_to_write in res_lines:
115 self.write(line_to_write)
116
118 """ This class takes care of applying the pre-processing statements
119 starting with ## in the template .inc files, using the contextual
120 variables specified in the dictionary 'context' given in input with
121 the variable names given as keys and their respective value as values."""
122
123 template_lines = []
124 if isinstance(input_lines, list):
125 for line in input_lines:
126 if not isinstance(line, str):
127 raise self.FileWriterError("%s not string" % repr(input_lines))
128 template_lines.extend(line.split('\n'))
129 elif isinstance(input_lines, str):
130 template_lines.extend(input_lines.split('\n'))
131 else:
132 raise self.FileWriterError("%s not string" % repr(input_lines))
133
134
135 for contextual_variable, value in context.items():
136 exec('%s=%s'%(str(contextual_variable),repr(value)))
137
138 res = []
139
140 if_stack = []
141 for i, line in enumerate(template_lines):
142 if not line.startswith('##'):
143 if all(if_stack):
144 res.append(line)
145 continue
146 preproc_command = self.preprocessor_command_re.match(line[2:])
147
148 if preproc_command is None:
149 preproc_endif = self.preprocessor_endif_re.match(line[2:])
150 if len(if_stack)==0 or preproc_endif is None:
151 raise self.FilePreProcessingError, 'Incorrect '+\
152 'preprocessing command %s at line %d.'%(line,i)
153 if preproc_endif.group('new_block') is None:
154 if_stack.pop()
155 elif preproc_endif.group('endif')=='else':
156 if_stack[-1]=(not if_stack[-1])
157
158 elif preproc_command.group('command')=='if':
159 try:
160 if_stack.append(eval(preproc_command.group('body'))==True)
161 except Exception, e:
162 raise self.FilePreProcessingError, 'Could not evaluate'+\
163 "python expression '%s' given the context %s provided."%\
164 (preproc_command.group('body'),str(context))+\
165 "\nLine %d of file %s."%(i,self.name)
166
167 if len(if_stack)>0:
168 raise self.FilePreProcessingError, 'Some conditional statements are'+\
169 ' not properly terminated.'
170 return res
171
172
173
174
176 """Routines for writing fortran lines. Keeps track of indentation
177 and splitting of long lines"""
178
180 """Exception raised if an error occurs in the definition
181 or the execution of a FortranWriter."""
182 pass
183
184
185 keyword_pairs = {'^if.+then\s*$': ('^endif', 2),
186 '^type(?!\s*\()\s*.+\s*$': ('^endtype', 2),
187 '^do(?!\s+\d+)\s+': ('^enddo\s*$', 2),
188 '^subroutine': ('^end\s*$', 0),
189 '^module': ('^end\s*$', 0),
190 'function': ('^end\s*$', 0)}
191 single_indents = {'^else\s*$':-2,
192 '^else\s*if.+then\s*$':-2}
193 number_re = re.compile('^(?P<num>\d+)\s+(?P<rest>.*)')
194 line_cont_char = '$'
195 comment_char = 'c'
196 downcase = False
197 line_length = 71
198 max_split = 20
199 split_characters = "+-*/,) "
200 comment_split_characters = " "
201
202
203 __indent = 0
204 __keyword_list = []
205 __comment_pattern = re.compile(r"^(\s*#|c$|(c\s+([^=]|$))|cf2py|c\-\-|c\*\*)", re.IGNORECASE)
206 __continuation_line = re.compile(r"(?: )[$&]")
207
209 """Write a fortran line, with correct indent and line splits"""
210
211
212 assert(isinstance(line, str) and line.find('\n') == -1)
213
214
215 res_lines = []
216
217
218 if not line.lstrip():
219 res_lines.append("\n")
220 return res_lines
221
222
223 if self.__comment_pattern.search(line):
224
225 res_lines = self.write_comment_line(line.lstrip()[1:])
226 return res_lines
227 elif self.__continuation_line.search(line):
228 return line+'\n'
229 else:
230
231
232
233 myline = line.lstrip()
234
235
236 num_group = self.number_re.search(myline)
237 num = ""
238 if num_group:
239 num = num_group.group('num')
240 myline = num_group.group('rest')
241
242
243
244 (myline, part, post_comment) = myline.partition("!")
245
246 if part:
247 part = " " + part
248
249 myline = myline.replace('\"', '\'')
250
251 splitline = myline.split('\'')
252 myline = ""
253 i = 0
254 while i < len(splitline):
255 if i % 2 == 1:
256
257 while splitline[i] and splitline[i][-1] == '\\':
258 splitline[i] = splitline[i] + '\'' + splitline.pop(i + 1)
259 else:
260
261 if FortranWriter.downcase:
262 splitline[i] = splitline[i].lower()
263 else:
264 splitline[i] = splitline[i].upper()
265 i = i + 1
266
267 myline = "\'".join(splitline).rstrip()
268
269
270 if self.__keyword_list and re.search(self.keyword_pairs[\
271 self.__keyword_list[-1]][0], myline.lower()):
272 key = self.__keyword_list.pop()
273 self.__indent = self.__indent - self.keyword_pairs[key][1]
274
275
276 single_indent = 0
277 for key in self.single_indents.keys():
278 if re.search(key, myline.lower()):
279 self.__indent = self.__indent + self.single_indents[key]
280 single_indent = -self.single_indents[key]
281 break
282
283
284
285 res = self.split_line(" " + num + \
286 " " * (5 + self.__indent - len(num)) + myline,
287 self.split_characters,
288 " " * 5 + self.line_cont_char + \
289 " " * (self.__indent + 1))
290
291
292 for key in self.keyword_pairs.keys():
293 if re.search(key, myline.lower()):
294 self.__keyword_list.append(key)
295 self.__indent = self.__indent + self.keyword_pairs[key][1]
296 break
297
298
299 if single_indent != None:
300 self.__indent = self.__indent + single_indent
301 single_indent = None
302
303
304 res_lines.append("\n".join(res) + part + post_comment + "\n")
305
306 return res_lines
307
339
340 - def split_line(self, line, split_characters, line_start):
341 """Split a line if it is longer than self.line_length
342 columns. Split in preferential order according to
343 split_characters, and start each new line with line_start."""
344
345 res_lines = [line]
346
347 while len(res_lines[-1]) > self.line_length:
348 split_at = 0
349 for character in split_characters:
350 index = res_lines[-1][(self.line_length - self.max_split): \
351 self.line_length].rfind(character)
352 if index >= 0:
353 split_at_tmp = self.line_length - self.max_split + index
354 if split_at_tmp > split_at:
355 split_at = split_at_tmp
356 if split_at == 0:
357 split_at = self.line_length
358
359 newline = res_lines[-1][split_at:]
360 nquotes = self.count_number_of_quotes(newline)
361
362
363
364 offset = 0
365 if nquotes%2==1:
366 if res_lines[-1][(split_at-1)] == '\'':
367 offset = 1
368 nquotes -=1
369 res_lines.append(line_start +(res_lines[-1][(split_at-offset):]))
370 else:
371 res_lines.append(line_start +('//\''+res_lines[-1][(split_at-offset):]))
372
373 elif res_lines[-1][(split_at)] in self.split_characters:
374 if res_lines[-1][(split_at)] in ')':
375
376 offset = -1
377
378
379 res_lines.append(line_start +res_lines[-1][(split_at-offset):])
380 elif line_start.startswith(('c','C')) or res_lines[-1][(split_at)] in split_characters:
381 res_lines.append(line_start +res_lines[-1][(split_at):])
382 else:
383 l_start = line_start.rstrip()
384 res_lines.append(l_start +res_lines[-1][(split_at):])
385
386 res_lines[-2] = (res_lines[-2][:(split_at-offset)]+'\'' if nquotes%2==1 \
387 else res_lines[-2][:split_at-offset])
388 return res_lines
389
391 """ Count the number of real quotes (not escaped ones) in a line. """
392
393 splitline = line.split('\'')
394 i = 0
395 while i < len(splitline):
396 if i % 2 == 1:
397
398 while splitline[i] and splitline[i][-1] == '\\':
399 splitline[i] = splitline[i] + '\'' + splitline.pop(i + 1)
400 i = i + 1
401 return len(splitline)-1
402
403
404
405
406
407
409 """write the incoming text but fully removing the associate routine/function
410 text can be a path to a file, an iterator, a string
411 fct_names should be a list of functions to remove
412 """
413
414 f77_type = ['real*8', 'integer', 'double precision', 'logical']
415 pattern = re.compile('^\s+(?:SUBROUTINE|(?:%(type)s)\s+function)\s+([a-zA-Z]\w*)' \
416 % {'type':'|'.join(f77_type)}, re.I)
417
418 removed = []
419 if isinstance(text, str):
420 if '\n' in text:
421 text = text.split('\n')
422 else:
423 text = open(text)
424 if isinstance(fct_names, str):
425 fct_names = [fct_names]
426
427 to_write=True
428 for line in text:
429 fct = pattern.findall(line)
430 if fct:
431 if fct[0] in fct_names:
432 to_write = False
433 else:
434 to_write = True
435
436 if to_write:
437 if formatting:
438 if line.endswith('\n'):
439 line = line[:-1]
440 self.writelines(line)
441 else:
442 if not line.endswith('\n'):
443 line = '%s\n' % line
444 file.writelines(self, line)
445 else:
446 removed.append(line)
447
448 return removed
449
450
451
453 """Routines for writing C++ lines. Keeps track of brackets,
454 spaces, indentation and splitting of long lines"""
455
457 """Exception raised if an error occurs in the definition
458 or the execution of a CPPWriter."""
459 pass
460
461
462 standard_indent = 2
463 line_cont_indent = 4
464
465 indent_par_keywords = {'^if': standard_indent,
466 '^else if': standard_indent,
467 '^for': standard_indent,
468 '^while': standard_indent,
469 '^switch': standard_indent}
470 indent_single_keywords = {'^else': standard_indent}
471 indent_content_keywords = {'^class': standard_indent,
472 '^namespace': 0}
473 cont_indent_keywords = {'^case': standard_indent,
474 '^default': standard_indent,
475 '^public': standard_indent,
476 '^private': standard_indent,
477 '^protected': standard_indent}
478
479 spacing_patterns = [('\s*\"\s*}', '\"'),
480 ('\s*,\s*', ', '),
481 ('\s*-\s*', ' - '),
482 ('([{(,=])\s*-\s*', '\g<1> -'),
483 ('(return)\s*-\s*', '\g<1> -'),
484 ('\s*\+\s*', ' + '),
485 ('([{(,=])\s*\+\s*', '\g<1> +'),
486 ('\(\s*', '('),
487 ('\s*\)', ')'),
488 ('\{\s*', '{'),
489 ('\s*\}', '}'),
490 ('\s*=\s*', ' = '),
491 ('\s*>\s*', ' > '),
492 ('\s*<\s*', ' < '),
493 ('\s*!\s*', ' !'),
494 ('\s*/\s*', '/'),
495 ('\s*\*\s*', ' * '),
496 ('\s*-\s+-\s*', '-- '),
497 ('\s*\+\s+\+\s*', '++ '),
498 ('\s*-\s+=\s*', ' -= '),
499 ('\s*\+\s+=\s*', ' += '),
500 ('\s*\*\s+=\s*', ' *= '),
501 ('\s*/=\s*', ' /= '),
502 ('\s*>\s+>\s*', ' >> '),
503 ('<\s*double\s*>>\s*', '<double> > '),
504 ('\s*<\s+<\s*', ' << '),
505 ('\s*-\s+>\s*', '->'),
506 ('\s*=\s+=\s*', ' == '),
507 ('\s*!\s+=\s*', ' != '),
508 ('\s*>\s+=\s*', ' >= '),
509 ('\s*<\s+=\s*', ' <= '),
510 ('\s*&&\s*', ' && '),
511 ('\s*\|\|\s*', ' || '),
512 ('\s*{\s*}', ' {}'),
513 ('\s*;\s*', '; '),
514 (';\s*\}', ';}'),
515 (';\s*$}', ';'),
516 ('\s*<\s*([a-zA-Z0-9]+?)\s*>', '<\g<1>>'),
517 ('^#include\s*<\s*(.*?)\s*>', '#include <\g<1>>'),
518 ('(\d+\.{0,1}\d*|\.\d+)\s*[eE]\s*([+-]{0,1})\s*(\d+)',
519 '\g<1>e\g<2>\g<3>'),
520 ('\s+',' ')]
521 spacing_re = dict([(key[0], re.compile(key[0])) for key in \
522 spacing_patterns])
523
524 init_array_pattern = re.compile(r"=\s*\{.*\}")
525 short_clause_pattern = re.compile(r"\{.*\}")
526
527 comment_char = '//'
528 comment_pattern = re.compile(r"^(\s*#\s+|\s*//)")
529 start_comment_pattern = re.compile(r"^(\s*/\*)")
530 end_comment_pattern = re.compile(r"(\s*\*/)$")
531
532 quote_chars = re.compile(r"[^\\][\"\']|^[\"\']")
533 no_space_comment_patterns = re.compile(r"--|\*\*|==|\+\+")
534 line_length = 80
535 max_split = 40
536 split_characters = " "
537 comment_split_characters = " "
538
539
540 __indent = 0
541 __keyword_list = collections.deque()
542 __comment_ongoing = False
543
545 """Write a C++ line, with correct indent, spacing and line splits"""
546
547
548 assert(isinstance(line, str) and line.find('\n') == -1)
549
550 res_lines = []
551
552
553 if self.comment_pattern.search(line) or \
554 self.start_comment_pattern.search(line) or \
555 self.__comment_ongoing:
556
557 res_lines = self.write_comment_line(line.lstrip())
558 return res_lines
559
560
561
562
563 myline = line.lstrip()
564
565
566 if not myline:
567 return ["\n"]
568
569
570 if myline[0] == "{":
571
572 indent = self.__indent
573 key = ""
574 if self.__keyword_list:
575 key = self.__keyword_list[-1]
576 if key in self.indent_par_keywords:
577 indent = indent - self.indent_par_keywords[key]
578 elif key in self.indent_single_keywords:
579 indent = indent - self.indent_single_keywords[key]
580 elif key in self.indent_content_keywords:
581 indent = indent - self.indent_content_keywords[key]
582 else:
583
584 self.__indent = self.__indent + self.standard_indent
585
586 res_lines.append(" " * indent + "{" + "\n")
587
588 self.__keyword_list.append("{")
589 myline = myline[1:].lstrip()
590 if myline:
591
592 res_lines.extend(self.write_line(myline))
593 return res_lines
594
595
596 if myline[0] == "}":
597
598 if not self.__keyword_list:
599 raise self.CPPWriterError(\
600 'Non-matching } in C++ output: ' \
601 + myline)
602
603 if self.__keyword_list[-1] in self.cont_indent_keywords.keys():
604 key = self.__keyword_list.pop()
605 self.__indent = self.__indent - self.cont_indent_keywords[key]
606
607 if not self.__keyword_list.pop() == "{":
608 raise self.CPPWriterError(\
609 'Non-matching } in C++ output: ' \
610 + ",".join(self.__keyword_list) + myline)
611
612 key = ""
613 if self.__keyword_list:
614 key = self.__keyword_list[-1]
615 if key in self.indent_par_keywords:
616 self.__indent = self.__indent - \
617 self.indent_par_keywords[key]
618 self.__keyword_list.pop()
619 elif key in self.indent_single_keywords:
620 self.__indent = self.__indent - \
621 self.indent_single_keywords[key]
622 self.__keyword_list.pop()
623 elif key in self.indent_content_keywords:
624 self.__indent = self.__indent - \
625 self.indent_content_keywords[key]
626 self.__keyword_list.pop()
627 else:
628
629 self.__indent = self.__indent - self.standard_indent
630
631
632 breakline_index = 1
633 if len(myline) > 1:
634 if myline[1] in [";", ","]:
635 breakline_index = 2
636 elif myline[1:].lstrip()[:2] == "//":
637 if myline.endswith('\n'):
638 breakline_index = len(myline) - 1
639 else:
640 breakline_index = len(myline)
641 res_lines.append("\n".join(self.split_line(\
642 myline[:breakline_index],
643 self.split_characters)) + "\n")
644 if len(myline) > breakline_index and myline[breakline_index] =='\n':
645 breakline_index +=1
646 myline = myline[breakline_index:].lstrip()
647
648 if myline:
649
650 res_lines.extend(self.write_line(myline))
651 return res_lines
652
653
654 for key in self.indent_par_keywords.keys():
655 if re.search(key, myline):
656
657 parenstack = collections.deque()
658 for i, ch in enumerate(myline[len(key)-1:]):
659 if ch == '(':
660 parenstack.append(ch)
661 elif ch == ')':
662 try:
663 parenstack.pop()
664 except IndexError:
665
666 raise self.CPPWriterError(\
667 'Non-matching parenthesis in C++ output' \
668 + myline)
669 if not parenstack:
670
671 break
672 endparen_index = len(key) + i
673
674 res_lines.append("\n".join(self.split_line(\
675 myline[:endparen_index], \
676 self.split_characters)) + \
677 "\n")
678 myline = myline[endparen_index:].lstrip()
679
680 self.__keyword_list.append(key)
681 self.__indent = self.__indent + \
682 self.indent_par_keywords[key]
683 if myline:
684
685 res_lines.extend(self.write_line(myline))
686
687 return res_lines
688
689
690 for key in self.indent_single_keywords.keys():
691 if re.search(key, myline):
692 end_index = len(key) - 1
693
694 res_lines.append(" " * self.__indent + myline[:end_index] + \
695 "\n")
696 myline = myline[end_index:].lstrip()
697
698 self.__keyword_list.append(key)
699 self.__indent = self.__indent + \
700 self.indent_single_keywords[key]
701 if myline:
702
703 res_lines.extend(self.write_line(myline))
704
705 return res_lines
706
707
708 for key in self.indent_content_keywords.keys():
709 if re.search(key, myline):
710
711 if "{" in myline:
712 end_index = myline.index("{")
713 else:
714 end_index = len(myline)
715 res_lines.append("\n".join(self.split_line(\
716 myline[:end_index], \
717 self.split_characters)) + \
718 "\n")
719 myline = myline[end_index:].lstrip()
720
721 self.__keyword_list.append(key)
722 self.__indent = self.__indent + \
723 self.indent_content_keywords[key]
724 if myline:
725
726 res_lines.extend(self.write_line(myline))
727
728 return res_lines
729
730
731 for key in self.cont_indent_keywords.keys():
732 if re.search(key, myline):
733
734 if self.__keyword_list[-1] in self.cont_indent_keywords.keys():
735 self.__indent = self.__indent - \
736 self.cont_indent_keywords[\
737 self.__keyword_list.pop()]
738
739 res_lines.append("\n".join(self.split_line(myline, \
740 self.split_characters)) + \
741 "\n")
742
743 self.__keyword_list.append(key)
744 self.__indent = self.__indent + \
745 self.cont_indent_keywords[key]
746
747 return res_lines
748
749
750 if self.init_array_pattern.search(myline):
751 res_lines.append("\n".join(self.split_line(\
752 myline,
753 self.split_characters)) + \
754 "\n")
755 return res_lines
756
757
758 if self.short_clause_pattern.search(myline):
759 lines = self.split_line(myline,
760 self.split_characters)
761 if len(lines) == 1:
762 res_lines.append("\n".join(lines) + "\n")
763 return res_lines
764
765
766 if "{" in myline:
767 end_index = myline.index("{")
768 res_lines.append("\n".join(self.split_line(\
769 myline[:end_index], \
770 self.split_characters)) + \
771 "\n")
772 myline = myline[end_index:].lstrip()
773 if myline:
774
775 res_lines.extend(self.write_line(myline))
776 return res_lines
777
778
779 if "}" in myline:
780 end_index = myline.index("}")
781 res_lines.append("\n".join(self.split_line(\
782 myline[:end_index], \
783 self.split_characters)) + \
784 "\n")
785 myline = myline[end_index:].lstrip()
786 if myline:
787
788 res_lines.extend(self.write_line(myline))
789 return res_lines
790
791
792 res_lines.append("\n".join(self.split_line(myline, \
793 self.split_characters)) + "\n")
794
795
796 if self.__keyword_list:
797 if self.__keyword_list[-1] in self.indent_par_keywords:
798 self.__indent = self.__indent - \
799 self.indent_par_keywords[self.__keyword_list.pop()]
800 elif self.__keyword_list[-1] in self.indent_single_keywords:
801 self.__indent = self.__indent - \
802 self.indent_single_keywords[self.__keyword_list.pop()]
803 elif self.__keyword_list[-1] in self.indent_content_keywords:
804 self.__indent = self.__indent - \
805 self.indent_content_keywords[self.__keyword_list.pop()]
806
807 return res_lines
808
841
843 """Split a line if it is longer than self.line_length
844 columns. Split in preferential order according to
845 split_characters. Also fix spacing for line."""
846
847
848 comment = ""
849 if line.find(self.comment_char) > -1:
850 line, dum, comment = line.partition(self.comment_char)
851
852
853 quotes = self.quote_chars.finditer(line)
854
855 start_pos = 0
856 line_quotes = []
857 line_no_quotes = []
858 for i, quote in enumerate(quotes):
859 if i % 2 == 0:
860
861 line_no_quotes.append(line[start_pos:quote.start()])
862 start_pos = quote.start()
863 else:
864
865 line_quotes.append(line[start_pos:quote.end()])
866 start_pos = quote.end()
867
868 line_no_quotes.append(line[start_pos:])
869
870
871 line.rstrip()
872 for i, no_quote in enumerate(line_no_quotes):
873 for key in self.spacing_patterns:
874 no_quote = self.spacing_re[key[0]].sub(key[1], no_quote)
875 line_no_quotes[i] = no_quote
876
877
878 line = line_no_quotes[0]
879 for i in range(len(line_quotes)):
880 line += line_quotes[i]
881 if len(line_no_quotes) > i + 1:
882 line += line_no_quotes[i+1]
883
884
885 res_lines = [" " * self.__indent + line]
886
887 while len(res_lines[-1]) > self.line_length:
888 long_line = res_lines[-1]
889 split_at = -1
890 for character in split_characters:
891 index = long_line[(self.line_length - self.max_split): \
892 self.line_length].rfind(character)
893 if index >= 0:
894 split_at = self.line_length - self.max_split + index + 1
895 break
896
897
898 if split_at == -1:
899 split_at = len(long_line)
900 for character in split_characters:
901 split = long_line[self.line_length].find(character)
902 if split > 0:
903 split_at = min(split, split_at)
904 if split_at == len(long_line):
905 break
906
907
908 quotes = self.quote_chars.findall(long_line[:split_at])
909 if quotes and len(quotes) % 2 == 1:
910 quote_match = self.quote_chars.search(long_line[split_at:])
911 if not quote_match:
912 raise self.CPPWriterError(\
913 "Error: Unmatched quote in line " + long_line)
914 split_at = quote_match.end() + split_at + 1
915 split_match = re.search(self.split_characters,
916 long_line[split_at:])
917 if split_match:
918 split_at = split_at + split_match.start()
919 else:
920 split_at = len(long_line) + 1
921
922
923 if long_line[split_at:].lstrip():
924
925 res_lines[-1] = long_line[:split_at].rstrip()
926 res_lines.append(" " * \
927 (self.__indent + self.line_cont_indent) + \
928 long_line[split_at:].strip())
929 else:
930 break
931
932 if comment:
933 res_lines[-1] += " " + self.comment_char + comment
934
935 return res_lines
936
965
971
973
977
979 """Extends the regular file.writeline() function to write out
980 nicely formatted code"""
981
982 self.write(lines)
983