From pa.dec.com!decwrl!uunet!sparky!kent Sun Aug 11 15:55:26 PDT 1991
Article: 2610 of comp.sources.misc
Xref: pa.dec.com comp.sources.misc:2610 comp.lang.c++:15942
Newsgroups: comp.sources.misc,comp.lang.c++
Path: pa.dec.com!decwrl!uunet!sparky!kent
From: Benson I. Margulies <benson@odi.com>
Subject:  v21i100:  indent - BSD Indent with C++ support, Part03/03
Message-ID: <1991Aug8.015940.3376@sparky.IMD.Sterling.COM>
X-Md4-Signature: 64faffc46f51124e951fdad0a2b3ee85
Sender: kent@sparky.IMD.Sterling.COM (Kent Landfield)
Organization: Sterling Software, IMD
References: <csm-v21i098=indent.205411@sparky.imd.sterling.com>
Date: Thu, 8 Aug 1991 01:59:40 GMT
Approved: kent@sparky.imd.sterling.com
Lines: 1095

Submitted-by: Benson I. Margulies <benson@odi.com>
Posting-number: Volume 21, Issue 100
Archive-name: indent/part03
Environment: UNIX, C++

#! /bin/sh
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix@uunet.uu.net if you want that tool.
# Contents:  indent/args.c indent/parse.c indent/pr_comment.c
# Wrapped by kent@sparky on Wed Aug  7 19:44:13 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo '          "shar: End of archive 3 (of 3)."'
if test -f 'indent/args.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'indent/args.c'\"
else
  echo shar: Extracting \"'indent/args.c'\" \(8848 characters\)
  sed "s/^X//" >'indent/args.c' <<'END_OF_FILE'
