📄 io.c
字号:
/* Copyright (c) 1992, Free Software Foundation, Inc. All rights reserved. Copyright (c) 1985 Sun Microsystems, Inc. Copyright (c) 1980 The Regents of the University of California. Copyright (c) 1976 Board of Trustees of the University of Illinois. All rights reserved. Redistribution and use in source and binary forms are permitted provided that the above copyright notice and this paragraph are duplicated in all such forms and that any documentation, advertising materials, and other materials related to such distribution and use acknowledge that the software was developed by the University of California, Berkeley, the University of Illinois, Urbana, and Sun Microsystems, Inc. The name of either University or Sun Microsystems may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */#include "sys.h"#include "indent.h"#include <ctype.h>#ifdef VMS# include <file.h># include <types.h># include <stat.h>#else /* not VMS *//* POSIX says that <fcntl.h> should exist. Some systems might need to use <sys/fcntl.h> or <sys/file.h> instead. */#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#endif /* not VMS *//* number of levels a label is placed to left of code */#define LABEL_OFFSET 2/* Stuff that needs to be shared with the rest of indent. Documented in indent.h. */char *in_prog;char *in_prog_pos;char *cur_line;unsigned long in_prog_size;FILE *output;char *buf_ptr;char *buf_end;int had_eof;int out_lines;int com_lines;int suppress_blanklines = 0;static int comment_open;int paren_target;/* Use `perror' to print the system error message caused by OFFENDER. */static char *errbuf;voidsys_error (offender) char *offender;{ int size = strlen (offender); static int buffer_size; if (errbuf == 0) { buffer_size = size + 10; /* Extra for random unix lossage */ errbuf = (char *) xmalloc (buffer_size); } else if (size + 10 > buffer_size) { buffer_size = size + 10; errbuf = xrealloc (errbuf, buffer_size); } sprintf (errbuf, "indent: %s", offender); perror (errbuf); exit (1);}#ifdef VMSintvms_read (int file_desc, void *buffer, int nbytes){ register char *bufp; register int nread, nleft; bufp = buffer; nread = 0; nleft = nbytes; while (nread = read (file_desc, bufp, nleft), nread > 0) { bufp += nread; nleft -= nread; if (nleft < 0) sys_error ("Internal buffering error"); } return nread;}#endif /* VMS */INLINE intcount_columns (column, bp) int column; char *bp;{ while (*bp != '\0') { switch (*bp++) { case EOL: case 014: /* form feed */ column = 1; break; case TAB: column += tabsize - (column - 1) % tabsize; break; case 010: /* backspace */ --column; break; default: ++column; break; } } return column;}/* Return the column we are at in the input line. */INLINE intcurrent_column (){ char *p; int column = 1; if (buf_ptr >= save_com.ptr && buf_ptr <= save_com.end) p = save_com.ptr; else p = cur_line;#if 0 /* Paranoia */ if (! (buf_ptr >= cur_line && buf_ptr < in_prog_pos)) abort ();#endif column = 1; while (p < buf_ptr) switch (*p++) { case EOL: case 014: /* form feed */ column = 1; break; case TAB: column += tabsize - (column - 1) % tabsize;#if 0 column += tabsize - (column % tabsize) + 1;#endif break; case '\b': /* backspace */ column--; break; default: column++; break; } return column;}voiddump_line (){ /* dump_line is the routine that actually effects the printing of the new source. It prints the label section, followed by the code section with the appropriate nesting level, followed by any comments */ register int cur_col; register int target_col = 0; static not_first_line; if (parser_state_tos->procname[0]) { if (troff) { if (comment_open) { comment_open = 0; fprintf (output, ".*/\n"); } fprintf (output, ".Pr \"%.*s\"\n", parser_state_tos->procname_end - parser_state_tos->procname, parser_state_tos->procname); } parser_state_tos->ind_level = 0; parser_state_tos->procname = "\0"; } /* A blank line */ if (s_code == e_code && s_lab == e_lab && s_com == e_com) { /* If we have a formfeed on a blank line, we should just output it, rather than treat it as a normal blank line. */ if (parser_state_tos->use_ff) { putc ('\014', output); parser_state_tos->use_ff = false; } else { if (suppress_blanklines > 0) suppress_blanklines--; else { parser_state_tos->bl_line = true; n_real_blanklines++; } } } else { suppress_blanklines = 0; parser_state_tos->bl_line = false; if (prefix_blankline_requested && not_first_line && n_real_blanklines == 0) n_real_blanklines = 1; else if (swallow_optional_blanklines && n_real_blanklines > 1) n_real_blanklines = 1; while (--n_real_blanklines >= 0) putc (EOL, output); n_real_blanklines = 0; if (parser_state_tos->ind_level == 0) parser_state_tos->ind_stmt = 0; /* this is a class A kludge. dont do additional statement indentation if we are at bracket level 0 */ if (e_lab != s_lab || e_code != s_code) ++code_lines; /* keep count of lines with code */ if (e_lab != s_lab) { /* print lab, if any */ if (comment_open) { comment_open = 0; fprintf (output, ".*/\n"); } while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == TAB)) e_lab--; cur_col = pad_output (1, compute_label_target ()); if (s_lab[0] == '#' && (strncmp (s_lab, "#else", 5) == 0 || strncmp (s_lab, "#endif", 6) == 0)) { /* Treat #else and #endif as a special case because any text after #else or #endif should be converted to a comment. */ register char *s = s_lab; if (e_lab[-1] == EOL) e_lab--; do putc (*s++, output); while (s < e_lab && 'a' <= *s && *s <= 'z'); while ((*s == ' ' || *s == TAB) && s < e_lab) s++; if (s < e_lab) { if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) fprintf (output, (tabsize > 1 ? "\t%.*s" : " %.*s"), e_lab - s, s); else fprintf (output, (tabsize > 1 ? "\t/* %.*s */" : " /* %.*s */"), e_lab - s, s); } } else fprintf (output, "%.*s", e_lab - s_lab, s_lab); cur_col = count_columns (cur_col, s_lab); } else cur_col = 1; /* there is no label section */ parser_state_tos->pcase = false; if (s_code != e_code) { /* print code section, if any */ register char *p; register i; if (comment_open) { comment_open = 0; fprintf (output, ".*/\n"); } /* If a comment begins this line, then indent it to the right column for comments, otherwise the line starts with code, so indent it for code. */ if (embedded_comment_on_line == 1) target_col = parser_state_tos->com_col; else target_col = compute_code_target (); /* If a line ends in an lparen character, the following line should not line up with the parenthesis, but should be indented by the usual amount. */ if (parser_state_tos->last_token == lparen) { parser_state_tos->paren_indents[parser_state_tos->p_l_follow - 1] += ind_size - 1; } for (i = 0; i < parser_state_tos->p_l_follow; i++) if (parser_state_tos->paren_indents[i] >= 0) parser_state_tos->paren_indents[i] = -(parser_state_tos->paren_indents[i] + target_col); cur_col = pad_output (cur_col, target_col); for (p = s_code; p < e_code; p++) {#if 0 if (*p == (char) 0200) fprintf (output, "%d", (int) (target_col * 7)); else if (tabsize > 1)#endif putc (*p, output);#if 0 else { int width = 1; if (*p == TAB) width = (tabsize - ((cur_col - 1) % tabsize)); cur_col += width; while (width--) putc (*p, output); }#endif } cur_col = count_columns (cur_col, s_code); } if (s_com != e_com) { if (troff) { int all_here = 0; register char *p; if (e_com[-1] == '/' && e_com[-2] == '*') e_com -= 2, all_here++; while (e_com > s_com && e_com[-1] == ' ') e_com--; *e_com = 0; p = s_com; while (*p == ' ') p++; if (p[0] == '/' && p[1] == '*') p += 2, all_here++; else if (p[0] == '*') p += p[1] == '/' ? 2 : 1; while (*p == ' ') p++; if (*p == 0) goto inhibit_newline; if (comment_open < 2 && parser_state_tos->box_com) { comment_open = 0; fprintf (output, ".*/\n"); } if (comment_open == 0) { if ('a' <= *p && *p <= 'z') *p = *p + 'A' - 'a'; if (e_com - p < 50 && all_here == 2) { register char *follow = p; fprintf (output, "\n.nr C! \\w\1"); while (follow < e_com) { switch (*follow) { case EOL: putc (' ', output); case 1: break; case '\\': putc ('\\', output); default: putc (*follow, output); } follow++; } putc (1, output); } fprintf (output, "\n./* %dp %d %dp\n", (int) (parser_state_tos->com_col * 7), (int) ((s_code != e_code || s_lab != e_lab) - parser_state_tos->box_com), (int) (target_col * 7)); } comment_open = 1 + parser_state_tos->box_com; while (*p) { if (*p == BACKSLASH) putc (BACKSLASH, output); putc (*p++, output); } } else { /* Here for comment printing. This code is new as of version 1.8 */ register target = parser_state_tos->com_col; register char *com_st = s_com; if (cur_col > target) { putc (EOL, output); cur_col = 1; ++out_lines; } cur_col = pad_output (cur_col, target); fwrite (com_st, e_com - com_st, 1, output); cur_col += e_com - com_st; com_lines++; } } else if (embedded_comment_on_line) com_lines++; embedded_comment_on_line = 0; if (parser_state_tos->use_ff) { putc ('\014', output); parser_state_tos->use_ff = false; } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -