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 def get_split_index(line, max_length, max_split, split_characters):
346 split_at = 0
347 for character in split_characters:
348 index = line[(max_length - max_split): \
349 max_length].rfind(character)
350 if index >= 0:
351 split_at_tmp = max_length - max_split + index
352 if split_at_tmp > split_at:
353 split_at = split_at_tmp
354 return split_at
355
356
357 res_lines = [line]
358
359 while len(res_lines[-1]) > self.line_length:
360 split_at = get_split_index(res_lines[-1], self.line_length,
361 self.max_split, split_characters)
362 if split_at == 0:
363 split_at = get_split_index(res_lines[-1], self.line_length,
364 self.max_split + 30, split_characters)
365 if split_at == 0:
366 split_at = self.line_length
367
368 newline = res_lines[-1][split_at:]
369 nquotes = self.count_number_of_quotes(newline)
370
371
372
373 offset = 0
374 if nquotes%2==1:
375 if res_lines[-1][(split_at-1)] == '\'':
376 offset = 1
377 nquotes -=1
378 res_lines.append(line_start +(res_lines[-1][(split_at-offset):]))
379 else:
380 res_lines.append(line_start +('//\''+res_lines[-1][(split_at-offset):]))
381
382 elif res_lines[-1][(split_at)] in self.split_characters:
383 if res_lines[-1][(split_at)] in ')':
384
385 offset = -1
386
387
388 res_lines.append(line_start +res_lines[-1][(split_at-offset):])
389 elif line_start.startswith(('c','C')) or res_lines[-1][(split_at)] in split_characters:
390 res_lines.append(line_start +res_lines[-1][(split_at):])
391 else:
392 l_start = line_start.rstrip()
393 res_lines.append(l_start +res_lines[-1][(split_at):])
394
395 res_lines[-2] = (res_lines[-2][:(split_at-offset)]+'\'' if nquotes%2==1 \
396 else res_lines[-2][:split_at-offset])
397 return res_lines
398
400 """ Count the number of real quotes (not escaped ones) in a line. """
401
402 splitline = line.split('\'')
403 i = 0
404 while i < len(splitline):
405 if i % 2 == 1:
406
407 while splitline[i] and splitline[i][-1] == '\\':
408 splitline[i] = splitline[i] + '\'' + splitline.pop(i + 1)
409 i = i + 1
410 return len(splitline)-1
411
412
413
414
415
416
418 """write the incoming text but fully removing the associate routine/function
419 text can be a path to a file, an iterator, a string
420 fct_names should be a list of functions to remove
421 """
422
423 f77_type = ['real*8', 'integer', 'double precision', 'logical']
424 pattern = re.compile('^\s+(?:SUBROUTINE|(?:%(type)s)\s+function)\s+([a-zA-Z]\w*)' \
425 % {'type':'|'.join(f77_type)}, re.I)
426
427 removed = []
428 if isinstance(text, str):
429 if '\n' in text:
430 text = text.split('\n')
431 else:
432 text = open(text)
433 if isinstance(fct_names, str):
434 fct_names = [fct_names]
435
436 to_write=True
437 for line in text:
438 fct = pattern.findall(line)
439 if fct:
440 if fct[0] in fct_names:
441 to_write = False
442 else:
443 to_write = True
444
445 if to_write:
446 if formatting:
447 if line.endswith('\n'):
448 line = line[:-1]
449 self.writelines(line)
450 else:
451 if not line.endswith('\n'):
452 line = '%s\n' % line
453 file.writelines(self, line)
454 else:
455 removed.append(line)
456
457 return removed
458
459
460
462 """Routines for writing C++ lines. Keeps track of brackets,
463 spaces, indentation and splitting of long lines"""
464
466 """Exception raised if an error occurs in the definition
467 or the execution of a CPPWriter."""
468 pass
469
470
471 standard_indent = 2
472 line_cont_indent = 4
473
474 indent_par_keywords = {'^if': standard_indent,
475 '^else if': standard_indent,
476 '^for': standard_indent,
477 '^while': standard_indent,
478 '^switch': standard_indent}
479 indent_single_keywords = {'^else': standard_indent}
480 indent_content_keywords = {'^class': standard_indent,
481 '^namespace': 0}
482 cont_indent_keywords = {'^case': standard_indent,
483 '^default': standard_indent,
484 '^public': standard_indent,
485 '^private': standard_indent,
486 '^protected': standard_indent}
487
488 spacing_patterns = [('\s*\"\s*}', '\"'),
489 ('\s*,\s*', ', '),
490 ('\s*-\s*', ' - '),
491 ('([{(,=])\s*-\s*', '\g<1> -'),
492 ('(return)\s*-\s*', '\g<1> -'),
493 ('\s*\+\s*', ' + '),
494 ('([{(,=])\s*\+\s*', '\g<1> +'),
495 ('\(\s*', '('),
496 ('\s*\)', ')'),
497 ('\{\s*', '{'),
498 ('\s*\}', '}'),
499 ('\s*=\s*', ' = '),
500 ('\s*>\s*', ' > '),
501 ('\s*<\s*', ' < '),
502 ('\s*!\s*', ' !'),
503 ('\s*/\s*', '/'),
504 ('\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+>\s*', ' >> '),
512 ('<\s*double\s*>>\s*', '<double> > '),
513 ('\s*<\s+<\s*', ' << '),
514 ('\s*-\s+>\s*', '->'),
515 ('\s*=\s+=\s*', ' == '),
516 ('\s*!\s+=\s*', ' != '),
517 ('\s*>\s+=\s*', ' >= '),
518 ('\s*<\s+=\s*', ' <= '),
519 ('\s*&&\s*', ' && '),
520 ('\s*\|\|\s*', ' || '),
521 ('\s*{\s*}', ' {}'),
522 ('\s*;\s*', '; '),
523 (';\s*\}', ';}'),
524 (';\s*$}', ';'),
525 ('\s*<\s*([a-zA-Z0-9]+?)\s*>', '<\g<1>>'),
526 ('^#include\s*<\s*(.*?)\s*>', '#include <\g<1>>'),
527 ('(\d+\.{0,1}\d*|\.\d+)\s*[eE]\s*([+-]{0,1})\s*(\d+)',
528 '\g<1>e\g<2>\g<3>'),
529 ('\s+',' ')]
530 spacing_re = dict([(key[0], re.compile(key[0])) for key in \
531 spacing_patterns])
532
533 init_array_pattern = re.compile(r"=\s*\{.*\}")
534 short_clause_pattern = re.compile(r"\{.*\}")
535
536 comment_char = '//'
537 comment_pattern = re.compile(r"^(\s*#\s+|\s*//)")
538 start_comment_pattern = re.compile(r"^(\s*/\*)")
539 end_comment_pattern = re.compile(r"(\s*\*/)$")
540
541 quote_chars = re.compile(r"[^\\][\"\']|^[\"\']")
542 no_space_comment_patterns = re.compile(r"--|\*\*|==|\+\+")
543 line_length = 80
544 max_split = 40
545 split_characters = " "
546 comment_split_characters = " "
547
548
549 __indent = 0
550 __keyword_list = collections.deque()
551 __comment_ongoing = False
552
554 """Write a C++ line, with correct indent, spacing and line splits"""
555
556
557 assert(isinstance(line, str) and line.find('\n') == -1)
558
559 res_lines = []
560
561
562 if self.comment_pattern.search(line) or \
563 self.start_comment_pattern.search(line) or \
564 self.__comment_ongoing:
565
566 res_lines = self.write_comment_line(line.lstrip())
567 return res_lines
568
569
570
571
572 myline = line.lstrip()
573
574
575 if not myline:
576 return ["\n"]
577
578
579 if myline[0] == "{":
580
581 indent = self.__indent
582 key = ""
583 if self.__keyword_list:
584 key = self.__keyword_list[-1]
585 if key in self.indent_par_keywords:
586 indent = indent - self.indent_par_keywords[key]
587 elif key in self.indent_single_keywords:
588 indent = indent - self.indent_single_keywords[key]
589 elif key in self.indent_content_keywords:
590 indent = indent - self.indent_content_keywords[key]
591 else:
592
593 self.__indent = self.__indent + self.standard_indent
594
595 res_lines.append(" " * indent + "{" + "\n")
596
597 self.__keyword_list.append("{")
598 myline = myline[1:].lstrip()
599 if myline:
600
601 res_lines.extend(self.write_line(myline))
602 return res_lines
603
604
605 if myline[0] == "}":
606
607 if not self.__keyword_list:
608 raise self.CPPWriterError(\
609 'Non-matching } in C++ output: ' \
610 + myline)
611
612 if self.__keyword_list[-1] in self.cont_indent_keywords.keys():
613 key = self.__keyword_list.pop()
614 self.__indent = self.__indent - self.cont_indent_keywords[key]
615
616 if not self.__keyword_list.pop() == "{":
617 raise self.CPPWriterError(\
618 'Non-matching } in C++ output: ' \
619 + ",".join(self.__keyword_list) + myline)
620
621 key = ""
622 if self.__keyword_list:
623 key = self.__keyword_list[-1]
624 if key in self.indent_par_keywords:
625 self.__indent = self.__indent - \
626 self.indent_par_keywords[key]
627 self.__keyword_list.pop()
628 elif key in self.indent_single_keywords:
629 self.__indent = self.__indent - \
630 self.indent_single_keywords[key]
631 self.__keyword_list.pop()
632 elif key in self.indent_content_keywords:
633 self.__indent = self.__indent - \
634 self.indent_content_keywords[key]
635 self.__keyword_list.pop()
636 else:
637
638 self.__indent = self.__indent - self.standard_indent
639
640
641 breakline_index = 1
642 if len(myline) > 1:
643 if myline[1] in [";", ","]:
644 breakline_index = 2
645 elif myline[1:].lstrip()[:2] == "//":
646 if myline.endswith('\n'):
647 breakline_index = len(myline) - 1
648 else:
649 breakline_index = len(myline)
650 res_lines.append("\n".join(self.split_line(\
651 myline[:breakline_index],
652 self.split_characters)) + "\n")
653 if len(myline) > breakline_index and myline[breakline_index] =='\n':
654 breakline_index +=1
655 myline = myline[breakline_index:].lstrip()
656
657 if myline:
658
659 res_lines.extend(self.write_line(myline))
660 return res_lines
661
662
663 for key in self.indent_par_keywords.keys():
664 if re.search(key, myline):
665
666 parenstack = collections.deque()
667 for i, ch in enumerate(myline[len(key)-1:]):
668 if ch == '(':
669 parenstack.append(ch)
670 elif ch == ')':
671 try:
672 parenstack.pop()
673 except IndexError:
674
675 raise self.CPPWriterError(\
676 'Non-matching parenthesis in C++ output' \
677 + myline)
678 if not parenstack:
679
680 break
681 endparen_index = len(key) + i
682
683 res_lines.append("\n".join(self.split_line(\
684 myline[:endparen_index], \
685 self.split_characters)) + \
686 "\n")
687 myline = myline[endparen_index:].lstrip()
688
689 self.__keyword_list.append(key)
690 self.__indent = self.__indent + \
691 self.indent_par_keywords[key]
692 if myline:
693
694 res_lines.extend(self.write_line(myline))
695
696 return res_lines
697
698
699 for key in self.indent_single_keywords.keys():
700 if re.search(key, myline):
701 end_index = len(key) - 1
702
703 res_lines.append(" " * self.__indent + myline[:end_index] + \
704 "\n")
705 myline = myline[end_index:].lstrip()
706
707 self.__keyword_list.append(key)
708 self.__indent = self.__indent + \
709 self.indent_single_keywords[key]
710 if myline:
711
712 res_lines.extend(self.write_line(myline))
713
714 return res_lines
715
716
717 for key in self.indent_content_keywords.keys():
718 if re.search(key, myline):
719
720 if "{" in myline:
721 end_index = myline.index("{")
722 else:
723 end_index = len(myline)
724 res_lines.append("\n".join(self.split_line(\
725 myline[:end_index], \
726 self.split_characters)) + \
727 "\n")
728 myline = myline[end_index:].lstrip()
729
730 self.__keyword_list.append(key)
731 self.__indent = self.__indent + \
732 self.indent_content_keywords[key]
733 if myline:
734
735 res_lines.extend(self.write_line(myline))
736
737 return res_lines
738
739
740 for key in self.cont_indent_keywords.keys():
741 if re.search(key, myline):
742
743 if self.__keyword_list[-1] in self.cont_indent_keywords.keys():
744 self.__indent = self.__indent - \
745 self.cont_indent_keywords[\
746 self.__keyword_list.pop()]
747
748 res_lines.append("\n".join(self.split_line(myline, \
749 self.split_characters)) + \
750 "\n")
751
752 self.__keyword_list.append(key)
753 self.__indent = self.__indent + \
754 self.cont_indent_keywords[key]
755
756 return res_lines
757
758
759 if self.init_array_pattern.search(myline):
760 res_lines.append("\n".join(self.split_line(\
761 myline,
762 self.split_characters)) + \
763 "\n")
764 return res_lines
765
766
767 if self.short_clause_pattern.search(myline):
768 lines = self.split_line(myline,
769 self.split_characters)
770 if len(lines) == 1:
771 res_lines.append("\n".join(lines) + "\n")
772 return res_lines
773
774
775 if "{" in myline:
776 end_index = myline.index("{")
777 res_lines.append("\n".join(self.split_line(\
778 myline[:end_index], \
779 self.split_characters)) + \
780 "\n")
781 myline = myline[end_index:].lstrip()
782 if myline:
783
784 res_lines.extend(self.write_line(myline))
785 return res_lines
786
787
788 if "}" in myline:
789 end_index = myline.index("}")
790 res_lines.append("\n".join(self.split_line(\
791 myline[:end_index], \
792 self.split_characters)) + \
793 "\n")
794 myline = myline[end_index:].lstrip()
795 if myline:
796
797 res_lines.extend(self.write_line(myline))
798 return res_lines
799
800
801 res_lines.append("\n".join(self.split_line(myline, \
802 self.split_characters)) + "\n")
803
804
805 if self.__keyword_list:
806 if self.__keyword_list[-1] in self.indent_par_keywords:
807 self.__indent = self.__indent - \
808 self.indent_par_keywords[self.__keyword_list.pop()]
809 elif self.__keyword_list[-1] in self.indent_single_keywords:
810 self.__indent = self.__indent - \
811 self.indent_single_keywords[self.__keyword_list.pop()]
812 elif self.__keyword_list[-1] in self.indent_content_keywords:
813 self.__indent = self.__indent - \
814 self.indent_content_keywords[self.__keyword_list.pop()]
815
816 return res_lines
817
850
852 """Split a line if it is longer than self.line_length
853 columns. Split in preferential order according to
854 split_characters. Also fix spacing for line."""
855
856
857 comment = ""
858 if line.find(self.comment_char) > -1:
859 line, dum, comment = line.partition(self.comment_char)
860
861
862 quotes = self.quote_chars.finditer(line)
863
864 start_pos = 0
865 line_quotes = []
866 line_no_quotes = []
867 for i, quote in enumerate(quotes):
868 if i % 2 == 0:
869
870 line_no_quotes.append(line[start_pos:quote.start()])
871 start_pos = quote.start()
872 else:
873
874 line_quotes.append(line[start_pos:quote.end()])
875 start_pos = quote.end()
876
877 line_no_quotes.append(line[start_pos:])
878
879
880 line.rstrip()
881 for i, no_quote in enumerate(line_no_quotes):
882 for key in self.spacing_patterns:
883 no_quote = self.spacing_re[key[0]].sub(key[1], no_quote)
884 line_no_quotes[i] = no_quote
885
886
887 line = line_no_quotes[0]
888 for i in range(len(line_quotes)):
889 line += line_quotes[i]
890 if len(line_no_quotes) > i + 1:
891 line += line_no_quotes[i+1]
892
893
894 res_lines = [" " * self.__indent + line]
895
896 while len(res_lines[-1]) > self.line_length:
897 long_line = res_lines[-1]
898 split_at = -1
899 for character in split_characters:
900 index = long_line[(self.line_length - self.max_split): \
901 self.line_length].rfind(character)
902 if index >= 0:
903 split_at = self.line_length - self.max_split + index + 1
904 break
905
906
907 if split_at == -1:
908 split_at = len(long_line)
909 for character in split_characters:
910 split = long_line[self.line_length].find(character)
911 if split > 0:
912 split_at = min(split, split_at)
913 if split_at == len(long_line):
914 break
915
916
917 quotes = self.quote_chars.findall(long_line[:split_at])
918 if quotes and len(quotes) % 2 == 1:
919 quote_match = self.quote_chars.search(long_line[split_at:])
920 if not quote_match:
921 raise self.CPPWriterError(\
922 "Error: Unmatched quote in line " + long_line)
923 split_at = quote_match.end() + split_at + 1
924 split_match = re.search(self.split_characters,
925 long_line[split_at:])
926 if split_match:
927 split_at = split_at + split_match.start()
928 else:
929 split_at = len(long_line) + 1
930
931
932 if long_line[split_at:].lstrip():
933
934 res_lines[-1] = long_line[:split_at].rstrip()
935 res_lines.append(" " * \
936 (self.__indent + self.line_cont_indent) + \
937 long_line[split_at:].strip())
938 else:
939 break
940
941 if comment:
942 res_lines[-1] += " " + self.comment_char + comment
943
944 return res_lines
945
974
980
982
986
988 """Extends the regular file.writeline() function to write out
989 nicely formatted code"""
990
991 self.write(lines)
992