PageRenderTime 52ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/src/indent.cpp

http://github.com/bengardner/uncrustify
C++ | 2578 lines | 2004 code | 207 blank | 367 comment | 778 complexity | 4fd4b0bed4443a2860dc50a7a61c4f71 MD5 | raw file
Possible License(s): GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. /**
  2. * @file indent.cpp
  3. * Does all the indenting stuff.
  4. *
  5. * @author Ben Gardner
  6. * @author Guy Maurel since version 0.62 for uncrustify4Qt
  7. * October 2015, 2016
  8. * @license GPL v2+
  9. */
  10. #include "indent.h"
  11. #include "uncrustify_types.h"
  12. #include "chunk_list.h"
  13. #include "prototypes.h"
  14. #include "options_for_QT.h"
  15. #include <cstdio>
  16. #include <cstdlib>
  17. #include <cstring>
  18. #include "unc_ctype.h"
  19. #include "uncrustify.h"
  20. #include "align.h"
  21. #include "space.h"
  22. #include "parse_frame.h"
  23. /**
  24. * General indenting approach:
  25. * Indenting levels are put into a stack.
  26. *
  27. * The stack entries contain:
  28. * - opening type
  29. * - brace column
  30. * - continuation column
  31. *
  32. * Items that start a new stack item:
  33. * - preprocessor (new parse frame)
  34. * - Brace Open (Virtual brace also)
  35. * - Paren, Square, Angle open
  36. * - Assignments
  37. * - C++ '<<' operator (ie, cout << "blah")
  38. * - case
  39. * - class colon
  40. * - return
  41. * - types
  42. * - any other continued statement
  43. *
  44. * Note that the column of items marked 'PCF_WAS_ALIGNED' is not changed.
  45. *
  46. * For an open brace:
  47. * - indent increases by indent_columns
  48. * - if part of if/else/do/while/switch/etc, an extra indent may be applied
  49. * - if in a paren, then cont-col is set to column + 1, ie "({ some code })"
  50. *
  51. * Open paren/square/angle:
  52. * cont-col is set to the column of the item after the open paren, unless
  53. * followed by a newline, then it is set to (brace-col + indent_columns).
  54. * Examples:
  55. * a_really_long_funcion_name(
  56. * param1, param2);
  57. * a_really_long_funcion_name(param1,
  58. * param2);
  59. *
  60. * Assignments:
  61. * Assignments are continued aligned with the first item after the assignment,
  62. * unless the assign is followed by a newline.
  63. * Examples:
  64. * some.variable = asdf + asdf +
  65. * asdf;
  66. * some.variable =
  67. * asdf + asdf + asdf;
  68. *
  69. * C++ << operator:
  70. * Handled the same as assignment.
  71. * Examples:
  72. * cout << "this is test number: "
  73. * << test_number;
  74. *
  75. * case:
  76. * Started with case or default.
  77. * Terminated with close brace at level or another case or default.
  78. * Special indenting according to various rules.
  79. * - indent of case label
  80. * - indent of case body
  81. * - how to handle optional braces
  82. * Examples:
  83. * {
  84. * case x: {
  85. * a++;
  86. * break;
  87. * }
  88. * case y:
  89. * b--;
  90. * break;
  91. * default:
  92. * c++;
  93. * break;
  94. * }
  95. *
  96. * Class colon:
  97. * Indent continuation by indent_columns:
  98. * class my_class :
  99. * baseclass1,
  100. * baseclass2
  101. * {
  102. *
  103. * Return: same as assignments
  104. * If the return statement is not fully paren'd, then the indent continues at
  105. * the column of the item after the return. If it is paren'd, then the paren
  106. * rules apply.
  107. * return somevalue +
  108. * othervalue;
  109. *
  110. * Type: pretty much the same as assignments
  111. * Examples:
  112. * int foo,
  113. * bar,
  114. * baz;
  115. *
  116. * Any other continued item:
  117. * There shouldn't be anything not covered by the above cases, but any other
  118. * continued item is indented by indent_columns:
  119. * Example:
  120. * somereallycrazylongname.with[lotsoflongstuff].
  121. * thatreallyannoysme.whenIhavetomaintain[thecode] = 3;
  122. */
  123. /**
  124. * REVISIT: This needs to be re-checked, maybe cleaned up
  125. *
  126. * Indents comments in a (hopefully) smart manner.
  127. *
  128. * There are two type of comments that get indented:
  129. * - stand alone (ie, no tokens on the line before the comment)
  130. * - trailing comments (last token on the line apart from a linefeed)
  131. * + note that a stand-alone comment is a special case of a trailing
  132. *
  133. * The stand alone comments will get indented in one of three ways:
  134. * - column 1:
  135. * + There is an empty line before the comment AND the indent level is 0
  136. * + The comment was originally in column 1
  137. *
  138. * - Same column as trailing comment on previous line (ie, aligned)
  139. * + if originally within TBD (3) columns of the previous comment
  140. *
  141. * - syntax indent level
  142. * + doesn't fit in the previous categories
  143. *
  144. * Options modify this behavior:
  145. * - keep original column (don't move the comment, if possible)
  146. * - keep relative column (move out the same amount as first item on line)
  147. * - fix trailing comment in column TBD
  148. *
  149. * @param pc The comment, which is the first item on a line
  150. * @param col The column if this is to be put at indent level
  151. */
  152. static void indent_comment(chunk_t *pc, size_t col);
  153. /**
  154. * Starts a new entry
  155. *
  156. * @param frm The parse frame
  157. * @param pc The chunk causing the push
  158. */
  159. static void indent_pse_push(parse_frame_t &frm, chunk_t *pc);
  160. /**
  161. * Removes the top entry
  162. *
  163. * @param frm The parse frame
  164. * @param pc The chunk causing the push
  165. */
  166. static void indent_pse_pop(parse_frame_t &frm, chunk_t *pc);
  167. static size_t token_indent(c_token_t type);
  168. static int calc_indent_continue(parse_frame_t &frm, int pse_tos);
  169. /**
  170. * We are on a '{' that has parent = OC_BLOCK_EXPR
  171. * find the column of the param tag
  172. */
  173. static chunk_t *oc_msg_block_indent(chunk_t *pc, bool from_brace, bool from_caret, bool from_colon, bool from_keyword);
  174. /**
  175. * We are on a '{' that has parent = OC_BLOCK_EXPR
  176. */
  177. static chunk_t *oc_msg_prev_colon(chunk_t *pc);
  178. /**
  179. * returns true if forward scan reveals only single newlines or comments
  180. * stops when hits code
  181. * false if next thing hit is a closing brace, also if 2 newlines in a row
  182. */
  183. static bool single_line_comment_indent_rule_applies(chunk_t *start);
  184. void indent_to_column(chunk_t *pc, size_t column)
  185. {
  186. LOG_FUNC_ENTRY();
  187. if (column < pc->column)
  188. {
  189. column = pc->column;
  190. }
  191. reindent_line(pc, column);
  192. }
  193. enum align_mode
  194. {
  195. ALMODE_SHIFT, /* shift relative to the current column */
  196. ALMODE_KEEP_ABS, /* try to keep the original absolute column */
  197. ALMODE_KEEP_REL, /* try to keep the original gap */
  198. };
  199. void align_to_column(chunk_t *pc, size_t column)
  200. {
  201. LOG_FUNC_ENTRY();
  202. if (column == pc->column)
  203. {
  204. return;
  205. }
  206. LOG_FMT(LINDLINE, "%s(%d): %zu] col %zu on %s [%s] => %zu\n",
  207. __func__, __LINE__, pc->orig_line, pc->column, pc->text(),
  208. get_token_name(pc->type), column);
  209. size_t col_delta = column - pc->column;
  210. size_t min_col = column;
  211. pc->column = column;
  212. do
  213. {
  214. chunk_t *next = chunk_get_next(pc);
  215. chunk_t *prev;
  216. align_mode almod = ALMODE_SHIFT;
  217. if (next == NULL)
  218. {
  219. break;
  220. }
  221. int min_delta = space_col_align(pc, next);
  222. min_col += min_delta;
  223. prev = pc;
  224. pc = next;
  225. if (chunk_is_comment(pc) && (pc->parent_type != CT_COMMENT_EMBED))
  226. {
  227. almod = (chunk_is_single_line_comment(pc) &&
  228. cpd.settings[UO_indent_relative_single_line_comments].b) ?
  229. ALMODE_KEEP_REL : ALMODE_KEEP_ABS;
  230. }
  231. if (almod == ALMODE_KEEP_ABS)
  232. {
  233. /* Keep same absolute column */
  234. pc->column = pc->orig_col;
  235. if (pc->column < min_col)
  236. {
  237. pc->column = min_col;
  238. }
  239. }
  240. else if (almod == ALMODE_KEEP_REL)
  241. {
  242. /* Keep same relative column */
  243. int orig_delta = pc->orig_col - prev->orig_col;
  244. if (orig_delta < min_delta)
  245. {
  246. orig_delta = min_delta;
  247. }
  248. pc->column = prev->column + orig_delta;
  249. }
  250. else /* ALMODE_SHIFT */
  251. {
  252. /* Shift by the same amount */
  253. pc->column += col_delta;
  254. if (pc->column < min_col)
  255. {
  256. pc->column = min_col;
  257. }
  258. }
  259. LOG_FMT(LINDLINED, " %s set column of %s on line %zu to col %zu (orig %zu)\n",
  260. (almod == ALMODE_KEEP_ABS) ? "abs" :
  261. (almod == ALMODE_KEEP_REL) ? "rel" : "sft",
  262. get_token_name(pc->type), pc->orig_line, pc->column, pc->orig_col);
  263. } while ((pc != NULL) && (pc->nl_count == 0));
  264. } // align_to_column
  265. void reindent_line(chunk_t *pc, size_t column)
  266. {
  267. LOG_FUNC_ENTRY();
  268. LOG_FMT(LINDLINE, "%s(%d): %zu] col %zu on '%s' [%s/%s] => %zu",
  269. __func__, __LINE__, pc->orig_line, pc->column, pc->text(),
  270. get_token_name(pc->type), get_token_name(pc->parent_type),
  271. column);
  272. log_func_stack_inline(LINDLINE);
  273. if (column == pc->column)
  274. {
  275. return;
  276. }
  277. size_t col_delta = column - pc->column;
  278. size_t min_col = column;
  279. pc->column = column;
  280. do
  281. {
  282. if (QT_SIGNAL_SLOT_found)
  283. {
  284. // fix the bug #654
  285. // connect(&mapper, SIGNAL(mapped(QString &)), this, SLOT(onSomeEvent(QString &)));
  286. // look for end of SIGNAL/SLOT block
  287. if (!(pc->flags & PCF_IN_QT_MACRO))
  288. {
  289. LOG_FMT(LINDLINE, "FLAGS is NOT set: PCF_IN_QT_MACRO\n");
  290. restore_options_for_QT();
  291. }
  292. }
  293. else
  294. {
  295. // look for begin of SIGNAL/SLOT block
  296. if (pc->flags & PCF_IN_QT_MACRO)
  297. {
  298. LOG_FMT(LINDLINE, "FLAGS is set: PCF_IN_QT_MACRO\n");
  299. save_set_options_for_QT(pc->level);
  300. }
  301. }
  302. chunk_t *next = chunk_get_next(pc);
  303. if (next == NULL)
  304. {
  305. break;
  306. }
  307. if (pc->nl_count)
  308. {
  309. min_col = 0;
  310. col_delta = 0;
  311. }
  312. min_col += space_col_align(pc, next);
  313. pc = next;
  314. bool is_comment = chunk_is_comment(pc);
  315. bool keep = is_comment && chunk_is_single_line_comment(pc) &&
  316. cpd.settings[UO_indent_relative_single_line_comments].b;
  317. if (is_comment && (pc->parent_type != CT_COMMENT_EMBED) && !keep)
  318. {
  319. pc->column = pc->orig_col;
  320. if (pc->column < min_col)
  321. {
  322. pc->column = min_col; // + 1;
  323. }
  324. LOG_FMT(LINDLINE, "%s(%d): set comment on line %zu to col %zu (orig %zu)\n",
  325. __func__, __LINE__, pc->orig_line, pc->column, pc->orig_col);
  326. }
  327. else
  328. {
  329. pc->column += col_delta;
  330. if (pc->column < min_col)
  331. {
  332. pc->column = min_col;
  333. }
  334. LOG_FMT(LINDLINED, " set column of ");
  335. if (pc->type == CT_NEWLINE)
  336. {
  337. LOG_FMT(LINDLINED, "newline");
  338. }
  339. else
  340. {
  341. LOG_FMT(LINDLINED, "'%s'", pc->text());
  342. }
  343. LOG_FMT(LINDLINED, " to %zu (orig %zu)\n", pc->column, pc->orig_col);
  344. }
  345. } while ((pc != NULL) && (pc->nl_count == 0));
  346. } // reindent_line
  347. static void indent_pse_push(parse_frame_t &frm, chunk_t *pc)
  348. {
  349. LOG_FUNC_ENTRY();
  350. static size_t ref = 0;
  351. /* check the stack depth */
  352. if (frm.pse_tos < (ARRAY_SIZE(frm.pse) - 1))
  353. {
  354. /* Bump up the index and initialize it */
  355. frm.pse_tos++;
  356. LOG_FMT(LINDLINE, "%s(%d): line=%zu, pse_tos=%zu, type=%s\n",
  357. __func__, __LINE__, pc->orig_line, frm.pse_tos, get_token_name(pc->type));
  358. memset(&frm.pse[frm.pse_tos], 0, sizeof(frm.pse[frm.pse_tos]));
  359. //LOG_FMT(LINDPSE, "%s(%d):%d] (pp=%d) OPEN [%d,%s] level=%d\n",
  360. // __func__, __LINE__, pc->orig_line, cpd.pp_level, frm.pse_tos, get_token_name(pc->type), pc->level);
  361. frm.pse[frm.pse_tos].pc = pc;
  362. frm.pse[frm.pse_tos].type = pc->type;
  363. frm.pse[frm.pse_tos].level = pc->level;
  364. frm.pse[frm.pse_tos].open_line = pc->orig_line;
  365. frm.pse[frm.pse_tos].ref = ++ref;
  366. frm.pse[frm.pse_tos].in_preproc = (pc->flags & PCF_IN_PREPROC);
  367. frm.pse[frm.pse_tos].indent_tab = frm.pse[frm.pse_tos - 1].indent_tab;
  368. frm.pse[frm.pse_tos].indent_cont = frm.pse[frm.pse_tos - 1].indent_cont;
  369. frm.pse[frm.pse_tos].non_vardef = false;
  370. frm.pse[frm.pse_tos].ns_cnt = frm.pse[frm.pse_tos - 1].ns_cnt;
  371. memcpy(&frm.pse[frm.pse_tos].ip, &frm.pse[frm.pse_tos - 1].ip, sizeof(frm.pse[frm.pse_tos].ip));
  372. }
  373. else
  374. {
  375. /* the stack depth is too small */
  376. /* fatal error */
  377. fprintf(stderr, "the stack depth is too small\n");
  378. exit(EXIT_FAILURE);
  379. }
  380. }
  381. static void indent_pse_pop(parse_frame_t &frm, chunk_t *pc)
  382. {
  383. LOG_FUNC_ENTRY();
  384. /* Bump up the index and initialize it */
  385. if (frm.pse_tos > 0)
  386. {
  387. if (pc != NULL)
  388. {
  389. LOG_FMT(LINDPSE, "%4zu] (pp=%d) CLOSE [%zu,%s] on %s, started on line %d, level=%zu/%zu\n",
  390. pc->orig_line, cpd.pp_level, frm.pse_tos,
  391. get_token_name(frm.pse[frm.pse_tos].type),
  392. get_token_name(pc->type),
  393. frm.pse[frm.pse_tos].open_line,
  394. frm.pse[frm.pse_tos].level,
  395. pc->level);
  396. }
  397. else
  398. {
  399. LOG_FMT(LINDPSE, " EOF] CLOSE [%zu,%s], started on line %d\n",
  400. frm.pse_tos, get_token_name(frm.pse[frm.pse_tos].type),
  401. frm.pse[frm.pse_tos].open_line);
  402. }
  403. /* Don't clear the stack entry because some code 'cheats' and uses the
  404. * just-popped indent values
  405. */
  406. frm.pse_tos--;
  407. LOG_FMT(LINDLINE, "(%d) ", __LINE__);
  408. if (pc != NULL)
  409. {
  410. LOG_FMT(LINDLINE, "%s(%d): orig_line=%zu, pse_tos=%zu, type=%s\n",
  411. __func__, __LINE__, pc->orig_line, frm.pse_tos, get_token_name(pc->type));
  412. }
  413. else
  414. {
  415. LOG_FMT(LINDLINE, "%s(%d): ------------------- pse_tos=%zu\n",
  416. __func__, __LINE__, frm.pse_tos);
  417. }
  418. }
  419. else
  420. {
  421. /* fatal error */
  422. fprintf(stderr, "the stack index is already zero\n");
  423. fprintf(stderr, "at line=%zu, type is %s\n",
  424. pc->orig_line, get_token_name(pc->type));
  425. exit(EXIT_FAILURE);
  426. }
  427. } // indent_pse_pop
  428. static size_t token_indent(c_token_t type)
  429. {
  430. switch (type)
  431. {
  432. case CT_IF:
  433. case CT_DO:
  434. return(3);
  435. case CT_FOR:
  436. case CT_ELSE: // wacky, but that's what is wanted
  437. return(4);
  438. case CT_WHILE:
  439. case CT_USING_STMT:
  440. return(6);
  441. case CT_SWITCH:
  442. return(7);
  443. case CT_ELSEIF:
  444. return(8);
  445. case CT_SYNCHRONIZED:
  446. return(13);
  447. default:
  448. return(0);
  449. }
  450. }
  451. #define indent_column_set(X) \
  452. do { \
  453. indent_column = (X); \
  454. LOG_FMT(LINDENT2, "%s:[line %d], orig_line=%zu, indent_column = %zu\n", \
  455. __func__, __LINE__, pc->orig_line, indent_column); \
  456. } while (0)
  457. static size_t calc_indent_continue(parse_frame_t &frm, size_t pse_tos)
  458. {
  459. int ic = cpd.settings[UO_indent_continue].n;
  460. if ((ic < 0) && frm.pse[pse_tos].indent_cont)
  461. {
  462. return(frm.pse[pse_tos].indent);
  463. }
  464. return(frm.pse[pse_tos].indent + abs(ic));
  465. }
  466. static chunk_t *oc_msg_block_indent(chunk_t *pc, bool from_brace,
  467. bool from_caret, bool from_colon,
  468. bool from_keyword)
  469. {
  470. LOG_FUNC_ENTRY();
  471. chunk_t *tmp = chunk_get_prev_nc(pc);
  472. if (from_brace)
  473. {
  474. return(pc);
  475. }
  476. if (chunk_is_paren_close(tmp))
  477. {
  478. tmp = chunk_get_prev_nc(chunk_skip_to_match_rev(tmp));
  479. }
  480. if (!tmp || (tmp->type != CT_OC_BLOCK_CARET))
  481. {
  482. return(NULL);
  483. }
  484. if (from_caret)
  485. {
  486. return(tmp);
  487. }
  488. tmp = chunk_get_prev_nc(tmp);
  489. if (!tmp || (tmp->type != CT_OC_COLON))
  490. {
  491. return(NULL);
  492. }
  493. if (from_colon)
  494. {
  495. return(tmp);
  496. }
  497. tmp = chunk_get_prev_nc(tmp);
  498. if (!tmp || ((tmp->type != CT_OC_MSG_NAME) && (tmp->type != CT_OC_MSG_FUNC)))
  499. {
  500. return(NULL);
  501. }
  502. if (from_keyword)
  503. {
  504. return(tmp);
  505. }
  506. return(NULL);
  507. } // oc_msg_block_indent
  508. static chunk_t *oc_msg_prev_colon(chunk_t *pc)
  509. {
  510. return(chunk_get_prev_type(pc, CT_OC_COLON, pc->level, CNAV_ALL));
  511. }
  512. void indent_text(void)
  513. {
  514. LOG_FUNC_ENTRY();
  515. chunk_t *pc;
  516. chunk_t *next;
  517. chunk_t *prev = NULL;
  518. bool did_newline = true;
  519. int idx;
  520. size_t vardefcol = 0;
  521. size_t shiftcontcol = 0;
  522. size_t indent_size = cpd.settings[UO_indent_columns].u;
  523. parse_frame_t frm;
  524. bool in_preproc = false;
  525. size_t indent_column;
  526. size_t parent_token_indent = 0;
  527. int xml_indent = 0;
  528. bool token_used;
  529. size_t sql_col = 0;
  530. size_t sql_orig_col = 0;
  531. bool in_func_def = false;
  532. c_token_t memtype;
  533. memset(&frm, 0, sizeof(frm));
  534. cpd.frame_count = 0;
  535. /* dummy top-level entry */
  536. frm.pse[0].indent = 1;
  537. frm.pse[0].indent_tmp = 1;
  538. frm.pse[0].indent_tab = 1;
  539. frm.pse[0].type = CT_EOF;
  540. pc = chunk_get_head();
  541. while (pc != NULL)
  542. {
  543. if (pc->type == CT_NEWLINE)
  544. {
  545. LOG_FMT(LINDLINE, "%s(%d): %zu NEWLINE\n",
  546. __func__, __LINE__, pc->orig_line);
  547. }
  548. else
  549. {
  550. LOG_FMT(LINDLINE, "%s(%d): %zu:%zu pc->text() %s\n",
  551. __func__, __LINE__, pc->orig_line, pc->orig_col, pc->text());
  552. log_pcf_flags(LINDLINE, pc->flags);
  553. }
  554. if ((cpd.settings[UO_use_options_overriding_for_qt_macros].b) &&
  555. ((strcmp(pc->text(), "SIGNAL") == 0) ||
  556. (strcmp(pc->text(), "SLOT") == 0)))
  557. { // guy 2015-09-22
  558. LOG_FMT(LINDLINE, "%s(%d): orig_line=%zu: type %s SIGNAL/SLOT found\n",
  559. __func__, __LINE__, pc->orig_line, get_token_name(pc->type));
  560. }
  561. /* Handle preprocessor transitions */
  562. in_preproc = (pc->flags & PCF_IN_PREPROC);
  563. if (cpd.settings[UO_indent_brace_parent].b)
  564. {
  565. parent_token_indent = token_indent(pc->parent_type);
  566. }
  567. /* Handle "force indentation of function definition to start in column 1" */
  568. if (cpd.settings[UO_indent_func_def_force_col1].b)
  569. {
  570. if (!in_func_def)
  571. {
  572. next = chunk_get_next_ncnl(pc);
  573. if ((pc->parent_type == CT_FUNC_DEF) ||
  574. ((pc->type == CT_COMMENT) &&
  575. (next != NULL) &&
  576. (next->parent_type == CT_FUNC_DEF)))
  577. {
  578. in_func_def = true;
  579. indent_pse_push(frm, pc);
  580. frm.pse[frm.pse_tos].indent_tmp = 1;
  581. frm.pse[frm.pse_tos].indent = 1;
  582. frm.pse[frm.pse_tos].indent_tab = 1;
  583. }
  584. }
  585. else
  586. {
  587. prev = chunk_get_prev(pc);
  588. if ((prev->type == CT_BRACE_CLOSE) &&
  589. (prev->parent_type == CT_FUNC_DEF))
  590. {
  591. in_func_def = false;
  592. indent_pse_pop(frm, pc);
  593. }
  594. }
  595. }
  596. /* Clean up after a #define, etc */
  597. if (!in_preproc)
  598. {
  599. while ((frm.pse_tos > 0) && frm.pse[frm.pse_tos].in_preproc)
  600. {
  601. c_token_t type = frm.pse[frm.pse_tos].type;
  602. indent_pse_pop(frm, pc);
  603. /* If we just removed an #endregion, then check to see if a
  604. * PP_REGION_INDENT entry is right below it
  605. */
  606. if ((type == CT_PP_ENDREGION) &&
  607. (frm.pse[frm.pse_tos].type == CT_PP_REGION_INDENT))
  608. {
  609. indent_pse_pop(frm, pc);
  610. }
  611. }
  612. }
  613. else if (pc->type == CT_PREPROC)
  614. {
  615. /* Close out PP_IF_INDENT before playing with the parse frames */
  616. if ((frm.pse[frm.pse_tos].type == CT_PP_IF_INDENT) &&
  617. ((pc->parent_type == CT_PP_ENDIF) ||
  618. (pc->parent_type == CT_PP_ELSE)))
  619. {
  620. indent_pse_pop(frm, pc);
  621. }
  622. pf_check(&frm, pc);
  623. /* Indent the body of a #region here */
  624. if (cpd.settings[UO_pp_region_indent_code].b &&
  625. (pc->parent_type == CT_PP_REGION))
  626. {
  627. next = chunk_get_next(pc);
  628. if (next == NULL)
  629. {
  630. break;
  631. }
  632. /* Hack to get the logs to look right */
  633. set_chunk_type(next, CT_PP_REGION_INDENT);
  634. indent_pse_push(frm, next);
  635. set_chunk_type(next, CT_PP_REGION);
  636. /* Indent one level */
  637. frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent + indent_size;
  638. frm.pse[frm.pse_tos].indent_tab = frm.pse[frm.pse_tos - 1].indent_tab + indent_size;
  639. frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
  640. frm.pse[frm.pse_tos].in_preproc = false;
  641. }
  642. /* Indent the body of a #if here */
  643. if (cpd.settings[UO_pp_if_indent_code].b &&
  644. ((pc->parent_type == CT_PP_IF) ||
  645. (pc->parent_type == CT_PP_ELSE)))
  646. {
  647. next = chunk_get_next(pc);
  648. if (next == NULL)
  649. {
  650. break;
  651. }
  652. /* Hack to get the logs to look right */
  653. memtype = next->type;
  654. set_chunk_type(next, CT_PP_IF_INDENT);
  655. indent_pse_push(frm, next);
  656. set_chunk_type(next, memtype);
  657. /* Indent one level except if the #if is a #include guard */
  658. int extra = ((pc->pp_level == 0) && ifdef_over_whole_file()) ? 0 : indent_size;
  659. frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent + extra;
  660. frm.pse[frm.pse_tos].indent_tab = frm.pse[frm.pse_tos - 1].indent_tab + extra;
  661. frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
  662. frm.pse[frm.pse_tos].in_preproc = false;
  663. }
  664. /* Transition into a preproc by creating a dummy indent */
  665. frm.level++;
  666. indent_pse_push(frm, chunk_get_next(pc));
  667. if ((pc->parent_type == CT_PP_DEFINE) ||
  668. (pc->parent_type == CT_PP_UNDEF))
  669. {
  670. frm.pse[frm.pse_tos].indent_tmp = cpd.settings[UO_pp_define_at_level].b ?
  671. frm.pse[frm.pse_tos - 1].indent_tmp : 1;
  672. frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos].indent_tmp + indent_size;
  673. frm.pse[frm.pse_tos].indent_tab = frm.pse[frm.pse_tos].indent;
  674. }
  675. else if ((pc->parent_type == CT_PP_PRAGMA) &&
  676. cpd.settings[UO_pp_define_at_level].b)
  677. {
  678. frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos - 1].indent_tmp;
  679. frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos].indent_tmp + indent_size;
  680. frm.pse[frm.pse_tos].indent_tab = frm.pse[frm.pse_tos].indent;
  681. }
  682. else
  683. {
  684. LOG_FMT(LINDLINE, "%s(%d): frm.pse_tos=%zu, ... indent=%d\n",
  685. __func__, __LINE__, frm.pse_tos, frm.pse[frm.pse_tos].indent);
  686. if ((frm.pse[frm.pse_tos - 1].type == CT_PP_REGION_INDENT) ||
  687. ((frm.pse[frm.pse_tos - 1].type == CT_PP_IF_INDENT) &&
  688. (frm.pse[frm.pse_tos].type != CT_PP_ENDIF)))
  689. {
  690. frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 2].indent;
  691. }
  692. else
  693. {
  694. frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent;
  695. }
  696. LOG_FMT(LINDLINE, "%s(%d): frm.pse_tos=%zu, ... indent=%d\n",
  697. __func__, __LINE__, frm.pse_tos, frm.pse[frm.pse_tos].indent);
  698. if ((pc->parent_type == CT_PP_REGION) ||
  699. (pc->parent_type == CT_PP_ENDREGION))
  700. {
  701. int val = cpd.settings[UO_pp_indent_region].n;
  702. if (val > 0)
  703. {
  704. frm.pse[frm.pse_tos].indent = val;
  705. }
  706. else
  707. {
  708. frm.pse[frm.pse_tos].indent += val;
  709. }
  710. }
  711. else if ((pc->parent_type == CT_PP_IF) ||
  712. (pc->parent_type == CT_PP_ELSE) ||
  713. (pc->parent_type == CT_PP_ENDIF))
  714. {
  715. int val = cpd.settings[UO_pp_indent_if].n;
  716. if (val > 0)
  717. {
  718. frm.pse[frm.pse_tos].indent = val;
  719. }
  720. else
  721. {
  722. frm.pse[frm.pse_tos].indent += val;
  723. }
  724. }
  725. frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
  726. LOG_FMT(LINDLINE, "%s(%d): frm.pse_tos=%zu, ... indent_tmp=%zu\n",
  727. __func__, __LINE__, frm.pse_tos, frm.pse[frm.pse_tos].indent_tmp);
  728. }
  729. }
  730. /* Check for close XML tags "</..." */
  731. if (cpd.settings[UO_indent_xml_string].n > 0)
  732. {
  733. if (pc->type == CT_STRING)
  734. {
  735. if ((pc->len() > 4) &&
  736. (xml_indent > 0) &&
  737. (pc->str[1] == '<') &&
  738. (pc->str[2] == '/'))
  739. {
  740. xml_indent -= cpd.settings[UO_indent_xml_string].n;
  741. }
  742. }
  743. else
  744. {
  745. if (!chunk_is_comment(pc) && !chunk_is_newline(pc))
  746. {
  747. xml_indent = 0;
  748. }
  749. }
  750. }
  751. /**
  752. * Handle non-brace closures
  753. */
  754. LOG_FMT(LINDLINE, "%s(%d): frm.pse_tos=%zu, ... indent_tmp=%zu\n",
  755. __func__, __LINE__, frm.pse_tos, frm.pse[frm.pse_tos].indent_tmp);
  756. token_used = false;
  757. size_t old_pse_tos;
  758. do
  759. {
  760. old_pse_tos = frm.pse_tos;
  761. /* End anything that drops a level */
  762. if (!chunk_is_newline(pc) &&
  763. !chunk_is_comment(pc) &&
  764. (frm.pse[frm.pse_tos].level > pc->level))
  765. {
  766. indent_pse_pop(frm, pc);
  767. }
  768. if (frm.pse[frm.pse_tos].level >= pc->level)
  769. {
  770. /* process virtual braces closes (no text output) */
  771. if ((pc->type == CT_VBRACE_CLOSE) &&
  772. (frm.pse[frm.pse_tos].type == CT_VBRACE_OPEN))
  773. {
  774. indent_pse_pop(frm, pc);
  775. frm.level--;
  776. pc = chunk_get_next(pc);
  777. if (!pc)
  778. {
  779. /* need to break out of both the do and while loops */
  780. goto null_pc;
  781. }
  782. }
  783. /* End any assign operations with a semicolon on the same level */
  784. if (((frm.pse[frm.pse_tos].type == CT_ASSIGN_NL) ||
  785. (frm.pse[frm.pse_tos].type == CT_ASSIGN)) &&
  786. (chunk_is_semicolon(pc) ||
  787. (pc->type == CT_COMMA) ||
  788. (pc->type == CT_BRACE_OPEN) ||
  789. (pc->type == CT_SPAREN_CLOSE) ||
  790. ((pc->type == CT_SQUARE_OPEN) && (pc->parent_type == CT_OC_AT)) ||
  791. ((pc->type == CT_SQUARE_OPEN) && (pc->parent_type == CT_ASSIGN))) &&
  792. (pc->parent_type != CT_CPP_LAMBDA))
  793. {
  794. indent_pse_pop(frm, pc);
  795. }
  796. /* End any assign operations with a semicolon on the same level */
  797. if (chunk_is_semicolon(pc) &&
  798. ((frm.pse[frm.pse_tos].type == CT_IMPORT) ||
  799. (frm.pse[frm.pse_tos].type == CT_USING)))
  800. {
  801. indent_pse_pop(frm, pc);
  802. }
  803. /* End any custom macro-based open/closes */
  804. if (!token_used &&
  805. (frm.pse[frm.pse_tos].type == CT_MACRO_OPEN) &&
  806. (pc->type == CT_MACRO_CLOSE))
  807. {
  808. token_used = true;
  809. indent_pse_pop(frm, pc);
  810. }
  811. /* End any CPP/ObjC class colon stuff */
  812. if (((frm.pse[frm.pse_tos].type == CT_CLASS_COLON) ||
  813. (frm.pse[frm.pse_tos].type == CT_CONSTR_COLON)) &&
  814. ((pc->type == CT_BRACE_OPEN) ||
  815. (pc->type == CT_OC_END) ||
  816. (pc->type == CT_OC_SCOPE) ||
  817. (pc->type == CT_OC_PROPERTY) ||
  818. chunk_is_semicolon(pc)))
  819. {
  820. indent_pse_pop(frm, pc);
  821. }
  822. /* End ObjC class colon stuff inside of generic definition (like Test<T1: id<T3>>) */
  823. if ((frm.pse[frm.pse_tos].type == CT_CLASS_COLON) &&
  824. (pc->type == CT_ANGLE_CLOSE) &&
  825. (pc->parent_type == CT_OC_GENERIC_SPEC))
  826. {
  827. indent_pse_pop(frm, pc);
  828. }
  829. /* a case is ended with another case or a close brace */
  830. if ((frm.pse[frm.pse_tos].type == CT_CASE) &&
  831. ((pc->type == CT_BRACE_CLOSE) ||
  832. (pc->type == CT_CASE)))
  833. {
  834. indent_pse_pop(frm, pc);
  835. }
  836. /* a class scope is ended with another class scope or a close brace */
  837. if (cpd.settings[UO_indent_access_spec_body].b &&
  838. (frm.pse[frm.pse_tos].type == CT_PRIVATE) &&
  839. ((pc->type == CT_BRACE_CLOSE) ||
  840. (pc->type == CT_PRIVATE)))
  841. {
  842. indent_pse_pop(frm, pc);
  843. }
  844. /* return & throw are ended with a semicolon */
  845. if (chunk_is_semicolon(pc) &&
  846. ((frm.pse[frm.pse_tos].type == CT_RETURN) ||
  847. (frm.pse[frm.pse_tos].type == CT_THROW)))
  848. {
  849. indent_pse_pop(frm, pc);
  850. }
  851. /* an OC SCOPE ('-' or '+') ends with a semicolon or brace open */
  852. if ((frm.pse[frm.pse_tos].type == CT_OC_SCOPE) &&
  853. (chunk_is_semicolon(pc) ||
  854. (pc->type == CT_BRACE_OPEN)))
  855. {
  856. indent_pse_pop(frm, pc);
  857. }
  858. /* a typedef and an OC SCOPE ('-' or '+') ends with a semicolon or
  859. * brace open */
  860. if ((frm.pse[frm.pse_tos].type == CT_TYPEDEF) &&
  861. (chunk_is_semicolon(pc) ||
  862. chunk_is_paren_open(pc) ||
  863. (pc->type == CT_BRACE_OPEN)))
  864. {
  865. indent_pse_pop(frm, pc);
  866. }
  867. /* an SQL EXEC is ended with a semicolon */
  868. if ((frm.pse[frm.pse_tos].type == CT_SQL_EXEC) &&
  869. chunk_is_semicolon(pc))
  870. {
  871. indent_pse_pop(frm, pc);
  872. }
  873. /* an CLASS is ended with a semicolon or brace open */
  874. if ((frm.pse[frm.pse_tos].type == CT_CLASS) &&
  875. ((pc->type == CT_CLASS_COLON) ||
  876. (pc->type == CT_BRACE_OPEN) ||
  877. chunk_is_semicolon(pc)))
  878. {
  879. indent_pse_pop(frm, pc);
  880. }
  881. /* Close out parens and squares */
  882. if ((frm.pse[frm.pse_tos].type == (pc->type - 1)) &&
  883. ((pc->type == CT_PAREN_CLOSE) ||
  884. (pc->type == CT_SPAREN_CLOSE) ||
  885. (pc->type == CT_FPAREN_CLOSE) ||
  886. (pc->type == CT_SQUARE_CLOSE) ||
  887. (pc->type == CT_ANGLE_CLOSE)))
  888. {
  889. indent_pse_pop(frm, pc);
  890. frm.paren_count--;
  891. }
  892. }
  893. } while (old_pse_tos > frm.pse_tos);
  894. /* Grab a copy of the current indent */
  895. LOG_FMT(LINDLINE, "%s(%d): frm.pse_tos=%zu, ... indent_tmp=%zu\n",
  896. __func__, __LINE__, frm.pse_tos, frm.pse[frm.pse_tos].indent_tmp);
  897. indent_column_set(frm.pse[frm.pse_tos].indent_tmp);
  898. if (!chunk_is_newline(pc) && !chunk_is_comment(pc) && log_sev_on(LINDPC))
  899. {
  900. LOG_FMT(LINDPC, " -=[ %zu:%zu %s ]=-\n",
  901. pc->orig_line, pc->orig_col, pc->text());
  902. for (int ttidx = frm.pse_tos; ttidx > 0; ttidx--)
  903. {
  904. // 1 2 3 4 5 6 7 8 9 10 11 12 13
  905. LOG_FMT(LINDPC, " [%d %zu:%zu %s %s/%s tmp=%zu ind=%d bri=%d tab=%d cont=%d lvl=%zu blvl=%zu]\n",
  906. ttidx,
  907. frm.pse[ttidx].pc->orig_line,
  908. frm.pse[ttidx].pc->orig_col,
  909. frm.pse[ttidx].pc->text(),
  910. get_token_name(frm.pse[ttidx].type),
  911. get_token_name(frm.pse[ttidx].pc->parent_type),
  912. frm.pse[ttidx].indent_tmp,
  913. frm.pse[ttidx].indent,
  914. frm.pse[ttidx].brace_indent,
  915. frm.pse[ttidx].indent_tab,
  916. frm.pse[ttidx].indent_cont,
  917. frm.pse[ttidx].level,
  918. frm.pse[ttidx].pc->brace_level);
  919. }
  920. }
  921. /**
  922. * Handle stuff that can affect the current indent:
  923. * - brace close
  924. * - vbrace open
  925. * - brace open
  926. * - case (immediate)
  927. * - labels (immediate)
  928. * - class colons (immediate)
  929. *
  930. * And some stuff that can't
  931. * - open paren
  932. * - open square
  933. * - assignment
  934. * - return
  935. */
  936. bool brace_indent = false;
  937. if ((pc->type == CT_BRACE_CLOSE) || (pc->type == CT_BRACE_OPEN))
  938. {
  939. brace_indent = (cpd.settings[UO_indent_braces].b &&
  940. (!cpd.settings[UO_indent_braces_no_func].b ||
  941. (pc->parent_type != CT_FUNC_DEF)) &&
  942. (!cpd.settings[UO_indent_braces_no_func].b ||
  943. (pc->parent_type != CT_FUNC_CLASS_DEF)) &&
  944. (!cpd.settings[UO_indent_braces_no_class].b ||
  945. (pc->parent_type != CT_CLASS)) &&
  946. (!cpd.settings[UO_indent_braces_no_struct].b ||
  947. (pc->parent_type != CT_STRUCT)));
  948. }
  949. if (pc->type == CT_BRACE_CLOSE)
  950. {
  951. if (frm.pse[frm.pse_tos].type == CT_BRACE_OPEN)
  952. {
  953. /* Indent the brace to match the open brace */
  954. indent_column_set(frm.pse[frm.pse_tos].brace_indent);
  955. if (frm.pse[frm.pse_tos].ip.ref)
  956. {
  957. pc->indent.ref = frm.pse[frm.pse_tos].ip.ref;
  958. pc->indent.delta = 0;
  959. }
  960. indent_pse_pop(frm, pc);
  961. frm.level--;
  962. }
  963. }
  964. else if (pc->type == CT_VBRACE_OPEN)
  965. {
  966. frm.level++;
  967. indent_pse_push(frm, pc);
  968. size_t iMinIndent = cpd.settings[UO_indent_min_vbrace_open].u;
  969. if (indent_size > iMinIndent)
  970. {
  971. iMinIndent = indent_size;
  972. }
  973. int iNewIndent = frm.pse[frm.pse_tos - 1].indent + iMinIndent;
  974. if (cpd.settings[UO_indent_vbrace_open_on_tabstop].b)
  975. {
  976. iNewIndent = next_tab_column(iNewIndent);
  977. }
  978. frm.pse[frm.pse_tos].indent = iNewIndent;
  979. frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
  980. frm.pse[frm.pse_tos].indent_tab = frm.pse[frm.pse_tos].indent;
  981. /* Always indent on virtual braces */
  982. indent_column_set(frm.pse[frm.pse_tos].indent_tmp);
  983. }
  984. else if ((pc->type == CT_BRACE_OPEN) &&
  985. ((pc->next != NULL) && pc->next->type != CT_NAMESPACE))
  986. {
  987. frm.level++;
  988. indent_pse_push(frm, pc);
  989. if (cpd.settings[UO_indent_cpp_lambda_body].b &&
  990. pc->parent_type == CT_CPP_LAMBDA)
  991. {
  992. frm.pse[frm.pse_tos].brace_indent = frm.pse[frm.pse_tos - 1].indent;
  993. indent_column = frm.pse[frm.pse_tos].brace_indent;
  994. frm.pse[frm.pse_tos].indent = indent_column + indent_size;
  995. frm.pse[frm.pse_tos].indent_tab = frm.pse[frm.pse_tos].indent;
  996. frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
  997. frm.pse[frm.pse_tos - 1].indent_tmp = frm.pse[frm.pse_tos].indent_tmp;
  998. }
  999. else if ((cpd.lang_flags & LANG_CS) && cpd.settings[UO_indent_cs_delegate_brace].b &&
  1000. (pc->parent_type == CT_LAMBDA || pc->parent_type == CT_DELEGATE))
  1001. {
  1002. frm.pse[frm.pse_tos].brace_indent = 1 + ((pc->brace_level + 1) * indent_size);
  1003. indent_column = frm.pse[frm.pse_tos].brace_indent;
  1004. frm.pse[frm.pse_tos].indent = indent_column + indent_size;
  1005. frm.pse[frm.pse_tos].indent_tab = frm.pse[frm.pse_tos].indent;
  1006. frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
  1007. frm.pse[frm.pse_tos - 1].indent_tmp = frm.pse[frm.pse_tos].indent_tmp;
  1008. }
  1009. /* any '{' that is inside of a '(' overrides the '(' indent */
  1010. else if (!cpd.settings[UO_indent_paren_open_brace].b &&
  1011. chunk_is_paren_open(frm.pse[frm.pse_tos - 1].pc) &&
  1012. chunk_is_newline(chunk_get_next_nc(pc)))
  1013. {
  1014. /* FIXME: I don't know how much of this is necessary, but it seems to work */
  1015. frm.pse[frm.pse_tos].brace_indent = 1 + (pc->brace_level * indent_size);
  1016. indent_column = frm.pse[frm.pse_tos].brace_indent;
  1017. frm.pse[frm.pse_tos].indent = indent_column + indent_size;
  1018. frm.pse[frm.pse_tos].indent_tab = frm.pse[frm.pse_tos].indent;
  1019. frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
  1020. frm.pse[frm.pse_tos - 1].indent_tmp = frm.pse[frm.pse_tos].indent_tmp;
  1021. }
  1022. else if (frm.paren_count != 0)
  1023. {
  1024. if (frm.pse[frm.pse_tos].pc->parent_type == CT_OC_BLOCK_EXPR)
  1025. {
  1026. if ((pc->flags & PCF_IN_OC_MSG) &&
  1027. cpd.settings[UO_indent_oc_block_msg].n)
  1028. {
  1029. frm.pse[frm.pse_tos].ip.ref = oc_msg_block_indent(pc, false, false, false, true);
  1030. frm.pse[frm.pse_tos].ip.delta = cpd.settings[UO_indent_oc_block_msg].n;
  1031. }
  1032. if (cpd.settings[UO_indent_oc_block].b ||
  1033. cpd.settings[UO_indent_oc_block_msg_xcode_style].b)
  1034. {
  1035. bool in_oc_msg = (pc->flags & PCF_IN_OC_MSG) != 0; // forcing value to bool
  1036. bool indent_from_keyword = cpd.settings[UO_indent_oc_block_msg_from_keyword].b && in_oc_msg;
  1037. bool indent_from_colon = cpd.settings[UO_indent_oc_block_msg_from_colon].b && in_oc_msg;
  1038. bool indent_from_caret = cpd.settings[UO_indent_oc_block_msg_from_caret].b && in_oc_msg;
  1039. bool indent_from_brace = cpd.settings[UO_indent_oc_block_msg_from_brace].b && in_oc_msg;
  1040. // In "Xcode indent mode", we want to indent:
  1041. // - if the colon is aligned (namely, if a newline has been
  1042. // added before it), indent_from_brace
  1043. // - otherwise, indent from previous block (the "else" statement here)
  1044. if (cpd.settings[UO_indent_oc_block_msg_xcode_style].b)
  1045. {
  1046. chunk_t *colon = oc_msg_prev_colon(pc);
  1047. chunk_t *param_name = chunk_get_prev(colon);
  1048. chunk_t *before_param = chunk_get_prev(param_name);
  1049. if (before_param && (before_param->type == CT_NEWLINE))
  1050. {
  1051. indent_from_keyword = true;
  1052. indent_from_colon = false;
  1053. indent_from_caret = false;
  1054. indent_from_brace = false;
  1055. }
  1056. else
  1057. {
  1058. indent_from_brace = false;
  1059. indent_from_colon = false;
  1060. indent_from_caret = false;
  1061. indent_from_keyword = false;
  1062. }
  1063. }
  1064. chunk_t *ref = oc_msg_block_indent(pc, indent_from_brace,
  1065. indent_from_caret,
  1066. indent_from_colon,
  1067. indent_from_keyword);
  1068. if (ref)
  1069. {
  1070. frm.pse[frm.pse_tos].indent = indent_size + ref->column;
  1071. indent_column_set(frm.pse[frm.pse_tos].indent - indent_size);
  1072. }
  1073. else
  1074. {
  1075. frm.pse[frm.pse_tos].indent = 1 + ((pc->brace_level + 1) * indent_size);
  1076. indent_column_set(frm.pse[frm.pse_tos].indent - indent_size);
  1077. }
  1078. }
  1079. else
  1080. {
  1081. frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent_tmp + indent_size;
  1082. }
  1083. }
  1084. else
  1085. {
  1086. /* We are inside ({ ... }) -- indent one tab from the paren */
  1087. frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent_tmp + indent_size;
  1088. }
  1089. }
  1090. else
  1091. {
  1092. /* Use the prev indent level + indent_size. */
  1093. frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent + indent_size;
  1094. /* If this brace is part of a statement, bump it out by indent_brace */
  1095. if ((pc->parent_type == CT_IF) ||
  1096. (pc->parent_type == CT_ELSE) ||
  1097. (pc->parent_type == CT_ELSEIF) ||
  1098. (pc->parent_type == CT_TRY) ||
  1099. (pc->parent_type == CT_CATCH) ||
  1100. (pc->parent_type == CT_DO) ||
  1101. (pc->parent_type == CT_WHILE) ||
  1102. (pc->parent_type == CT_USING_STMT) ||
  1103. (pc->parent_type == CT_SWITCH) ||
  1104. (pc->parent_type == CT_SYNCHRONIZED) ||
  1105. (pc->parent_type == CT_FOR))
  1106. {
  1107. if (parent_token_indent != 0)
  1108. {
  1109. frm.pse[frm.pse_tos].indent += parent_token_indent - indent_size;
  1110. }
  1111. else
  1112. {
  1113. frm.pse[frm.pse_tos].indent += cpd.settings[UO_indent_brace].n;
  1114. indent_column_set(indent_column + cpd.settings[UO_indent_brace].n);
  1115. }
  1116. }
  1117. else if (pc->parent_type == CT_CASE)
  1118. {
  1119. /* An open brace with the parent of case does not indent by default
  1120. * UO_indent_case_brace can be used to indent the brace.
  1121. * So we need to take the CASE indent, subtract off the
  1122. * indent_size that was added above and then add indent_case_brace.
  1123. */
  1124. indent_column_set(frm.pse[frm.pse_tos - 1].indent - indent_size +
  1125. cpd.settings[UO_indent_case_brace].n);
  1126. /* Stuff inside the brace still needs to be indented */
  1127. frm.pse[frm.pse_tos].indent = indent_column + indent_size;
  1128. frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
  1129. }
  1130. else if ((pc->parent_type == CT_CLASS) && !cpd.settings[UO_indent_class].b)
  1131. {
  1132. frm.pse[frm.pse_tos].indent -= indent_size;
  1133. }
  1134. else if (pc->parent_type == CT_NAMESPACE)
  1135. {
  1136. if (cpd.settings[UO_indent_namespace].b &&
  1137. cpd.settings[UO_indent_namespace_single_indent].b)
  1138. {
  1139. if (frm.pse[frm.pse_tos].ns_cnt)
  1140. {
  1141. /* undo indent on all except the first namespace */
  1142. frm.pse[frm.pse_tos].indent -= indent_size;
  1143. }
  1144. indent_column_set((frm.pse_tos <= 1) ? 1 : frm.pse[frm.pse_tos - 1].brace_indent);
  1145. }
  1146. else if ((pc->flags & PCF_LONG_BLOCK) ||
  1147. !cpd.settings[UO_indent_namespace].b)
  1148. {
  1149. /* don't indent long blocks */
  1150. frm.pse[frm.pse_tos].indent -= indent_size;
  1151. }
  1152. else /* indenting 'short' namespace */
  1153. {
  1154. if (cpd.settings[UO_indent_namespace_level].n > 0)
  1155. {
  1156. frm.pse[frm.pse_tos].indent -= indent_size;
  1157. frm.pse[frm.pse_tos].indent +=
  1158. cpd.settings[UO_indent_namespace_level].n;
  1159. }
  1160. }
  1161. frm.pse[frm.pse_tos].ns_cnt++;
  1162. }
  1163. else if ((pc->parent_type == CT_EXTERN) && !cpd.settings[UO_indent_extern].b)
  1164. {
  1165. frm.pse[frm.pse_tos].indent -= indent_size;
  1166. }
  1167. frm.pse[frm.pse_tos].indent_tab = frm.pse[frm.pse_tos].indent;
  1168. }
  1169. if (pc->flags & PCF_DONT_INDENT)
  1170. {
  1171. frm.pse[frm.pse_tos].indent = pc->column;
  1172. indent_column_set(pc->column);
  1173. }
  1174. else
  1175. {
  1176. /**
  1177. * If there isn't a newline between the open brace and the next
  1178. * item, just indent to wherever the next token is.
  1179. * This covers this sort of stuff:
  1180. * { a++;
  1181. * b--; };
  1182. */
  1183. next = chunk_get_next_ncnl(pc);
  1184. if (next == NULL)
  1185. {
  1186. break;
  1187. }
  1188. if (!chunk_is_newline_between(pc, next))
  1189. {
  1190. if (cpd.settings[UO_indent_token_after_brace].b)
  1191. {
  1192. frm.pse[frm.pse_tos].indent = next->column;
  1193. }
  1194. }
  1195. frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
  1196. frm.pse[frm.pse_tos].open_line = pc->orig_line;
  1197. /* Update the indent_column if needed */
  1198. if (brace_indent || (parent_token_indent != 0))
  1199. {
  1200. indent_column_set(frm.pse[frm.pse_tos].indent_tmp);
  1201. }
  1202. }
  1203. /* Save the brace indent */
  1204. frm.pse[frm.pse_tos].brace_indent = indent_column;
  1205. }
  1206. else if (pc->type == CT_SQL_END)
  1207. {
  1208. if (frm.pse[frm.pse_tos].type == CT_SQL_BEGIN)
  1209. {
  1210. indent_pse_pop(frm, pc);
  1211. frm.level--;
  1212. indent_column_set(frm.pse[frm.pse_tos].indent_tmp);
  1213. }
  1214. }
  1215. else if (pc->type == CT_SQL_BEGIN)
  1216. {
  1217. frm.level++;
  1218. indent_pse_push(frm, pc);
  1219. frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent + indent_size;
  1220. frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
  1221. frm.pse[frm.pse_tos].indent_tab = frm.pse[frm.pse_tos].indent;
  1222. }
  1223. else if (pc->type == CT_SQL_EXEC)
  1224. {
  1225. frm.level++;
  1226. indent_pse_push(frm, pc);
  1227. frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent + indent_size;
  1228. frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
  1229. }
  1230. else if (pc->type == CT_MACRO_OPEN)
  1231. {
  1232. frm.level++;
  1233. indent_pse_push(frm, pc);
  1234. frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent + indent_size;
  1235. frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
  1236. frm.pse[frm.pse_tos].indent_tab = frm.pse[frm.pse_tos].indent;
  1237. }
  1238. else if (pc->type == CT_MACRO_ELSE)
  1239. {
  1240. if (frm.pse[frm.pse_tos].type == CT_MACRO_OPEN)
  1241. {
  1242. indent_column_set(frm.pse[frm.pse_tos - 1].indent);
  1243. }
  1244. }
  1245. else if (pc->type == CT_CASE)
  1246. {
  1247. /* Start a case - indent UO_indent_switch_case from the switch level */
  1248. int tmp = frm.pse[frm.pse_tos].indent + cpd.settings[UO_indent_switch_case].n;
  1249. indent_pse_push(frm, pc);
  1250. frm.pse[frm.pse_tos].indent = tmp;
  1251. frm.pse[frm.pse_tos].indent_tmp = tmp - indent_size + cpd.settings[UO_indent_case_shift].n;
  1252. frm.pse[frm.pse_tos].indent_tab = tmp;
  1253. /* Always set on case statements */
  1254. indent_column_set(frm.pse[frm.pse_tos].indent_tmp);
  1255. /* comments before 'case' need to be aligned with the 'case' */
  1256. chunk_t *pct = pc;
  1257. while (((pct = chunk_get_prev_nnl(pct)) != NULL) &&
  1258. chunk_is_comment(pct))
  1259. {
  1260. chunk_t *t2 = chunk_get_prev(pct);
  1261. if (chunk_is_newline(t2))
  1262. {
  1263. pct->column = frm.pse[frm.pse_tos].indent_tmp;
  1264. pct->column_indent = pct->column;
  1265. }
  1266. }
  1267. }
  1268. else if (pc->type == CT_BREAK)
  1269. {
  1270. prev = chunk_get_prev_ncnl(pc);
  1271. if ((prev != NULL) &&
  1272. (prev->type == CT_BRACE_CLOSE) &&
  1273. (prev->parent_type == CT_CASE))
  1274. {
  1275. // issue #663
  1276. chunk_t *temp = chunk_get_prev_type(pc, CT_BRACE_OPEN, pc->level);
  1277. /* This only affects the 'break', so no need for a stack entry */
  1278. indent_column_set(temp->column);
  1279. }
  1280. }
  1281. else if (pc->type == CT_LABEL)
  1282. {
  1283. /* Labels get sent to the left or backed up */
  1284. if (cpd.settings[UO_indent_label].n > 0)
  1285. {
  1286. indent_column_set(cpd.settings[UO_indent_label].n);
  1287. next = chunk_get_next(pc); /* colon */
  1288. if (next != NULL)
  1289. {
  1290. next = chunk_get_next(next); /* possible statement */
  1291. if ((next != NULL) && !chunk_is_newline(next) &&
  1292. /* label (+ 2, because there is colon and space after it) must fit into indent */
  1293. (cpd.settings[UO_indent_label].n + (int)pc->len() + 2 <= (int)frm.pse[frm.pse_tos].indent))
  1294. {
  1295. reindent_line(next, frm.pse[frm.pse_tos].indent);
  1296. }
  1297. }
  1298. }
  1299. else
  1300. {
  1301. indent_column_set(frm.pse[frm.pse_tos].indent +
  1302. cpd.settings[UO_indent_label].n);
  1303. }
  1304. }
  1305. else if (pc->type == CT_PRIVATE)
  1306. {
  1307. if (cpd.settings[UO_indent_access_spec_body].b)
  1308. {
  1309. int tmp = frm.pse[frm.pse_tos].indent + indent_size;
  1310. indent_pse_push(frm, pc);
  1311. frm.pse[frm.pse_tos].indent = tmp;
  1312. frm.pse[frm.pse_tos].indent_tmp = tmp - indent_size;
  1313. frm.pse[frm.pse_tos].indent_tab = tmp;
  1314. /* If we are indenting the body, then we must leave the access spec
  1315. * indented at brace level
  1316. */
  1317. indent_column_set(frm.pse[frm.pse_tos].indent_tmp);
  1318. }
  1319. else

Large files files are truncated, but you can click here to view the full file