X/*
X * Copyright (c) 1985 Sun Microsystems, Inc.
X * Copyright (c) 1980 The Regents of the University of California.
X * Copyright (c) 1976 Board of Trustees of the University of Illinois.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by the University of California, Berkeley, the University of Illinois,
X * Urbana, and Sun Microsystems, Inc.  The name of either University
X * or Sun Microsystems may not be used to endorse or promote products
X * derived from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)args.c	5.6 (Berkeley) 9/15/88";
X#endif /* not lint */
X
X/*
X * Argument scanning and profile reading code.  Default parameters are set
X * here as well.
X */
X
X#include "indent_globs.h"
X#include <sys/types.h>
X#include <ctype.h>
X
Xchar       *getenv(), *index();
X
X/* profile types */
X#define	PRO_SPECIAL	1	/* special case */
X#define	PRO_BOOL	2	/* boolean */
X#define	PRO_INT		3	/* integer */
X#define PRO_FONT	4	/* troff font */
X
X/* profile specials for booleans */
X#define	ON		1	/* turn it on */
X#define	OFF		0	/* turn it off */
X
X/* profile specials for specials */
X#define	IGN		1	/* ignore it */
X#define	CLI		2	/* case label indent (float) */
X#define	STDIN		3	/* use stdin */
X#define	KEY		4	/* type (keyword) */
X#define	CCI		5	/* case code indent (float) */
X
X/*
X * N.B.: because of the way the table here is scanned, options whose names are
X * substrings of other options must occur later; that is, with -lp vs -l, -lp
X * must be first.  Also, while (most) booleans occur more than once, the last
X * default value is the one actually assigned.
X */
Xstruct pro {
X    char       *p_name;		/* name, eg -bl, -cli */
X    int         p_type;		/* type (int, bool, special) */
X    int         p_default;	/* the default value (if int) */
X    int         p_special;	/* depends on type */
X    int        *p_obj;		/* the associated variable */
X}           pro[] = {
X
X    "T", PRO_SPECIAL, 0, KEY, 0,
X    "bacc", PRO_BOOL, false, ON, &blanklines_around_conditional_compilation,
X    "badp", PRO_BOOL, false, ON, &blanklines_after_declarations_at_proctop,
X    "bad", PRO_BOOL, false, ON, &blanklines_after_declarations,
X    "bap", PRO_BOOL, false, ON, &blanklines_after_procs,
X    "bbb", PRO_BOOL, false, ON, &blanklines_before_blockcomments,
X    "bc", PRO_BOOL, true, OFF, &ps.leave_comma,
X    "bl", PRO_BOOL, false, OFF, &btype_2,
X    "brr", PRO_BOOL, false, ON, &btype_3,
X    "br", PRO_BOOL, true, ON, &btype_2,
X    "bs", PRO_BOOL, false, ON, &Bill_Shannon,
X    "cdb", PRO_BOOL, true, ON, &comment_delimiter_on_blankline,
X    "cd", PRO_INT, 0, 0, &ps.decl_com_ind,
X    "ce", PRO_BOOL, true, ON, &cuddle_else,
X    "ci", PRO_INT, 0, 0, &continuation_indent,
X    "cli", PRO_SPECIAL, 0, CLI, 0,
X    "cci", PRO_SPECIAL, 0, CCI, 0,
X    "c", PRO_INT, 33, 0, &ps.com_ind,
X    "di", PRO_INT, 16, 0, &ps.decl_indent,
X    "dj", PRO_BOOL, false, ON, &ps.ljust_decl,
X    "d", PRO_INT, 0, 0, &ps.unindent_displace,
X    "eei", PRO_BOOL, false, ON, &extra_expression_indent,
X    "ei", PRO_BOOL, true, ON, &ps.else_if,
X    "fbc", PRO_FONT, 0, 0, (int *) &blkcomf,
X    "fbx", PRO_FONT, 0, 0, (int *) &boxcomf,
X    "fb", PRO_FONT, 0, 0, (int *) &bodyf,
X    "fc1", PRO_BOOL, true, ON, &format_col1_comments,
X    "fc", PRO_FONT, 0, 0, (int *) &scomf,
X    "fk", PRO_FONT, 0, 0, (int *) &keywordf,
X    "fs", PRO_FONT, 0, 0, (int *) &stringf,
X    "ip", PRO_BOOL, true, ON, &ps.indent_parameters,
X    "i", PRO_INT, 8, 0, &ps.ind_size,
X    "lc", PRO_INT, 0, 0, &block_comment_max_col,
X    "lp", PRO_BOOL, true, ON, &lineup_to_parens,
X    "l", PRO_INT, 78, 0, &max_col,
X    "nbacc", PRO_BOOL, false, OFF, &blanklines_around_conditional_compilation,
X    "nbadp", PRO_BOOL, false, OFF, &blanklines_after_declarations_at_proctop,
X    "nbad", PRO_BOOL, false, OFF, &blanklines_after_declarations,
X    "nbap", PRO_BOOL, false, OFF, &blanklines_after_procs,
X    "nbbb", PRO_BOOL, false, OFF, &blanklines_before_blockcomments,
X    "nbc", PRO_BOOL, true, ON, &ps.leave_comma,
X    "nbs", PRO_BOOL, false, OFF, &Bill_Shannon,
X    "ncdb", PRO_BOOL, true, OFF, &comment_delimiter_on_blankline,
X    "nce", PRO_BOOL, true, OFF, &cuddle_else,
X    "ndj", PRO_BOOL, false, OFF, &ps.ljust_decl,
X    "neei", PRO_BOOL, false, OFF, &extra_expression_indent,
X    "nei", PRO_BOOL, true, OFF, &ps.else_if,
X    "nfc1", PRO_BOOL, true, OFF, &format_col1_comments,
X    "nip", PRO_BOOL, true, OFF, &ps.indent_parameters,
X    "nlp", PRO_BOOL, true, OFF, &lineup_to_parens,
X    "npcs", PRO_BOOL, false, OFF, &proc_calls_space,
X    "npro", PRO_SPECIAL, 0, IGN, 0,
X    "nprs", PRO_BOOL, false, OFF, &parens_space,
X    "npsl", PRO_BOOL, true, OFF, &procnames_start_line,
X    "nps", PRO_BOOL, false, OFF, &pointer_as_binop,
X    "nsc", PRO_BOOL, true, OFF, &star_comment_cont,
X    "nsob", PRO_BOOL, false, OFF, &swallow_optional_blanklines,
X    "nv", PRO_BOOL, false, OFF, &verbose,
X    "pcs", PRO_BOOL, false, ON, &proc_calls_space,
X    "prs", PRO_BOOL, false, ON, &parens_space,
X    "psl", PRO_BOOL, true, ON, &procnames_start_line,
X    "ps", PRO_BOOL, false, ON, &pointer_as_binop,
X    "sc", PRO_BOOL, true, ON, &star_comment_cont,
X    "sob", PRO_BOOL, false, ON, &swallow_optional_blanklines,
X    "st", PRO_SPECIAL, 0, STDIN, 0,
X    "troff", PRO_BOOL, false, ON, &troff,
X    "v", PRO_BOOL, false, ON, &verbose,
X     "+", PRO_BOOL, false, ON, &cplus,
X /* whew! */
X    0, 0, 0, 0, 0
X};
X
X/*
X * set_profile reads $HOME/.indent.pro and ./.indent.pro and handles arguments
X * given in these files.
X */
Xset_profile()
X{
X    register FILE *f;
X    char        fname[BUFSIZ];
X    static char prof[] = ".indent.pro";
X
X    sprintf(fname, "%s/%s", getenv("HOME"), prof);
X    if ((f = fopen(fname, "r")) != NULL) {
X	scan_profile(f);
X	(void) fclose(f);
X    }
X    if ((f = fopen(prof, "r")) != NULL) {
X	scan_profile(f);
X	(void) fclose(f);
X    }
X}
X
Xscan_profile(f)
X    register FILE *f;
X{
X    register int i;
X    register char *p;
X    char        buf[BUFSIZ];
X
X    while (1) {
X	for (p = buf; (i = getc(f)) != EOF && (*p = i) > ' '; ++p);
X	if (p != buf) {
X	    *p++ = 0;
X	    if (verbose)
X		printf("profile: %s\n", buf);
X	    set_option(buf);
X	}
X	else if (i == EOF)
X	    return;
X    }
X}
X
Xchar       *param_start;
X
Xeqin(s1, s2)
X    register char *s1;
X    register char *s2;
X{
X    while (*s1) {
X	if (*s1++ != *s2++)
X	    return (false);
X    }
X    param_start = s2;
X    return (true);
X}
X
X/*
X * Set the defaults.
X */
Xset_defaults()
X{
X    register struct pro *p;
X
X    /*
X     * Because ps.case_indent and ps.case_code_indent are floats, we can't
X     * initialize them from the table:
X     */
X    ps.case_indent = 0.0;	/* -cli0.0 */
X    ps.case_code_indent = 1.0;	/* -cci1.0 */
X    for (p = pro; p->p_name; p++)
X	if (p->p_type != PRO_SPECIAL && p->p_type != PRO_FONT)
X	    *p->p_obj = p->p_default;
X}
X
Xset_option(arg)
X    register char *arg;
X{
X    register struct pro *p;
X    extern double atof();
X
X    arg++;			/* ignore leading "-" */
X    for (p = pro; p->p_name; p++)
X	if (*p->p_name == *arg && eqin(p->p_name, arg))
X	    goto found;
X    fprintf(stderr, "indent: unknown parameter \"%s\"\n", arg - 1);
X    exit(1);
Xfound:
X    switch (p->p_type) {
X
X    case PRO_SPECIAL:
X	switch (p->p_special) {
X
X	case IGN:
X	    break;
X
X	case CLI:
X	    if (*param_start == 0)
X		goto need_param;
X	    ps.case_indent = atof(param_start);
X	    break;
X
X	case CCI:
X	    if (*param_start == 0)
X		goto need_param;
X	    ps.case_code_indent = atof(param_start);
X	    break;
X
X	case STDIN:
X	    if (input == 0)
X		input = stdin;
X	    if (output == 0)
X		output = stdout;
X	    break;
X
X	case KEY:
X	    if (*param_start == 0)
X		goto need_param;
X	    {
X		register char *str = (char *) malloc(strlen(param_start) + 1);
X		strcpy(str, param_start);
X		addkey(str, 4);
X	    }
X	    break;
X
X	default:
X	    fprintf(stderr, "\
Xindent: set_option: internal error: p_special %d\n", p->p_special);
X	    exit(1);
X	}
X	break;
X
X    case PRO_BOOL:
X	if (p->p_special == OFF)
X	    *p->p_obj = false;
X	else
X	    *p->p_obj = true;
X	break;
X
X    case PRO_INT:
X	if (*param_start == 0) {
X    need_param:
X	    fprintf(stderr, "indent: ``%s'' requires a parameter\n",
X		    arg - 1);
X	    exit(1);
X	}
X	*p->p_obj = atoi(param_start);
X	break;
X
X    case PRO_FONT:
X	parsefont((struct fstate *) p->p_obj, param_start);
X	break;
X
X    default:
X	fprintf(stderr, "indent: set_option: internal error: p_type %d\n",
X		p->p_type);
X	exit(1);
X    }
X}
END_OF_FILE
  if test 8848 -ne `wc -c <'indent/args.c'`; then
    echo shar: \"'indent/args.c'\" unpacked with wrong size!
  fi
  # end of 'indent/args.c'
