// // aegis - project change supervisor // Copyright (C) 1991-1993, 1995, 1999, 2002-2006, 2008 Peter Miller // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see // . // #include #include #include #include #include #include #define INDENT 4 static FILE *fp; static const char *fn; static int depth; static int in_col; static int out_col; static int continuation_line; static int within_string; // // Function Name: // indent_more // // Description: // The indent_more function is used to increase the indenting // beyond the automatically calculated indent. // // Preconditions: // There must be a matching indent_less call. // // validataion: // none // // Passed: // nothing // // Returns: // nothing // void indent_more(void) { ++depth; } // // Function Name: // indent_less // // Description: // The indent_less function is used to decrease the indenting // to less than the automatically calculated indent. // // Preconditions: // There must be a matching indent_more call. // // validataion: // none // // Passed: // nothing // // Returns: // nothing // void indent_less(void) { --depth; } // // Function Name: // indent_putchar // // Description: // The indent_putchar function is used to emity characters. // It keeps track of (){}[] pairs and indents between them. // Leading whitespace is suppressed and replaced with its own // idea of indenting. // // Preconditions: // none // // validation: // none // // Passed: // 'c' the character to emit. // void indent_putchar(int c) { assert(fp); switch (c) { case '\n': fputc('\n', fp); #ifdef DEBUG fflush(fp); #endif in_col = 0; out_col = 0; if (continuation_line == 1) continuation_line = 2; else continuation_line = 0; break; case ' ': if (out_col) ++in_col; break; case '\t': if (out_col) in_col = (in_col / INDENT + 1) * INDENT; break; case '\1': if (!out_col) break; if (in_col >= INDENT * depth + 16) ++in_col; else in_col = INDENT * depth + 16; break; case '"': case '\'': if (within_string == 0) within_string = c; else if (continuation_line != 1 && within_string == c) within_string = 0; goto normal; case '}': case ')': case ']': if (!within_string) --depth; // fall through default: normal: if (!out_col && c != '#' && continuation_line != 2) in_col += INDENT * depth; while (((out_col + 8) & -8) <= in_col && out_col + 1 < in_col) { fputc('\t', fp); out_col = (out_col + 8) & -8; } while (out_col < in_col) { fputc(' ', fp); ++out_col; } if (!within_string && (c == '{' || c == '(' || c == '[')) ++depth; fputc(c, fp); in_col++; out_col = in_col; continuation_line = (c == '\\'); break; } if (ferror(fp)) nfatal("write \"%s\"", fn); } // // Function Name: // indent_printf // // Description: // As putchar is to indent_putchasr, printf is to indent_printf. // // Preconditions: // none // // Validation: // none // // Passed: // 's' format string // ... and optional arguments // // Returns: // nothing // void indent_printf(const char *s, ...) { va_list ap; char buffer[2000]; va_start(ap, s); vsnprintf(buffer, sizeof(buffer), s, ap); va_end(ap); for (s = buffer; *s; ++s) indent_putchar(*s); } void indent_open(const char *s) { trace(("indent_open(s = %08lX)\n{\n", (long)s)); if (!s) { fp = stdout; s = "(stdout)"; } else { trace_string(s); fp = fopen(s, "w"); if (!fp) nfatal("open \"%s\"", s); } trace_pointer(fp); fn = s; depth = 0; in_col = 0; out_col = 0; continuation_line = 0; trace(("}\n")); } void indent_close(void) { trace(("indent_close()\n{\n")); trace_pointer(fp); if (out_col) indent_putchar('\n'); if (fflush(fp)) nfatal("write \"%s\"", fn); if (fp != stdout && fclose(fp)) nfatal("close \"%s\"", fn); fp = 0; fn = 0; trace(("}\n")); }