+++ /dev/null
-.TH ENTAB 1 local
-.SH NAME
-entab - tab processor
-.SH SYNOPSIS
-.nf
-entab [-cdq] [-s min_spaces] [-t tab_width] [file ... ]
-detab [-cq] [-s min_spaces] [-t tab_width] [file ... ]
-.fi
-.SH DESCRIPTION
-Entab is a program designed to selectively add or remove tabs
-from a file based on user-supplied criteria.
-In default mode, entab prints the specified files to standard output
-with the optimal mix of tabs and spaces.
-Tabs default to every 8 characters, and tabs are used only when they
-can replace more than one space, unlike 'col' which uses tabs wherever
-possible.
-.LP
-The options are:
-.in +0.5i
-.nf
--c Clip trailing tabs and spaces from each line.
--d Delete all tabs from output
--q Protect single and double-quoted strings from tab replacement.
- (This option is useful when operating on source code.
- Line continuation with back-slashes is also understood.)
--s Minimum spaces needed to replace with a tab (default = 2).
--t Number of spaces in a tab stop (default = 8).
-.fi
-.in -0.5i
-Detab is equivalent to entab -d.
-.SH NOTES
-Entab has improved tab handling for certain situations.
-It only replaces tabs if there is a user-defined number of spaces
-to be saved.
-Other tab replacement programs put tabs wherever
-possible, so if two words are separated by one space, and that
-space is on a tab stop, a tab is inserted.
-Then, when words are added to the left, the words are shifted over,
-leaving a large gap.
-The quote-protection option allows tab replacement without
-quoted strings being changed.
-Useful when strings in source code will not have the same tab stops
-when executed in the program.
-.LP
-To change a text file created on a system with one size of tab
-stop to display properly on a device with different tab setting,
-use detab (or entab -d) to remove tabs from the file with the
-tab size set to the original tab size, then use entab to re-tab
-the file with the new tab size.
-.SH AUTHOR
-Bruce Momjian, bruce@momjian.us
+++ /dev/null
-/*
- * entab.c - adds/removes tabs from text files
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <unistd.h>
-
-#if defined(WIN32) || defined(__CYGWIN__)
-#define PG_BINARY_R "rb"
-#else
-#define PG_BINARY_R "r"
-#endif
-
-#define NUL '\0'
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-extern char *optarg;
-extern int optind;
-
-
-static void
-output_accumulated_spaces(int *prv_spaces, char **dst)
-{
- for (; *prv_spaces > 0; (*prv_spaces)--)
- *((*dst)++) = ' ';
-}
-
-
-static void
-trim_trailing_whitespace(int *prv_spaces, char **dst, char *out_line)
-{
- while (*dst > out_line &&
- (*((*dst) - 1) == ' ' || *((*dst) - 1) == '\t'))
- (*dst)--;
- *prv_spaces = 0;
-}
-
-
-int
-main(int argc, char **argv)
-{
- int tab_size = 8,
- min_spaces = 2,
- only_comment_periods = FALSE,
- protect_quotes = FALSE,
- protect_leading_whitespace = FALSE,
- del_tabs = FALSE,
- clip_lines = FALSE,
- in_comment = FALSE,
- was_period = FALSE,
- prv_spaces,
- col_in_tab,
- escaped,
- nxt_spaces,
- in_leading_whitespace;
- char in_line[BUFSIZ],
- out_line[BUFSIZ],
- *src,
- *dst,
- quote_char,
- *cp;
- int ch;
- FILE *in_file;
-
- if ((cp = strrchr(argv[0], '/')) != NULL)
- ++cp;
- else
- cp = argv[0];
- if (strcmp(cp, "detab") == 0)
- del_tabs = 1;
-
- while ((ch = getopt(argc, argv, "cdhlmqs:t:")) != -1)
- switch (ch)
- {
- case 'c':
- clip_lines = TRUE;
- break;
- case 'd':
- del_tabs = TRUE;
- break;
- case 'l':
- protect_leading_whitespace = TRUE;
- break;
- case 'm':
- /* only process text followed by periods in C comments */
- only_comment_periods = TRUE;
- break;
- case 'q':
- protect_quotes = TRUE;
- break;
- case 's':
- min_spaces = atoi(optarg);
- break;
- case 't':
- tab_size = atoi(optarg);
- break;
- case 'h':
- case '?':
- fprintf(stderr, "USAGE: %s [ -cdqst ] [file ...]\n\
- -c (clip trailing whitespace)\n\
- -d (delete tabs)\n\
- -l (protect leading whitespace)\n\
- -m (only C comment periods)\n\
- -q (protect quotes)\n\
- -s minimum_spaces\n\
- -t tab_width\n",
- cp);
- exit(0);
- }
-
- argv += optind;
- argc -= optind;
-
- /* process arguments */
- do
- {
- if (argc < 1)
- in_file = stdin;
- else
- {
- if ((in_file = fopen(*argv, PG_BINARY_R)) == NULL)
- {
- fprintf(stderr, "Cannot open file %s: %s\n", argv[0], strerror(errno));
- exit(1);
- }
- argv++;
- }
-
- escaped = FALSE;
-
- /* process lines */
- while (fgets(in_line, sizeof(in_line), in_file) != NULL)
- {
- col_in_tab = 0;
- prv_spaces = 0;
- src = in_line; /* points to current processed char */
- dst = out_line; /* points to next unallocated char */
- if (escaped == FALSE)
- quote_char = ' ';
- escaped = FALSE;
- in_leading_whitespace = TRUE;
-
- /* process line */
- while (*src != NUL)
- {
- col_in_tab++;
-
- /* look backward so we handle slash-star-slash properly */
- if (!in_comment && src > in_line &&
- *(src - 1) == '/' && *src == '*')
- in_comment = TRUE;
- else if (in_comment && *src == '*' && *(src + 1) == '/')
- in_comment = FALSE;
-
- /* Is this a potential space/tab replacement? */
- if ((!only_comment_periods || (in_comment && was_period)) &&
- (!protect_leading_whitespace || !in_leading_whitespace) &&
- quote_char == ' ' && (*src == ' ' || *src == '\t'))
- {
- if (*src == '\t')
- {
- prv_spaces += tab_size - col_in_tab + 1;
- col_in_tab = tab_size;
- }
- else
- prv_spaces++;
-
- /* Are we at a tab stop? */
- if (col_in_tab == tab_size)
- {
- /*
- * Is the next character going to be a tab? We do tab
- * replacement in the current spot if the next char is
- * going to be a tab and ignore min_spaces.
- */
- nxt_spaces = 0;
- while (1)
- {
- /* Have we reached non-whitespace? */
- if (*(src + nxt_spaces + 1) == NUL ||
- (*(src + nxt_spaces + 1) != ' ' &&
- *(src + nxt_spaces + 1) != '\t'))
- break;
- /* count spaces */
- if (*(src + nxt_spaces + 1) == ' ')
- ++nxt_spaces;
- /* Have we found a forward tab? */
- if (*(src + nxt_spaces + 1) == '\t' ||
- nxt_spaces == tab_size)
- {
- nxt_spaces = tab_size;
- break;
- }
- }
- /* Do tab replacment for spaces? */
- if ((prv_spaces >= min_spaces ||
- nxt_spaces == tab_size) &&
- del_tabs == FALSE)
- {
- *(dst++) = '\t';
- prv_spaces = 0;
- }
- else
- output_accumulated_spaces(&prv_spaces, &dst);
- }
- }
- /* Not a potential space/tab replacement */
- else
- {
- /* allow leading stars in comments */
- if (in_leading_whitespace && *src != ' ' && *src != '\t' &&
- (!in_comment || *src != '*'))
- in_leading_whitespace = FALSE;
- was_period = (*src == '.');
- /* output accumulated spaces */
- output_accumulated_spaces(&prv_spaces, &dst);
- /* This can only happen in a quote. */
- if (*src == '\t')
- col_in_tab = 0;
- /* visual backspace? */
- if (*src == '\b')
- col_in_tab -= 2;
- /* Do we process quotes? */
- if (escaped == FALSE && protect_quotes == TRUE)
- {
- if (*src == '\\')
- escaped = TRUE;
- /* Is this a quote character? */
- if (*src == '"' || *src == '\'')
- {
- /* toggle quote mode */
- if (quote_char == ' ')
- quote_char = *src;
- else if (*src == quote_char)
- quote_char = ' ';
- }
- }
- /* newlines/CRs do not terminate escapes */
- else if (*src != '\r' && *src != '\n')
- escaped = FALSE;
-
- /* reached newline/CR; clip line? */
- if ((*src == '\r' || *src == '\n') &&
- clip_lines == TRUE &&
- quote_char == ' ' &&
- escaped == FALSE)
- trim_trailing_whitespace(&prv_spaces, &dst, out_line);
- *(dst++) = *src;
- }
- col_in_tab %= tab_size;
- ++src;
- }
- /* for cases where the last line of file has no newline */
- if (clip_lines == TRUE && escaped == FALSE)
- trim_trailing_whitespace(&prv_spaces, &dst, out_line);
- output_accumulated_spaces(&prv_spaces, &dst);
- *dst = NUL;
-
- if (fputs(out_line, stdout) == EOF)
- {
- fprintf(stderr, "Cannot write to output file %s: %s\n", argv[0], strerror(errno));
- exit(1);
- }
- }
- } while (--argc > 0);
- return 0;
-}
$typedefs_file ||= shift if @ARGV && $ARGV[0] !~ /\.[ch]$/;
$typedefs_file ||= $ENV{PGTYPEDEFS};
-# build mode sets PGINDENT and PGENTAB
+# build mode sets PGINDENT
$indent ||= $ENV{PGINDENT} || $ENV{INDENT} || "pg_bsd_indent";
-my $entab = $ENV{PGENTAB} || "entab";
# no non-option arguments given. so do everything in the current directory
$code_base ||= '.' unless @ARGV;
sub check_indent
{
- system("$entab < $devnull");
- if ($?)
- {
- print STDERR
-"Go to the src/tools/entab directory and do 'make' and 'make install'.\n",
- "This will put the 'entab' command in your path.\n",
- "Then run $0 again.\n";
- exit 1;
- }
-
system("$indent -? < $devnull > $devnull 2>&1");
if ($? >> 8 != 1)
{
}
-# XXX Ideally we'd implement entab/detab in pure perl.
-
-sub detab
-{
- my $source = shift;
-
- my $tmp_fh = new File::Temp(TEMPLATE => "pgdetXXXXX");
- print $tmp_fh $source;
- $tmp_fh->close();
-
- open(my $entab, '-|', "$entab -d -t4 -qc " . $tmp_fh->filename);
- local ($/) = undef;
- $source = <$entab>;
- close($entab);
-
- return $source;
-}
-
-
-sub entab
-{
- my $source = shift;
-
- my $tmp_fh = new File::Temp(TEMPLATE => "pgentXXXXX");
- print $tmp_fh $source;
- $tmp_fh->close();
-
- open(
- my $entab,
- '-|',
- "$entab -d -t8 -qc "
- . $tmp_fh->filename
- . " | $entab -t4 -qc | $entab -d -t4 -m");
- local ($/) = undef;
- $source = <$entab>;
- close($entab);
-
- return $source;
-}
-
# for development diagnostics
sub diff
$ENV{PGINDENT} = abs_path('pg_bsd_indent');
- chdir "../../entab";
- system("make > $devnull 2>&1");
-
- $ENV{PGENTAB} = abs_path('entab');
-
chdir $save_dir;
}
system("rm -rf src/tools/pgindent/pg_bsd_indent");
system("rm -f src/tools/pgindent/tmp_typedefs.list");
-
- system("git clean -q -f src/tools/entab");
}