GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
pt-pr-code.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1996-2024 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include <cctype>
31 
32 #include "comment-list.h"
33 #include "error.h"
34 #include "ov-usr-fcn.h"
35 #include "pr-output.h"
36 #include "pt-all.h"
37 
39 
40 void
42 {
43  indent ();
44 
45  print_parens (afh, "(");
46 
47  m_os << "@";
48 
49  tree_parameter_list *param_list = afh.parameter_list ();
50 
51  if (param_list)
52  param_list->accept (*this);
53 
55 
56  print_parens (afh, ")");
57 }
58 
59 void
61 {
62  auto p = lst.begin ();
63 
64  while (p != lst.end ())
65  {
66  tree_expression *elt = *p++;
67 
68  if (elt)
69  {
70  elt->accept (*this);
71 
72  if (p != lst.end ())
73  m_os << ", ";
74  }
75  }
76 }
77 
78 void
80 {
81  indent ();
82 
83  // FIXME
84  m_os << "arguments ... endarguments";
85 }
86 
87 void
89 {
91 }
92 
93 void
95 {
97 }
98 
99 void
101 {
102  panic_impossible ();
103 }
104 
105 void
107 {
108  panic_impossible ();
109 }
110 
111 void
113 {
114  panic_impossible ();
115 }
116 
117 void
119 {
120  indent ();
121 
122  print_parens (expr, "(");
123 
124  tree_expression *op1 = expr.lhs ();
125 
126  if (op1)
127  op1->accept (*this);
128 
129  m_os << ' ' << expr.oper () << ' ';
130 
131  tree_expression *op2 = expr.rhs ();
132 
133  if (op2)
134  op2->accept (*this);
135 
136  print_parens (expr, ")");
137 }
138 
139 void
141 {
142  indent ();
143 
144  m_os << "break";
145 }
146 
147 void
149 {
150  indent ();
151 
152  print_parens (expr, "(");
153 
154  tree_expression *op1 = expr.base ();
155 
156  if (op1)
157  op1->accept (*this);
158 
159  // Stupid syntax.
160 
161  tree_expression *op3 = expr.increment ();
162 
163  if (op3)
164  {
165  m_os << ':';
166  op3->accept (*this);
167  }
168 
169  tree_expression *op2 = expr.limit ();
170 
171  if (op2)
172  {
173  m_os << ':';
174  op2->accept (*this);
175  }
176 
177  print_parens (expr, ")");
178 }
179 
180 void
182 {
183  indent ();
184 
185  m_os << "continue";
186 }
187 
188 void
190 {
191  indent ();
192 
193  m_os << cmd.name () << ' ';
194 
195  tree_decl_init_list *init_list = cmd.initializer_list ();
196 
197  if (init_list)
198  init_list->accept (*this);
199 }
200 
201 void
203 {
204  auto p = lst.begin ();
205 
206  while (p != lst.end ())
207  {
208  tree_decl_elt *elt = *p++;
209 
210  if (elt)
211  {
212  elt->accept (*this);
213 
214  if (p != lst.end ())
215  m_os << ", ";
216  }
217  }
218 }
219 
220 void
222 {
223  tree_identifier *id = cmd.ident ();
224 
225  if (id)
226  id->accept (*this);
227 
228  tree_expression *expr = cmd.expression ();
229 
230  if (expr)
231  {
232  m_os << " = ";
233 
234  expr->accept (*this);
235  }
236 }
237 
238 void
240 {
241  print_comment_list (cmd.leading_comment ());
242 
243  indent ();
244 
245  m_os << (cmd.in_parallel () ? "parfor " : "for ");
246 
247  tree_expression *lhs = cmd.left_hand_side ();
248 
249  tree_expression *maxproc = cmd.maxproc_expr ();
250 
251  if (maxproc)
252  m_os << '(';
253 
254  if (lhs)
255  lhs->accept (*this);
256 
257  m_os << " = ";
258 
259  tree_expression *expr = cmd.control_expr ();
260 
261  if (expr)
262  expr->accept (*this);
263 
264  if (maxproc)
265  {
266  m_os << ", ";
267  maxproc->accept (*this);
268  m_os << ')';
269  }
270 
271  newline ();
272 
273  tree_statement_list *list = cmd.body ();
274 
275  if (list)
276  {
277  increment_indent_level ();
278 
279  list->accept (*this);
280 
281  decrement_indent_level ();
282  }
283 
284  print_indented_comment (cmd.trailing_comment ());
285 
286  indent ();
287 
288  m_os << (cmd.in_parallel () ? "endparfor" : "endfor");
289 }
290 
291 void
293 {
294  print_comment_list (cmd.leading_comment ());
295 
296  indent ();
297 
298  m_os << "for [";
299  m_nesting.push ('[');
300 
301  tree_argument_list *lhs = cmd.left_hand_side ();
302 
303  if (lhs)
304  lhs->accept (*this);
305 
306  m_nesting.pop ();
307  m_os << "] = ";
308 
309  tree_expression *expr = cmd.control_expr ();
310 
311  if (expr)
312  expr->accept (*this);
313 
314  newline ();
315 
316  tree_statement_list *list = cmd.body ();
317 
318  if (list)
319  {
320  increment_indent_level ();
321 
322  list->accept (*this);
323 
324  decrement_indent_level ();
325  }
326 
327  print_indented_comment (cmd.trailing_comment ());
328 
329  indent ();
330 
331  m_os << "endfor";
332 }
333 
334 void
336 {
337  print_comment_list (cmd.leading_comment ());
338 
339  indent ();
340 
341  m_os << "spmd";
342 
343  newline ();
344 
345  tree_statement_list *list = cmd.body ();
346 
347  if (list)
348  {
349  increment_indent_level ();
350 
351  list->accept (*this);
352 
353  decrement_indent_level ();
354  }
355 
356  print_indented_comment (cmd.trailing_comment ());
357 
358  indent ();
359 
360  m_os << "endspmd";
361 }
362 
363 void
365 {
366  reset ();
367 
368  tree_statement_list *cmd_list = fcn.body ();
369 
370  if (cmd_list)
371  cmd_list->accept (*this);
372 }
373 
374 void
376 {
377  reset ();
378 
380 
381  tree_statement_list *cmd_list = fcn.body ();
382 
383  if (cmd_list)
384  {
385  increment_indent_level ();
386 
387  cmd_list->accept (*this);
388 
389  // endfunction will decrement the indent level.
390  }
391 
393 }
394 
395 void
397 {
398  comment_list *leading_comment = fcn.leading_comment ();
399 
400  if (leading_comment)
401  {
402  print_comment_list (leading_comment);
403  newline ();
404  }
405 
406  indent ();
407 
408  m_os << "function ";
409 
410  tree_parameter_list *ret_list = fcn.return_list ();
411 
412  if (ret_list)
413  {
414  ret_list->accept (*this);
415 
416  m_os << " = ";
417  }
418  std::string fcn_name = fcn.name ();
419 
420  m_os << (fcn_name.empty () ? "(empty)" : fcn_name) << ' ';
421 
422  tree_parameter_list *param_list = fcn.parameter_list ();
423 
424  if (param_list)
425  param_list->accept (*this);
426 
427  newline ();
428 }
429 
430 void
432 {
433  print_indented_comment (fcn.trailing_comment ());
434 
435  newline ();
436 }
437 
438 void
440 {
441  indent ();
442 
443  octave_value fcn = fdef.function ();
444 
445  octave_function *f = fcn.function_value ();
446 
447  if (f)
448  f->accept (*this);
449 }
450 
451 void
453 {
454  indent ();
455 
456  print_parens (id, "(");
457 
458  std::string nm = id.name ();
459  m_os << (nm.empty () ? "(empty)" : nm);
460 
461  print_parens (id, ")");
462 }
463 
464 void
466 {
467  tree_expression *expr = cmd.condition ();
468 
469  if (expr)
470  expr->accept (*this);
471 
472  newline ();
473 
474  tree_statement_list *list = cmd.commands ();
475 
476  if (list)
477  {
478  increment_indent_level ();
479 
480  list->accept (*this);
481 
482  decrement_indent_level ();
483  }
484 }
485 
486 void
488 {
489  print_comment_list (cmd.leading_comment ());
490 
491  indent ();
492 
493  m_os << "if ";
494 
495  tree_if_command_list *list = cmd.cmd_list ();
496 
497  if (list)
498  list->accept (*this);
499 
500  print_indented_comment (cmd.trailing_comment ());
501 
502  indent ();
503 
504  m_os << "endif";
505 }
506 
507 void
509 {
510  auto p = lst.begin ();
511 
512  bool first_elt = true;
513 
514  while (p != lst.end ())
515  {
516  tree_if_clause *elt = *p++;
517 
518  if (elt)
519  {
520  if (! first_elt)
521  {
522  print_indented_comment (elt->leading_comment ());
523 
524  indent ();
525 
526  if (elt->is_else_clause ())
527  m_os << "else";
528  else
529  m_os << "elseif ";
530  }
531 
532  elt->accept (*this);
533  }
534 
535  first_elt = false;
536  }
537 }
538 
539 void
541 {
542  indent ();
543 
544  print_parens (expr, "(");
545 
546  tree_expression *e = expr.expression ();
547 
548  if (e)
549  e->accept (*this);
550 
551  std::list<tree_argument_list *> arg_lists = expr.arg_lists ();
552  std::string type_tags = expr.type_tags ();
553  std::list<string_vector> arg_names = expr.arg_names ();
554  std::list<tree_expression *> dyn_fields = expr.dyn_fields ();
555 
556  int n = type_tags.length ();
557 
558  auto p_arg_lists = arg_lists.begin ();
559  auto p_arg_names = arg_names.begin ();
560  auto p_dyn_fields = dyn_fields.begin ();
561 
562  for (int i = 0; i < n; i++)
563  {
564  switch (type_tags[i])
565  {
566  case '(':
567  {
568  char nc = m_nesting.top ();
569  if ((nc == '[' || nc == '{') && expr.paren_count () == 0)
570  m_os << '(';
571  else
572  m_os << " (";
573  m_nesting.push ('(');
574 
575  tree_argument_list *l = *p_arg_lists;
576  if (l)
577  l->accept (*this);
578 
579  m_nesting.pop ();
580  m_os << ')';
581  }
582  break;
583 
584  case '{':
585  {
586  char nc = m_nesting.top ();
587  if ((nc == '[' || nc == '{') && expr.paren_count () == 0)
588  m_os << '{';
589  else
590  m_os << " {";
591  // We only care about whitespace inside [] and {} when we
592  // are defining matrix and cell objects, not when indexing.
593  m_nesting.push ('(');
594 
595  tree_argument_list *l = *p_arg_lists;
596  if (l)
597  l->accept (*this);
598 
599  m_nesting.pop ();
600  m_os << '}';
601  }
602  break;
603 
604  case '.':
605  {
606  std::string fn = (*p_arg_names)(0);
607  if (fn.empty ())
608  {
609  tree_expression *df = *p_dyn_fields;
610 
611  if (df)
612  {
613  m_nesting.push ('(');
614  m_os << ".(";
615  df->accept (*this);
616  m_os << ")";
617  m_nesting.pop ();
618  }
619  }
620  else
621  m_os << '.' << fn;
622  }
623  break;
624 
625  default:
626  panic_impossible ();
627  }
628 
629  p_arg_lists++;
630  p_arg_names++;
631  p_dyn_fields++;
632  }
633 
634  print_parens (expr, ")");
635 }
636 
637 void
639 {
640  indent ();
641 
642  print_parens (lst, "(");
643 
644  m_os << '[';
645  m_nesting.push ('[');
646 
647  auto p = lst.begin ();
648 
649  while (p != lst.end ())
650  {
651  tree_argument_list *elt = *p++;
652 
653  if (elt)
654  {
655  elt->accept (*this);
656 
657  if (p != lst.end ())
658  m_os << "; ";
659  }
660  }
661 
662  m_nesting.pop ();
663  m_os << ']';
664 
665  print_parens (lst, ")");
666 }
667 
668 void
670 {
671  indent ();
672 
673  print_parens (lst, "(");
674 
675  m_os << '{';
676  m_nesting.push ('{');
677 
678  auto p = lst.begin ();
679 
680  while (p != lst.end ())
681  {
682  tree_argument_list *elt = *p++;
683 
684  if (elt)
685  {
686  elt->accept (*this);
687 
688  if (p != lst.end ())
689  m_os << "; ";
690  }
691  }
692 
693  m_nesting.pop ();
694  m_os << '}';
695 
696  print_parens (lst, ")");
697 }
698 
699 void
701 {
702  indent ();
703 
704  print_parens (expr, "(");
705 
706  tree_argument_list *lhs = expr.left_hand_side ();
707 
708  if (lhs)
709  {
710  int len = lhs->length ();
711 
712  if (len > 1)
713  {
714  m_os << '[';
715  m_nesting.push ('[');
716  }
717 
718  lhs->accept (*this);
719 
720  if (len > 1)
721  {
722  m_nesting.pop ();
723  m_os << ']';
724  }
725  }
726 
727  m_os << ' ' << expr.oper () << ' ';
728 
729  tree_expression *rhs = expr.right_hand_side ();
730 
731  if (rhs)
732  rhs->accept (*this);
733 
734  print_parens (expr, ")");
735 }
736 
737 void
739 {
740  if (cmd.is_end_of_fcn_or_script () && m_curr_print_indent_level > 1)
741  decrement_indent_level ();
742 
743  indent ();
744 
745  m_os << cmd.original_command ();
746 }
747 
748 void
750 {
751  indent ();
752 
753  print_parens (val, "(");
754 
755  val.print_raw (m_os, true, m_print_original_text);
756 
757  print_parens (val, ")");
758 }
759 
760 void
762 {
763  indent ();
764 
765  print_parens (fh, "(");
766 
767  fh.print_raw (m_os, true, m_print_original_text);
768 
769  print_parens (fh, ")");
770 }
771 
772 void
774 {
775  bool is_input_list = lst.is_input_list ();
776 
777  if (is_input_list)
778  {
779  m_os << '(';
780  m_nesting.push ('(');
781  }
782  else
783  {
784  int len = lst.length ();
785  if (lst.takes_varargs ())
786  len++;
787 
788  if (len != 1)
789  {
790  m_os << '[';
791  m_nesting.push ('[');
792  }
793  }
794 
795  auto p = lst.begin ();
796 
797  while (p != lst.end ())
798  {
799  tree_decl_elt *elt = *p++;
800 
801  if (elt)
802  {
803  elt->accept (*this);
804 
805  if (p != lst.end () || lst.takes_varargs ())
806  m_os << ", ";
807  }
808  }
809 
810  if (lst.takes_varargs ())
811  m_os << lst.varargs_symbol_name ();
812 
813  if (is_input_list)
814  {
815  m_nesting.pop ();
816  m_os << ')';
817  }
818  else
819  {
820  int len = lst.length ();
821  if (lst.takes_varargs ())
822  len++;
823 
824  if (len != 1)
825  {
826  m_nesting.pop ();
827  m_os << ']';
828  }
829  }
830 }
831 
832 void
834 {
835  indent ();
836 
837  print_parens (expr, "(");
838 
839  tree_expression *e = expr.operand ();
840 
841  if (e)
842  e->accept (*this);
843 
844  m_os << expr.oper ();
845 
846  print_parens (expr, ")");
847 }
848 
849 void
851 {
852  indent ();
853 
854  print_parens (expr, "(");
855 
856  m_os << expr.oper ();
857 
858  tree_expression *e = expr.operand ();
859 
860  if (e)
861  e->accept (*this);
862 
863  print_parens (expr, ")");
864 }
865 
866 void
868 {
869  indent ();
870 
871  m_os << "return";
872 }
873 
874 void
876 {
877  indent ();
878 
879  print_parens (expr, "(");
880 
881  tree_expression *lhs = expr.left_hand_side ();
882 
883  if (lhs)
884  lhs->accept (*this);
885 
886  m_os << ' ' << expr.oper () << ' ';
887 
888  tree_expression *rhs = expr.right_hand_side ();
889 
890  if (rhs)
891  rhs->accept (*this);
892 
893  print_parens (expr, ")");
894 }
895 
896 void
898 {
899  print_comment_list (stmt.comment_text ());
900 
901  tree_command *cmd = stmt.command ();
902 
903  if (cmd)
904  {
905  cmd->accept (*this);
906 
907  newline ();
908  }
909  else
910  {
911  tree_expression *expr = stmt.expression ();
912 
913  if (expr)
914  {
915  expr->accept (*this);
916 
917  if (! stmt.print_result ())
918  {
919  m_os << ';';
920  newline (" ");
921  }
922  else
923  newline ();
924  }
925  }
926 }
927 
928 void
930 {
931  for (tree_statement *elt : lst)
932  {
933  if (elt)
934  elt->accept (*this);
935  }
936 }
937 
938 void
940 {
941  print_comment_list (cs.leading_comment ());
942 
943  indent ();
944 
945  if (cs.is_default_case ())
946  m_os << "otherwise";
947  else
948  m_os << "case ";
949 
950  tree_expression *label = cs.case_label ();
951 
952  if (label)
953  label->accept (*this);
954 
955  newline ();
956 
957  tree_statement_list *list = cs.commands ();
958 
959  if (list)
960  {
961  increment_indent_level ();
962 
963  list->accept (*this);
964 
965  newline ();
966 
967  decrement_indent_level ();
968  }
969 }
970 
971 void
973 {
974  print_comment_list (cmd.leading_comment ());
975 
976  indent ();
977 
978  m_os << "switch ";
979 
980  tree_expression *expr = cmd.switch_value ();
981 
982  if (expr)
983  expr->accept (*this);
984 
985  newline ();
986 
987  tree_switch_case_list *list = cmd.case_list ();
988 
989  if (list)
990  {
991  increment_indent_level ();
992 
993  list->accept (*this);
994 
995  decrement_indent_level ();
996  }
997 
998  print_indented_comment (cmd.leading_comment ());
999 
1000  indent ();
1001 
1002  m_os << "endswitch";
1003 }
1004 
1005 void
1007 {
1008  print_comment_list (cmd.leading_comment ());
1009 
1010  indent ();
1011 
1012  m_os << "try";
1013 
1014  newline ();
1015 
1016  tree_statement_list *try_code = cmd.body ();
1017  tree_identifier *expr_id = cmd.identifier ();
1018 
1019  if (try_code)
1020  {
1021  increment_indent_level ();
1022 
1023  try_code->accept (*this);
1024 
1025  decrement_indent_level ();
1026  }
1027 
1028  print_indented_comment (cmd.middle_comment ());
1029 
1030  indent ();
1031 
1032  m_os << "catch";
1033 
1034  if (expr_id)
1035  {
1036  m_os << ' ';
1037  expr_id->accept (*this);
1038  }
1039 
1040  newline ();
1041 
1042  tree_statement_list *catch_code = cmd.cleanup ();
1043 
1044  if (catch_code)
1045  {
1046  increment_indent_level ();
1047 
1048  catch_code->accept (*this);
1049 
1050  decrement_indent_level ();
1051  }
1052 
1053  print_indented_comment (cmd.trailing_comment ());
1054 
1055  indent ();
1056 
1057  m_os << "end_try_catch";
1058 }
1059 
1060 void
1062 {
1063  print_comment_list (cmd.leading_comment ());
1064 
1065  indent ();
1066 
1067  m_os << "unwind_protect";
1068 
1069  newline ();
1070 
1071  tree_statement_list *unwind_protect_code = cmd.body ();
1072 
1073  if (unwind_protect_code)
1074  {
1075  increment_indent_level ();
1076 
1077  unwind_protect_code->accept (*this);
1078 
1079  decrement_indent_level ();
1080  }
1081 
1082  print_indented_comment (cmd.middle_comment ());
1083 
1084  indent ();
1085 
1086  m_os << "unwind_protect_cleanup";
1087 
1088  newline ();
1089 
1090  tree_statement_list *cleanup_code = cmd.cleanup ();
1091 
1092  if (cleanup_code)
1093  {
1094  increment_indent_level ();
1095 
1096  cleanup_code->accept (*this);
1097 
1098  decrement_indent_level ();
1099  }
1100 
1101  print_indented_comment (cmd.trailing_comment ());
1102 
1103  indent ();
1104 
1105  m_os << "end_unwind_protect";
1106 }
1107 
1108 void
1110 {
1111  print_comment_list (cmd.leading_comment ());
1112 
1113  indent ();
1114 
1115  m_os << "while ";
1116 
1117  tree_expression *expr = cmd.condition ();
1118 
1119  if (expr)
1120  expr->accept (*this);
1121 
1122  newline ();
1123 
1124  tree_statement_list *list = cmd.body ();
1125 
1126  if (list)
1127  {
1128  increment_indent_level ();
1129 
1130  list->accept (*this);
1131 
1132  decrement_indent_level ();
1133  }
1134 
1135  print_indented_comment (cmd.trailing_comment ());
1136 
1137  indent ();
1138 
1139  m_os << "endwhile";
1140 }
1141 
1142 void
1144 {
1145  print_comment_list (cmd.leading_comment ());
1146 
1147  indent ();
1148 
1149  m_os << "do";
1150 
1151  newline ();
1152 
1153  tree_statement_list *list = cmd.body ();
1154 
1155  if (list)
1156  {
1157  increment_indent_level ();
1158 
1159  list->accept (*this);
1160 
1161  decrement_indent_level ();
1162  }
1163 
1164  print_indented_comment (cmd.trailing_comment ());
1165 
1166  indent ();
1167 
1168  m_os << "until ";
1169 
1170  tree_expression *expr = cmd.condition ();
1171 
1172  if (expr)
1173  expr->accept (*this);
1174 
1175  newline ();
1176 }
1177 
1178 void
1180 {
1181  m_os << scr.method_name () << "@" << scr.class_name ();
1182 }
1183 
1184 void
1186 {
1187  m_os << "?" << mcq.class_name ();
1188 }
1189 
1190 void
1192 {
1193  if (e)
1194  {
1195  m_suppress_newlines++;
1196  e->accept (*this);
1197  m_suppress_newlines--;
1198  }
1199 }
1200 
1201 // Each print_code() function should call this before printing anything.
1202 
1203 void
1204 tree_print_code::indent ()
1205 {
1206  panic_unless (m_curr_print_indent_level >= 0);
1207 
1208  if (m_beginning_of_line)
1209  {
1210  m_os << m_prefix;
1211 
1212  m_os << std::string (m_curr_print_indent_level, ' ');
1213 
1214  m_beginning_of_line = false;
1215  }
1216 }
1217 
1218 // All print_code() functions should use this to print new lines.
1219 
1220 void
1221 tree_print_code::newline (const char *alt_txt)
1222 {
1223  if (m_suppress_newlines)
1224  m_os << alt_txt;
1225  else
1226  {
1227  // Print prefix for blank lines.
1228  indent ();
1229 
1230  m_os << "\n";
1231 
1232  m_beginning_of_line = true;
1233  }
1234 }
1235 
1236 // For resetting print_code state.
1237 
1238 void
1239 tree_print_code::reset ()
1240 {
1241  m_beginning_of_line = true;
1242  m_curr_print_indent_level = 0;
1243  while (m_nesting.top () != 'n')
1244  m_nesting.pop ();
1245 }
1246 
1247 void
1248 tree_print_code::print_parens (const tree_expression& expr, const char *txt)
1249 {
1250  int n = expr.paren_count ();
1251 
1252  for (int i = 0; i < n; i++)
1253  m_os << txt;
1254 }
1255 
1256 void
1257 tree_print_code::print_comment_elt (const comment_elt& elt)
1258 {
1259  bool printed_something = false;
1260 
1261  bool prev_char_was_newline = false;
1262 
1263  std::string comment = elt.text ();
1264 
1265  std::size_t len = comment.length ();
1266 
1267  std::size_t i = 0;
1268 
1269  while (i < len && comment[i++] == '\n')
1270  ; // Skip leading new lines.
1271  i--;
1272 
1273  while (i < len)
1274  {
1275  char c = comment[i++];
1276 
1277  if (c == '\n')
1278  {
1279  if (prev_char_was_newline)
1280  {
1281  printed_something = true;
1282 
1283  indent ();
1284 
1285  m_os << "##";
1286  }
1287 
1288  newline ();
1289 
1290  prev_char_was_newline = true;
1291  }
1292  else
1293  {
1294  if (m_beginning_of_line)
1295  {
1296  printed_something = true;
1297 
1298  indent ();
1299 
1300  m_os << "##";
1301 
1302  if (! (isspace (c) || c == '!'))
1303  m_os << ' ';
1304  }
1305 
1306  m_os << static_cast<char> (c);
1307 
1308  prev_char_was_newline = false;
1309  }
1310  }
1311 
1312  if (printed_something && ! m_beginning_of_line)
1313  newline ();
1314 }
1315 
1316 void
1317 tree_print_code::print_comment_list (comment_list *comment_list)
1318 {
1319  if (comment_list)
1320  {
1321  auto p = comment_list->begin ();
1322 
1323  while (p != comment_list->end ())
1324  {
1325  comment_elt elt = *p++;
1326 
1327  print_comment_elt (elt);
1328 
1329  if (p != comment_list->end ())
1330  newline ();
1331  }
1332  }
1333 }
1334 
1335 void
1336 tree_print_code::print_indented_comment (comment_list *comment_list)
1337 {
1338  increment_indent_level ();
1339 
1340  print_comment_list (comment_list);
1341 
1342  decrement_indent_level ();
1343 }
1344 
1345 OCTAVE_END_NAMESPACE(octave)
std::size_t length() const
Definition: base-list.h:53
iterator end()
Definition: base-list.h:68
iterator begin()
Definition: base-list.h:65
std::string text() const
Definition: comment-list.h:78
std::string name() const
Definition: ov-fcn.h:206
octave::tree_statement_list * body()
Definition: ov-usr-fcn.h:118
octave::comment_list * trailing_comment()
Definition: ov-usr-fcn.h:390
octave::comment_list * leading_comment()
Definition: ov-usr-fcn.h:388
octave::tree_parameter_list * parameter_list()
Definition: ov-usr-fcn.h:384
octave::tree_parameter_list * return_list()
Definition: ov-usr-fcn.h:386
octave_function * function_value(bool silent=false) const
tree_parameter_list * parameter_list() const
tree_expression * expression() const
void accept(tree_walker &tw)
Definition: pt-arg-list.h:102
tree_expression * lhs()
Definition: pt-binop.h:86
tree_expression * rhs()
Definition: pt-binop.h:87
std::string oper() const
Definition: pt-binop.cc:51
tree_expression * limit()
Definition: pt-colon.h:82
tree_expression * base()
Definition: pt-colon.h:80
tree_expression * increment()
Definition: pt-colon.h:84
comment_list * trailing_comment()
Definition: pt-loop.h:237
tree_statement_list * body()
Definition: pt-loop.h:233
tree_argument_list * left_hand_side()
Definition: pt-loop.h:229
tree_expression * control_expr()
Definition: pt-loop.h:231
comment_list * leading_comment()
Definition: pt-loop.h:235
void print_raw(std::ostream &os, bool pr_as_read_syntax=false, bool pr_orig_txt=true)
Definition: pt-const.cc:54
tree_decl_init_list * initializer_list()
Definition: pt-decl.h:189
std::string name() const
Definition: pt-decl.h:191
void accept(tree_walker &tw)
Definition: pt-decl.h:92
tree_identifier * ident()
Definition: pt-decl.h:84
tree_expression * expression()
Definition: pt-decl.h:88
void accept(tree_walker &tw)
Definition: pt-decl.h:155
int paren_count() const
Definition: pt-exp.h:88
void print_raw(std::ostream &os, bool pr_as_read_syntax=false, bool pr_orig_txt=true)
octave_value function()
Definition: pt-cmd.h:107
void accept(tree_walker &tw)
Definition: pt-id.h:101
void accept(tree_walker &tw)
Definition: pt-select.h:72
tree_expression * condition()
Definition: pt-select.h:66
bool is_else_clause()
Definition: pt-select.h:64
tree_statement_list * commands()
Definition: pt-select.h:68
comment_list * leading_comment()
Definition: pt-select.h:70
void accept(tree_walker &tw)
Definition: pt-select.h:109
comment_list * trailing_comment()
Definition: pt-select.h:137
tree_if_command_list * cmd_list()
Definition: pt-select.h:133
comment_list * leading_comment()
Definition: pt-select.h:135
tree_expression * expression()
Definition: pt-idx.h:80
std::string type_tags()
Definition: pt-idx.h:84
std::list< tree_argument_list * > arg_lists()
Definition: pt-idx.h:82
std::list< string_vector > arg_names()
Definition: pt-idx.h:86
std::list< tree_expression * > dyn_fields()
Definition: pt-idx.h:88
std::string class_name() const
Definition: pt-classdef.h:108
tree_argument_list * left_hand_side()
Definition: pt-assign.h:140
std::string oper() const
Definition: pt-assign.cc:171
tree_expression * right_hand_side()
Definition: pt-assign.h:142
std::string original_command()
Definition: pt-cmd.h:80
bool is_end_of_fcn_or_script() const
Definition: pt-cmd.h:73
void accept(tree_walker &tw)
Definition: pt-misc.h:98
bool takes_varargs() const
Definition: pt-misc.h:81
bool is_input_list() const
Definition: pt-misc.h:85
std::string varargs_symbol_name() const
Definition: pt-misc.h:91
void visit_binary_expression(tree_binary_expression &)
Definition: pt-pr-code.cc:118
void visit_continue_command(tree_continue_command &)
Definition: pt-pr-code.cc:181
void visit_switch_case(tree_switch_case &)
Definition: pt-pr-code.cc:939
void visit_decl_init_list(tree_decl_init_list &)
Definition: pt-pr-code.cc:202
void visit_constant(tree_constant &)
Definition: pt-pr-code.cc:749
void visit_postfix_expression(tree_postfix_expression &)
Definition: pt-pr-code.cc:833
void visit_superclass_ref(tree_superclass_ref &)
Definition: pt-pr-code.cc:1179
void visit_no_op_command(tree_no_op_command &)
Definition: pt-pr-code.cc:738
void visit_args_block_attribute_list(tree_args_block_attribute_list &)
Definition: pt-pr-code.cc:88
void visit_while_command(tree_while_command &)
Definition: pt-pr-code.cc:1109
void visit_fcn_handle(tree_fcn_handle &)
Definition: pt-pr-code.cc:761
void visit_arguments_block(tree_arguments_block &)
Definition: pt-pr-code.cc:79
void visit_switch_command(tree_switch_command &)
Definition: pt-pr-code.cc:972
void visit_prefix_expression(tree_prefix_expression &)
Definition: pt-pr-code.cc:850
void visit_octave_user_function_header(octave_user_function &)
Definition: pt-pr-code.cc:396
void visit_simple_assignment(tree_simple_assignment &)
Definition: pt-pr-code.cc:875
void visit_decl_command(tree_decl_command &)
Definition: pt-pr-code.cc:189
void visit_if_clause(tree_if_clause &)
Definition: pt-pr-code.cc:465
void visit_index_expression(tree_index_expression &)
Definition: pt-pr-code.cc:540
void print_fcn_handle_body(tree_expression *)
Definition: pt-pr-code.cc:1191
void visit_statement(tree_statement &)
Definition: pt-pr-code.cc:897
void visit_break_command(tree_break_command &)
Definition: pt-pr-code.cc:140
void visit_return_command(tree_return_command &)
Definition: pt-pr-code.cc:867
void visit_if_command(tree_if_command &)
Definition: pt-pr-code.cc:487
void visit_unwind_protect_command(tree_unwind_protect_command &)
Definition: pt-pr-code.cc:1061
void visit_identifier(tree_identifier &)
Definition: pt-pr-code.cc:452
void visit_complex_for_command(tree_complex_for_command &)
Definition: pt-pr-code.cc:292
void visit_multi_assignment(tree_multi_assignment &)
Definition: pt-pr-code.cc:700
void visit_matrix(tree_matrix &)
Definition: pt-pr-code.cc:638
void visit_if_command_list(tree_if_command_list &)
Definition: pt-pr-code.cc:508
void visit_try_catch_command(tree_try_catch_command &)
Definition: pt-pr-code.cc:1006
void visit_do_until_command(tree_do_until_command &)
Definition: pt-pr-code.cc:1143
void visit_arg_validation(tree_arg_validation &)
Definition: pt-pr-code.cc:100
void visit_octave_user_function(octave_user_function &)
Definition: pt-pr-code.cc:375
void visit_parameter_list(tree_parameter_list &)
Definition: pt-pr-code.cc:773
void visit_statement_list(tree_statement_list &)
Definition: pt-pr-code.cc:929
void visit_spmd_command(tree_spmd_command &)
Definition: pt-pr-code.cc:335
void visit_decl_elt(tree_decl_elt &)
Definition: pt-pr-code.cc:221
void visit_args_block_validation_list(tree_args_block_validation_list &)
Definition: pt-pr-code.cc:94
void visit_arg_size_spec(tree_arg_size_spec &)
Definition: pt-pr-code.cc:106
void visit_simple_for_command(tree_simple_for_command &)
Definition: pt-pr-code.cc:239
void visit_anon_fcn_handle(tree_anon_fcn_handle &)
Definition: pt-pr-code.cc:41
void visit_argument_list(tree_argument_list &)
Definition: pt-pr-code.cc:60
void visit_colon_expression(tree_colon_expression &)
Definition: pt-pr-code.cc:148
void visit_octave_user_script(octave_user_script &)
Definition: pt-pr-code.cc:364
void visit_arg_validation_fcns(tree_arg_validation_fcns &)
Definition: pt-pr-code.cc:112
void visit_cell(tree_cell &)
Definition: pt-pr-code.cc:669
void visit_octave_user_function_trailer(octave_user_function &)
Definition: pt-pr-code.cc:431
void visit_metaclass_query(tree_metaclass_query &)
Definition: pt-pr-code.cc:1185
void visit_function_def(tree_function_def &)
Definition: pt-pr-code.cc:439
std::string oper() const
Definition: pt-assign.cc:60
tree_expression * left_hand_side()
Definition: pt-assign.h:73
tree_expression * right_hand_side()
Definition: pt-assign.h:75
comment_list * leading_comment()
Definition: pt-loop.h:173
comment_list * trailing_comment()
Definition: pt-loop.h:175
tree_expression * left_hand_side()
Definition: pt-loop.h:165
tree_expression * control_expr()
Definition: pt-loop.h:167
tree_expression * maxproc_expr()
Definition: pt-loop.h:169
tree_statement_list * body()
Definition: pt-loop.h:171
comment_list * trailing_comment()
Definition: pt-spmd.h:59
comment_list * leading_comment()
Definition: pt-spmd.h:57
tree_statement_list * body()
Definition: pt-spmd.h:55
void accept(tree_walker &tw)
Definition: pt-stmt.h:191
tree_command * command()
Definition: pt-stmt.h:95
comment_list * comment_text()
Definition: pt-stmt.h:99
tree_expression * expression()
Definition: pt-stmt.h:97
bool print_result()
Definition: pt-stmt.cc:71
std::string method_name() const
Definition: pt-classdef.h:62
std::string class_name() const
Definition: pt-classdef.h:67
void accept(tree_walker &tw)
Definition: pt-select.h:224
comment_list * leading_comment()
Definition: pt-select.h:185
tree_statement_list * commands()
Definition: pt-select.h:183
bool is_default_case()
Definition: pt-select.h:179
tree_expression * case_label()
Definition: pt-select.h:181
tree_switch_case_list * case_list()
Definition: pt-select.h:250
comment_list * leading_comment()
Definition: pt-select.h:252
tree_expression * switch_value()
Definition: pt-select.h:248
tree_statement_list * cleanup()
Definition: pt-except.h:70
tree_identifier * identifier()
Definition: pt-except.h:66
tree_statement_list * body()
Definition: pt-except.h:68
comment_list * trailing_comment()
Definition: pt-except.h:76
comment_list * middle_comment()
Definition: pt-except.h:74
comment_list * leading_comment()
Definition: pt-except.h:72
tree_expression * operand()
Definition: pt-unop.h:68
std::string oper() const
Definition: pt-unop.cc:40
comment_list * middle_comment()
Definition: pt-except.h:136
comment_list * trailing_comment()
Definition: pt-except.h:138
comment_list * leading_comment()
Definition: pt-except.h:134
tree_statement_list * cleanup()
Definition: pt-except.h:132
tree_statement_list * body()
Definition: pt-except.h:130
tree_statement_list * body()
Definition: pt-loop.h:75
tree_expression * condition()
Definition: pt-loop.h:73
comment_list * trailing_comment()
Definition: pt-loop.h:79
comment_list * leading_comment()
Definition: pt-loop.h:77
virtual void accept(tree_walker &tw)=0
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#define panic_impossible()
Definition: error.h:503
#define panic_unless(cond)
Definition: error.h:515
F77_RET_T const F77_DBLE const F77_DBLE * f
octave_idx_type n
Definition: mx-inlines.cc:761
F77_RET_T len
Definition: xerbla.cc:61