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