fi
if test -f 'indent/parse.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'indent/parse.c'\"
else
  echo shar: Extracting \"'indent/parse.c'\" \(8434 characters\)
  sed "s/^X//" >'indent/parse.c' <<'END_OF_FILE'
X/*
X * Copyright (c) 1985 Sun Microsystems, Inc.
X * Copyright (c) 1980 The Regents of the University of California.
X * Copyright (c) 1976 Board of Trustees of the University of Illinois.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by the University of California, Berkeley, the University of Illinois,
X * Urbana, and Sun Microsystems, Inc.  The name of either University
X * or Sun Microsystems may not be used to endorse or promote products
X * derived from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)parse.c	5.8 (Berkeley) 9/15/88";
X#endif /* not lint */
X
X#include "./indent_globs.h"
X#include "./indent_codes.h"
X
X
X
X
Xparse(tk)
X    int         tk;		/* the code for the construct scanned */
X{
X    int         i;
X
X#ifdef debug
X    printf("%2d - %s\n", tk, token);
X#endif
X
X    while (ps.p_stack[ps.tos] == ifhead && tk != elselit) {
X	/* true if we have an if without an else */
X	ps.p_stack[ps.tos] = stmt;	/* apply the if(..) stmt ::= stmt
X					 * reduction */
X	reduce();		/* see if this allows any reduction */
X    }
X
X
X    switch (tk) {		/* go on and figure out what to do with the
X				 * input */
X
X    case decl:			/* scanned a declaration word */
X	ps.search_brace = btype_2 && !btype_3;
X	/* indicate that following brace should be on same line */
X	if (ps.p_stack[ps.tos] != decl) {	/* only put one declaration
X						 * onto stack */
X	    break_comma = true;	/* while in declaration, newline should be
X				 * forced after comma */
X	    ps.p_stack[++ps.tos] = decl;
X	    ps.il[ps.tos] = ps.i_l_follow;
X
X	    if (ps.ljust_decl) {/* only do if we want left justified
X				 * declarations */
X		ps.ind_level = 0;
X		for (i = ps.tos - 1; i > 0; --i)
X		    if (ps.p_stack[i] == decl)
X			++ps.ind_level;	/* indentation is number of
X					 * declaration levels deep we are */
X		ps.i_l_follow = ps.ind_level;
X	    }
X	}
X	break;
X
X    case ifstmt:		/* scanned if (...) */
X	if (ps.p_stack[ps.tos] == elsehead && ps.else_if)	/* "else if ..." */
X	    ps.i_l_follow = ps.il[ps.tos];
X    case dolit:		/* 'do' */
X    case forstmt:		/* for (...) */
X	ps.p_stack[++ps.tos] = tk;
X	ps.il[ps.tos] = ps.ind_level = ps.i_l_follow;
X	++ps.i_l_follow;	/* subsequent statements should be indented 1 */
X	ps.search_brace = btype_2 && !btype_3;
X	break;
X
X    case lbrace:		/* scanned { */
X	break_comma = false;	/* don't break comma in an initial list */
X	if (ps.p_stack[ps.tos] == stmt || ps.p_stack[ps.tos] == decl
X		|| ps.p_stack[ps.tos] == stmtl)
X	    ++ps.i_l_follow;	/* it is a random, isolated stmt group or a
X				 * declaration */
X	else {
X	    if (s_code == e_code) {
X		/*
X		 * only do this if there is nothing on the line
X		 */
X		--ps.ind_level;
X		/*
X		 * it is a group as part of a while, for, etc.
X		 */
X		if (ps.p_stack[ps.tos] == swstmt && ps.case_indent >= 1 &&
X		    ps.case_code_indent >= 1)
X		    --ps.ind_level;
X		/*
X		 * for a switch, brace should be two levels out from the code
X		 */
X	    }
X	}
X
X	ps.p_stack[++ps.tos] = lbrace;
X	ps.il[ps.tos] = ps.ind_level;
X	ps.p_stack[++ps.tos] = stmt;
X	/* allow null stmt between braces */
X	ps.il[ps.tos] = ps.i_l_follow;
X	break;
X
X    case whilestmt:		/* scanned while (...) */
X	if (ps.p_stack[ps.tos] == dohead) {
X	    /* it is matched with do stmt */
X	    ps.ind_level = ps.i_l_follow = ps.il[ps.tos];
X	    ps.p_stack[++ps.tos] = whilestmt;
X	    ps.il[ps.tos] = ps.ind_level = ps.i_l_follow;
X	}
X	else {			/* it is a while loop */
X	    ps.p_stack[++ps.tos] = whilestmt;
X	    ps.il[ps.tos] = ps.i_l_follow;
X	    ++ps.i_l_follow;
X	    ps.search_brace = btype_2 && !btype_3;
X	}
X
X	break;
X
X    case elselit:		/* scanned an else */
X
X	if (ps.p_stack[ps.tos] != ifhead)
X	    diag(1, "Unmatched 'else'");
X	else {
X	    ps.ind_level = ps.il[ps.tos];	/* indentation for else should
X						 * be same as for if */
X	    ps.i_l_follow = ps.ind_level + 1;	/* everything following should
X						 * be in 1 level */
X	    ps.p_stack[ps.tos] = elsehead;
X	    /* remember if with else */
X	    ps.search_brace = (btype_2 && !btype_3) | ps.else_if;
X	}
X	break;
X
X    case rbrace:		/* scanned a } */
X	/* stack should have <lbrace> <stmt> or <lbrace> <stmtl> */
X	if (ps.p_stack[ps.tos - 1] == lbrace) {
X	    if (btype_3)
X		ps.i_l_follow = ps.il[--ps.tos];
X	    else
X		ps.ind_level = ps.i_l_follow = ps.il[--ps.tos];
X	    ps.p_stack[ps.tos] = stmt;
X	}
X	else
X	    diag(1, "Stmt nesting error.");
X	break;
X
X    case swstmt:		/* had switch (...) */
X	ps.p_stack[++ps.tos] = swstmt;
X	ps.cstk[ps.tos] = case_ind;
X	/* save current case indent level */
X	ps.il[ps.tos] = ps.i_l_follow;
X	case_ind = ps.i_l_follow + ps.case_indent;
X	/*
X	 * cases should be one level down from switch
X	 */
X	ps.i_l_follow += ps.case_indent + ps.case_code_indent;
X	/*
X	 * statements should be two levels in
X	 */
X	ps.search_brace = btype_2 && !btype_3;
X	break;
X
X    case semicolon:		/* this indicates a simple stmt */
X	break_comma = false;	/* turn off flag to break after commas in a
X				 * declaration */
X	ps.p_stack[++ps.tos] = stmt;
X	ps.il[ps.tos] = ps.ind_level;
X	break;
X
X    default:			/* this is an error */
X	diag(1, "Unknown code to parser");
X	return;
X
X
X    }				/* end of switch */
X
X    reduce();			/* see if any reduction can be done */
X
X#ifdef debug
X    for (i = 1; i <= ps.tos; ++i)
X	printf("(%d %d)", ps.p_stack[i], ps.il[i]);
X    printf("\n");
X#endif
X
X    return;
X}
X
X/*
X * Copyright (C) 1976 by the Board of Trustees of the University of Illinois
X * 
X * All rights reserved
X * 
X * 
X * NAME: reduce
X * 
X * FUNCTION: Implements the reduce part of the parsing algorithm
X * 
X * ALGORITHM: The following reductions are done.  Reductions are repeated until
X * no more are possible.
X * 
X * Old TOS		New TOS <stmt> <stmt>	<stmtl> <stmtl> <stmt>	<stmtl> do
X * <stmt>	"dostmt" if <stmt>	"ifstmt" switch <stmt>	<stmt> decl
X * <stmt>	<stmt> "ifelse" <stmt>	<stmt> for <stmt>	<stmt> while
X * <stmt>	<stmt> "dostmt" while	<stmt>
X * 
X * On each reduction, ps.i_l_follow (the indentation for the following line) is
X * set to the indentation level associated with the old TOS.
X * 
X * PARAMETERS: None
X * 
X * RETURNS: Nothing
X * 
X * GLOBALS: ps.cstk ps.i_l_follow = ps.il ps.p_stack = ps.tos =
X * 
X * CALLS: None
X * 
X * CALLED BY: parse 
X * 
X * HISTORY: initial coding 	November 1976	D A Willcox of CAC
X * 
X */
X/*----------------------------------------------*\
X|   REDUCTION PHASE				    |
X\*----------------------------------------------*/
Xreduce()
X{
X
X    register int i;
X
X    for (;;) {			/* keep looping until there is nothing left to
X				 * reduce */
X
X	switch (ps.p_stack[ps.tos]) {
X
X	case stmt:
X	    switch (ps.p_stack[ps.tos - 1]) {
X
X	    case stmt:
X	    case stmtl:
X		/* stmtl stmt or stmt stmt */
X		ps.p_stack[--ps.tos] = stmtl;
X		break;
X
X	    case dolit:	/* <do> <stmt> */
X		ps.p_stack[--ps.tos] = dohead;
X		ps.i_l_follow = ps.il[ps.tos];
X		break;
X
X	    case ifstmt:
X		/* <if> <stmt> */
X		ps.p_stack[--ps.tos] = ifhead;
X		for (i = ps.tos - 1;
X			(
X			 ps.p_stack[i] != stmt
X			 &&
X			 ps.p_stack[i] != stmtl
X			 &&
X			 ps.p_stack[i] != lbrace
X			 );
X			--i);
X		ps.i_l_follow = ps.il[i];
X		/*
X		 * for the time being, we will assume that there is no else on
X		 * this if, and set the indentation level accordingly. If an
X		 * else is scanned, it will be fixed up later
X		 */
X		break;
X
X	    case swstmt:
X		/* <switch> <stmt> */
X		case_ind = ps.cstk[ps.tos - 1];
X
X	    case decl:		/* finish of a declaration */
X	    case elsehead:
X		/* <<if> <stmt> else> <stmt> */
X	    case forstmt:
X		/* <for> <stmt> */
X	    case whilestmt:
X		/* <while> <stmt> */
X		ps.p_stack[--ps.tos] = stmt;
X		ps.i_l_follow = ps.il[ps.tos];
X		break;
X
X	    default:		/* <anything else> <stmt> */
X		return;
X
X	    }			/* end of section for <stmt> on top of stack */
X	    break;
X
X	case whilestmt:	/* while (...) on top */
X	    if (ps.p_stack[ps.tos - 1] == dohead) {
X		/* it is termination of a do while */
X		ps.p_stack[--ps.tos] = stmt;
X		break;
X	    }
X	    else
X		return;
X
X	default:		/* anything else on top */
X	    return;
X
X	}
X    }
X}
END_OF_FILE
  if test 8434 -ne `wc -c <'indent/parse.c'`; then
    echo shar: \"'indent/parse.c'\" unpacked with wrong size!
  fi
  # end of 'indent/parse.c'
fi
if test -f 'indent/pr_comment.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'indent/pr_comment.c'\"
else
  echo shar: Extracting \"'indent/pr_comment.c'\" \(12009 characters\)
  sed "s/^X//" >'indent/pr_comment.c' <<'END_OF_FILE'
X/*
X * Copyright (c) 1985 Sun Microsystems, Inc.
X * Copyright (c) 1980 The Regents of the University of California.
X * Copyright (c) 1976 Board of Trustees of the University of Illinois.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by the University of California, Berkeley, the University of Illinois,
X * Urbana, and Sun Microsystems, Inc.  The name of either University
X * or Sun Microsystems may not be used to endorse or promote products
X * derived from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)pr_comment.c	5.9 (Berkeley) 9/15/88";
X#endif /* not lint */
X
X/*
X * NAME:
X *	pr_comment
X *
X * FUNCTION:
X *	This routine takes care of scanning and printing comments.
X *
X * ALGORITHM:
X *	1) Decide where the comment should be aligned, and if lines should
X *	   be broken.
X *	2) If lines should not be broken and filled, just copy up to end of
X *	   comment.
X *	3) If lines should be filled, then scan thru input_buffer copying
X *	   characters to com_buf.  Remember where the last blank, tab, or
X *	   newline was.  When line is filled, print up to last blank and
X *	   continue copying.
X *
X * HISTORY:
X *	November 1976	D A Willcox of CAC	Initial coding
X *	12/6/76		D A Willcox of CAC	Modification to handle
X *						UNIX-style comments
X *
X */
X
X/*
X * this routine processes comments.  It makes an attempt to keep comments from
X * going over the max line length.  If a line is too long, it moves everything
X * from the last blank to the next comment line.  Blanks and tabs from the
X * beginning of the input line are removed
X */
X
X
X#include "indent_globs.h"
X
X
Xpr_comment()
X{
X    int         now_col;	/* column we are in now */
X    int         adj_max_col;	/* Adjusted max_col for when we decide to
X				 * spill comments over the right margin */
X    char       *last_bl;	/* points to the last blank in the output
X				 * buffer */
X    char       *t_ptr;		/* used for moving string */
X    int         unix_comment;	/* tri-state variable used to decide if it is
X				 * a unix-style comment. 0 means only blanks
X				 * since /*, 1 means regular style comment, 2
X				 * means unix style comment */
X    int         break_delim = comment_delimiter_on_blankline;
X    int         l_just_saw_decl = ps.just_saw_decl;
X    /*
X     * int         ps.last_nl = 0;	/* true iff the last significant thing
X     * weve seen is a newline
X     */
X    int         one_liner = 1;	/* true iff this comment is a one-liner */
X    adj_max_col = max_col;
X    ps.just_saw_decl = 0;
X    last_bl = 0;		/* no blanks found so far */
X    ps.box_com = false;		/* at first, assume that we are not in
X					 * a boxed comment or some other
X					 * comment that should not be touched */
X    ++ps.out_coms;		/* keep track of number of comments */
X    unix_comment = 1;		/* set flag to let us figure out if there is a
X				 * unix-style comment ** DISABLED: use 0 to
X				 * reenable this hack! */
X
X    /* Figure where to align and how to treat the comment */
X
X    if (ps.col_1 && !format_col1_comments) {	/* if comment starts in column
X						 * 1 it should not be touched */
X	ps.box_com = true;
X	ps.com_col = 1;
X    }
X    else {
X	if (*buf_ptr == '-' || *buf_ptr == '*') {
X	    ps.box_com = true;	/* a comment with a '-' or '*' immediately
X				 * after the /* is assumed to be a boxed
X				 * comment */
X	    break_delim = 0;
X	}
X	if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) {
X	    /* klg: check only if this line is blank */
X	    /*
X	     * If this (*and previous lines are*) blank, dont put comment way
X	     * out at left
X	     */
X	    ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
X	    adj_max_col = block_comment_max_col;
X	    if (ps.com_col <= 1)
X		ps.com_col = 1 + !format_col1_comments;
X	}
X	else {
X	    register    target_col;
X	    break_delim = 0;
X	    if (s_code != e_code)
X		target_col = count_spaces(compute_code_target(), s_code);
X	    else {
X		target_col = 1;
X		if (s_lab != e_lab)
X		    target_col = count_spaces(compute_label_target(), s_lab);
X	    }
X	    ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? ps.decl_com_ind : ps.com_ind;
X	    if (ps.com_col < target_col)
X		ps.com_col = ((target_col + 7) & ~7) + 1;
X	    if (ps.com_col + 24 > adj_max_col)
X		adj_max_col = ps.com_col + 24;
X	}
X    }
X    if (ps.box_com) {
X	buf_ptr[-2] = 0;
X	ps.n_comment_delta = 1 - count_spaces(1, in_buffer);
X	buf_ptr[-2] = '/';
X    }
X    else {
X	ps.n_comment_delta = 0;
X	while (*buf_ptr == ' ' || *buf_ptr == '\t')
X	    buf_ptr++;
X    }
X    ps.comment_delta = 0;
X    *e_com++ = '/';		/* put '/*' into buffer */
X    if (ps.cc_comment)		/*  (or '//') */
X	*e_com++ = '/';
X    else
X	*e_com++ = '*';
X    if (*buf_ptr != ' ' && !ps.box_com)
X	*e_com++ = ' ';
X
X    *e_com = '\0';
X    if (troff) {
X	now_col = 1;
X	adj_max_col = 80;
X    }
X    else
X	now_col = count_spaces(ps.com_col, s_com);	/* figure what column we
X							 * would be in if we
X							 * printed the comment
X							 * now */
X
X    /* Start to copy the comment */
X
X    while (1) {			/* this loop will go until the comment is
X				 * copied */
X	if (*buf_ptr >= 040 && *buf_ptr != '*')
X	    ps.last_nl = 0;
X	check_size(com);
X	switch (*buf_ptr) {	/* this checks for various spcl cases */
X	case 014:		/* check for a form feed */
X	    if (!ps.box_com) {	/* in a text comment, break the line here */
X		ps.use_ff = true;
X		/* fix so dump_line uses a form feed */
X		dump_line();
X		last_bl = 0;
X		*e_com++ = ' ';
X		*e_com++ = '*';
X		*e_com++ = ' ';
X		while (*++buf_ptr == ' ' || *buf_ptr == '\t');
X	    }
X	    else {
X		if (++buf_ptr >= buf_end)
X		    fill_buffer();
X		*e_com++ = 014;
X	    }
X	    break;
X
X	case '\n':
X	    if (ps.cc_comment) {
X		*e_com = '\0';
X		dump_line();
X		ps.cc_comment = 0;
X		ps.just_saw_decl = l_just_saw_decl; /* ?? */
X		if (++buf_ptr >= buf_end)	/* eat '\n' */
X		    fill_buffer();
X		return;
X	    }
X	    if (had_eof) {	/* check for unexpected eof */
X		printf("Unterminated comment\n");
X		*e_com = '\0';
X		dump_line();
X		return;
X	    }
X	    one_liner = 0;
X	    if (ps.box_com || ps.last_nl) {	/* if this is a boxed comment,
X						 * we dont ignore the newline */
X		if (s_com == e_com) {
X		    *e_com++ = ' ';
X		    *e_com++ = ' ';
X		}
X		*e_com = '\0';
X		if (!ps.box_com && e_com - s_com > 3) {
X		    if (break_delim == 1 && s_com[0] == '/'
X			    && s_com[1] == '*' && s_com[2] == ' ') {
X			char       *t = e_com;
X			break_delim = 2;
X			e_com = s_com + 2;
X			*e_com = 0;
X			if (blanklines_before_blockcomments)
X			    prefix_blankline_requested = 1;
X			dump_line();
X			e_com = t;
X			s_com[0] = s_com[1] = s_com[2] = ' ';
X		    }
X		    dump_line();
X		    check_size(com);
X		    *e_com++ = ' ';
X		    *e_com++ = ' ';
X		}
X		dump_line();
X		now_col = ps.com_col;
X	    }
X	    else {
X		ps.last_nl = 1;
X		if (unix_comment != 1) {	/* we not are in unix_style
X						 * comment */
X		    if (unix_comment == 0 && s_code == e_code) {
X			/*
X			 * if it is a UNIX-style comment, ignore the
X			 * requirement that previous line be blank for
X			 * unindention
X			 */
X			ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
X			if (ps.com_col <= 1)
X			    ps.com_col = 2;
X		    }
X		    unix_comment = 2;	/* permanently remember that we are in
X					 * this type of comment */
X		    dump_line();
X		    ++line_no;
X		    now_col = ps.com_col;
X		    *e_com++ = ' ';
X		    /*
X		     * fix so that the star at the start of the line will line
X		     * up
X		     */
X		    do		/* flush leading white space */
X			if (++buf_ptr >= buf_end)
X			    fill_buffer();
X		    while (*buf_ptr == ' ' || *buf_ptr == '\t');
X		    break;
X		}
X		if (*(e_com - 1) == ' ' || *(e_com - 1) == '\t')
X		    last_bl = e_com - 1;
X		/*
X		 * if there was a space at the end of the last line, remember
X		 * where it was
X		 */
X		else {		/* otherwise, insert one */
X		    last_bl = e_com;
X		    check_size(com);
X		    *e_com++ = ' ';
X		    ++now_col;
X		}
X	    }
X	    ++line_no;		/* keep track of input line number */
X	    if (!ps.box_com) {
X		int         nstar = 1;
X		do {		/* flush any blanks and/or tabs at start of
X				 * next line */
X		    if (++buf_ptr >= buf_end)
X			fill_buffer();
X		    if (*buf_ptr == '*' && --nstar >= 0) {
X			if (++buf_ptr >= buf_end)
X			    fill_buffer();
X			if (*buf_ptr == '/')
X			    goto end_of_comment;
X		    }
X		} while (*buf_ptr == ' ' || *buf_ptr == '\t');
X	    }
X	    else if (++buf_ptr >= buf_end)
X		fill_buffer();
X	    break;		/* end of case for newline */
X
X	case '*':		/* must check for possibility of being at end
X				 * of comment */
X	    if (++buf_ptr >= buf_end)	/* get to next char after * */
X		fill_buffer();
X
X	    if (unix_comment == 0)	/* set flag to show we are not in
X					 * unix-style comment */
X		unix_comment = 1;
X
X	    if (*buf_ptr == '/') {	/* it is the end!!! */
X	end_of_comment:
X		if (++buf_ptr >= buf_end)
X		    fill_buffer();
X
X		if (*(e_com - 1) != ' ' && !ps.box_com) {	/* insure blank before
X								 * end */
X		    *e_com++ = ' ';
X		    ++now_col;
X		}
X		if (break_delim == 1 && !one_liner && s_com[0] == '/'
X			&& s_com[1] == '*' && s_com[2] == ' ') {
X		    char       *t = e_com;
X		    break_delim = 2;
X		    e_com = s_com + 2;
X		    *e_com = 0;
X		    if (blanklines_before_blockcomments)
X			prefix_blankline_requested = 1;
X		    dump_line();
X		    e_com = t;
X		    s_com[0] = s_com[1] = s_com[2] = ' ';
X		}
X		if (break_delim == 2 && e_com > s_com + 3
X			 /* now_col > adj_max_col - 2 && !ps.box_com */ ) {
X		    *e_com = '\0';
X		    dump_line();
X		    now_col = ps.com_col;
X		}
X		check_size(com);
X		*e_com++ = '*';
X		*e_com++ = '/';
X		*e_com = '\0';
X		ps.just_saw_decl = l_just_saw_decl;
X		return;
X	    }
X	    else {		/* handle isolated '*' */
X		*e_com++ = '*';
X		++now_col;
X	    }
X	    break;
X	default:		/* we have a random char */
X	    if (unix_comment == 0 && *buf_ptr != ' ' && *buf_ptr != '\t')
X		unix_comment = 1;	/* we are not in unix-style comment */
X
X	    *e_com = *buf_ptr++;
X	    if (buf_ptr >= buf_end)
X		fill_buffer();
X
X	    if (*e_com == '\t')	/* keep track of column */
X		now_col = ((now_col - 1) & tabmask) + tabsize + 1;
X	    else if (*e_com == '\b')	/* this is a backspace */
X		--now_col;
X	    else
X		++now_col;
X
X	    if (*e_com == ' ' || *e_com == '\t')
X		last_bl = e_com;
X	    /* remember we saw a blank */
X
X	    ++e_com;
X	    if (now_col > adj_max_col && !ps.box_com && unix_comment == 1 && e_com[-1] > ' ') {
X		/*
X		 * the comment is too long, it must be broken up
X		 */
X		if (break_delim == 1 && s_com[0] == '/'
X			&& s_com[1] == '*' && s_com[2] == ' ') {
X		    char       *t = e_com;
X		    break_delim = 2;
X		    e_com = s_com + 2;
X		    *e_com = 0;
X		    if (blanklines_before_blockcomments)
X			prefix_blankline_requested = 1;
X		    dump_line();
X		    e_com = t;
X		    s_com[0] = s_com[1] = s_com[2] = ' ';
X		}
X		if (last_bl == 0) {	/* we have seen no blanks */
X		    last_bl = e_com;	/* fake it */
X		    *e_com++ = ' ';
X		}
X		*e_com = '\0';	/* print what we have */
X		*last_bl = '\0';
X		while (last_bl > s_com && last_bl[-1] < 040)
X		    *--last_bl = 0;
X		e_com = last_bl;
X		dump_line();
X
X		*e_com++ = ' ';	/* add blanks for continuation */
X		*e_com++ = ' ';
X		*e_com++ = ' ';
X
X		t_ptr = last_bl + 1;
X		last_bl = 0;
X		if (t_ptr >= e_com) {
X		    while (*t_ptr == ' ' || *t_ptr == '\t')
X			t_ptr++;
X		    while (*t_ptr != '\0') {	/* move unprinted part of
X						 * comment down in buffer */
X			if (*t_ptr == ' ' || *t_ptr == '\t')
X			    last_bl = e_com;
X			*e_com++ = *t_ptr++;
X		    }
X		}
X		*e_com = '\0';
X		now_col = count_spaces(ps.com_col, s_com);	/* recompute current
X								 * position */
X	    }
X	    break;
X	}
X    }
X}
END_OF_FILE
  if test 12009 -ne `wc -c <'indent/pr_comment.c'`; then
    echo shar: \"'indent/pr_comment.c'\" unpacked with wrong size!
  fi
  # end of 'indent/pr_comment.c'
fi
echo shar: End of archive 3 \(of 3\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 3 archives.
    rm -f ark[1-9]isdone
else
    echo You still must unpack the following archives:
    echo "        " ${MISSING}
fi
exit 0
exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.


