📄 output.c
字号:
/* * Copyright (c) 2002 D.Ingamells * * File: output.c * Purpose: Interface to the output file for the indent tool. * * History: * 2002-03-04 D.Ingamells Creation. * 2002-11-10 Cristalle Azundris Sabon <cristalle@azundris.com> * Added --preprocessor-indentation (ppi) if set, will indent nested * preprocessor-statements with n spaces per level. overrides -lps. */#include <stdio.h>#include <sys/types.h>#include <time.h> /*changed from utime.h to time.h BY YWQ*/#include <sys/stat.h>#include "indent.h"#include "sys.h"#include "globs.h"#include "output.h"#include<assert.h>/* next 2 lines is add by ywq for function free() and exit()*/#include <malloc.h>#include <stdlib.h>RCSTAG_CC ("$Id: output.c,v 1.5 2002/12/12 17:36:49 david Exp $");static MEMFILE * output = NULL;static BOOLEAN inhibited = 0;static buf_break_st_ty * buf_break_list = NULL;/* Priority mask bits */static const int boolean_operator = 1;buf_break_st_ty * buf_break = NULL;int out_lines = 0; /* used in output.c indent.c */int com_lines = 0; /* used in output.c indent.c comments.c */int prev_target_col_break = 0;int buf_break_used = 0;int preproc_indent = 0;/* * Returns `true' when `b1' is a better place to break the code than `b2'. * `b1' must be newer. * * When `lineup_to_parens' is true, do not break more then 1 level deeper * unless that doesn't cost us "too much" indentation. * What is "too much" is determined in a fuzzy way as follows: * Consider the example, * while (!(!(!(!(!(!(mask * || (((a_very_long_expression_that_cant_be_broken * here we prefer to break after `mask' instead of after `while'. * This is because the `target_col' is pretty close to the break point * of the `while': "mask"->target_col - "while"->col == 15 == "mask"->level * 2 + 1. */static int better_break ( buf_break_st_ty *b1, const buf_break_st_ty *b2){ static int first_level; int is_better; if (!b2) { first_level = b1->level; b1->first_level = first_level; return 1; } if (b2->target_col >= b2->col + 1) { is_better = true; } else if (settings.honour_newlines && b2->priority_newline) { is_better = false; } else if (settings.honour_newlines && b1->priority_newline) { is_better = true; } else { int only_parens_till_b2 = 0; is_better = (b1->priority > b2->priority); if (is_better) { char *p; for (p = &s_code[b2->offset]; p >= s_code; --p) { if (*p == '!') { --p; } if (*p != '(') { break; } } if (p < s_code) { only_parens_till_b2 = 1; } } if (settings.lineup_to_parens && (b1->level > first_level + 1) && !(only_parens_till_b2 && (b1->target_col <= b2->col + (1 + 2 * b1->level))) && (b1->level > b2->level)) { is_better = false; } } if (is_better) { b1->first_level = first_level; } return is_better;}/* * Example: * e_code (`s_code' buffer, at the moment set_buf_break() is called) * ptr (`s_code' buffer) * corresponds_to (input buffer) * Left most column col+1 (the column (31 here)). * | | * 1234567890123456789012345678901234567890 * if (!(mask[0] == '\\0' * | * target_col (assuming `lineup_to_parens' is true in this example) * 1 2 3 2 | level == 2 * <---------------------> * priority_code_length *//* * Calculate break priority. */static void set_priority ( buf_break_st_ty *bb){ bb->priority = bb->priority_code_length; switch (bb->priority_code) { case bb_semicolon: bb->priority += 6000; break; case bb_before_boolean_binary_op: bb->priority += 5000; break; case bb_after_boolean_binary_op: if (bb->priority_code_length > 2) { bb->priority += 5000; } if (settings.break_before_boolean_operator) { bb->priority -= 3; } break; case bb_after_equal_sign: bb->priority += 4000; break; case bb_attribute: bb->priority += 3000; break; case bb_comma: bb->priority += 2000; break; case bb_comparisation: bb->priority += 1000; break; case bb_proc_call: bb->priority -= 1000; break; case bb_operator6: bb->priority += 600; break; case bb_operator5: bb->priority += 500; break; case bb_operator4: bb->priority += 400; break; case bb_operator2: bb->priority += 200; break; case bb_doublecolon: bb->priority += 100; break; default: break; }}/* * This function is called at every position where we possibly want * to break a line (if it gets too long). */void set_buf_break ( bb_code_ty code, int paren_targ){ int target_col, level; int code_target = compute_code_target (paren_targ); buf_break_st_ty *bb; /* First, calculate the column that code following e_code would be * printed in if we'd break the line here. * This is done quite simular to compute_code_target(). */ /* Base indentation level (number of open left-braces) */ target_col = parser_state_tos->i_l_follow + 1; /* Did we just parse a brace that will be put on the next line * by this line break? */ if (*token == '{') { target_col -= settings.ind_size; /* Use `ind_size' because this only happens * for the first brace of initializer blocks. */ } /* Number of open brackets */ level = parser_state_tos->p_l_follow; /* Did we just parse a bracket that will be put on the next line * by this line break? */ if (*token == '(' || *token == '[') { --level; /* then don't take it into account */ } /* Procedure name of function declaration? */ if (parser_state_tos->procname[0] && token == parser_state_tos->procname) { target_col = 1; } else if (level == 0) /* No open brackets? */ { if (parser_state_tos->in_stmt) /* Breaking a statement? */ { target_col += settings.continuation_indent; } } else if (!settings.lineup_to_parens) { target_col += settings.continuation_indent + (settings.paren_indent * (level - 1)); } else { if (parser_state_tos->paren_indents[level - 1] < 0) { target_col = -parser_state_tos->paren_indents[level - 1]; } else { target_col = code_target + parser_state_tos->paren_indents[level - 1]; } } /* Store the position of `e_code' as the place to break this line. */ bb = (buf_break_st_ty *) xmalloc (sizeof (buf_break_st_ty)); bb->offset = e_code - s_code; bb->level = level; bb->target_col = target_col; bb->corresponds_to = token; *e_code = 0; bb->col = count_columns (code_target, s_code, NULL_CHAR) - 1; /* Calculate default priority. */ bb->priority_code_length = (e_code - s_code); bb->priority_newline = (parser_state_tos->last_saw_nl && !parser_state_tos->broken_at_non_nl); if (buf_break) { bb->first_level = buf_break->first_level; } switch (parser_state_tos->last_token) { case binary_op: if ((e_code - s_code) >= 3 && e_code[-3] == ' ' && ((e_code[-1] == '&' && e_code[-2] == '&') || (e_code[-1] == '|' && e_code[-2] == '|'))) { bb->priority_code = bb_after_boolean_binary_op; } else if ( (e_code - s_code >= 2) && (e_code[-1] == '=') && ( (e_code[-2] == ' ') || ( (e_code - s_code >= 3) && (e_code[-3] == ' ') && ( (e_code[-2] == '%') || (e_code[-2] == '^') || (e_code[-2] == '&') || (e_code[-2] == '*') || (e_code[-2] == '-') || (e_code[-2] == '+') || (e_code[-2] == '|'))))) { bb->priority_code = bb_after_equal_sign; } else if ( ( ( (e_code - s_code) >= 2) && (e_code[-2] == ' ') && ( (e_code[-1] == '<') || (e_code[-1] == '>'))) || ( ( (e_code - s_code) >= 3) && (e_code[-3] == ' ') && (e_code[-1] == '=') && ( (e_code[-2] == '=') || (e_code[-2] == '!') || (e_code[-2] == '<') || (e_code[-2] == '>')))) { bb->priority_code = bb_comparisation; } else if ( (e_code[-1] == '+') || (e_code[-1] == '-')) { bb->priority_code = bb_operator6; } else if ( (e_code[-1] == '*') || (e_code[-1] == '/') || (e_code[-1] == '%')) { bb->priority_code = bb_operator5; } else { bb->priority_code = bb_binary_op; } break; case comma: bb->priority_code = bb_comma; break; default: if ( (code == bb_binary_op) && ( (*token == '&') || (*token == '|')) && (*token == token[1])) { bb->priority_code = bb_before_boolean_binary_op; } else if (e_code[-1] == ';') { bb->priority_code = bb_semicolon; } else { bb->priority_code = code; if (code == bb_struct_delim) /* . -> .* or ->* */ { if (e_code[-1] == '*') { bb->priority_code = bb_operator4; } else { bb->priority_code = bb_operator2; } } } } set_priority (bb); /* Add buf_break to the list */ if (buf_break_list) { buf_break_list->next = bb; } bb->prev = buf_break_list; bb->next = NULL; buf_break_list = bb; if (buf_break && bb->col > settings.max_col) { return; } if (!better_break (bb, buf_break)) { return; } /* Found better buf_break. Get rid of all previous possible breaks. */ buf_break = bb; for (bb = bb->prev; bb;) { buf_break_st_ty *obb = bb; bb = bb->prev; free (obb); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -