1375 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1375 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/**
 | 
						|
 * 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.
 | 
						|
 */
 | 
						|
 | 
						|
/* ported to MINIX by: Robert R. Hall <hall@pnet01.cts.com>  */
 | 
						|
 | 
						|
#define _POSIX_SOURCE 1
 | 
						|
#define	PUBLIC
 | 
						|
#define NAME_SIZE _POSIX_NAME_MAX
 | 
						|
 | 
						|
#include <ctype.h>
 | 
						|
#include <string.h>
 | 
						|
#include <sys/types.h>
 | 
						|
#include <fcntl.h>
 | 
						|
#include <unistd.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <limits.h>
 | 
						|
#include "globs.h"
 | 
						|
#include "codes.h"
 | 
						|
#include "proto.h"
 | 
						|
 | 
						|
char           *in_name = "Standard Input";	/* will always point to
 | 
						|
						   name of input file */
 | 
						|
char           *out_name = "Standard Output";	/* will always point to
 | 
						|
						   name of output file */
 | 
						|
char            bakfile[60];
 | 
						|
 | 
						|
void main(argc, argv)
 | 
						|
   int             argc;
 | 
						|
   char          **argv;
 | 
						|
{
 | 
						|
 | 
						|
   extern int      found_err;		/* flag set in diag() on error */
 | 
						|
   int             dec_ind;		/* current indentation for
 | 
						|
					   declarations */
 | 
						|
   int             di_stack[20];	/* a stack of structure
 | 
						|
					   indentation levels */
 | 
						|
   int             flushed_nl;		/* used when buffering up
 | 
						|
					   comments to remember that a
 | 
						|
					   newline was passed over */
 | 
						|
   int             force_nl;		/* when true, code must be
 | 
						|
					   broken */
 | 
						|
   int             hd_type;		/* used to store type of stmt
 | 
						|
					   for if (...), for (...), etc */
 | 
						|
   register int    i;			/* local loop counter */
 | 
						|
   int             scase;		/* set to true when we see a
 | 
						|
					   case, so we will know what
 | 
						|
					   to do with the following
 | 
						|
					   colon */
 | 
						|
   int             sp_sw;		/* when true, we are in the
 | 
						|
					   expressin of if(...),
 | 
						|
					   while(...), etc. */
 | 
						|
   int             squest;		/* when this is positive, we
 | 
						|
					   have seen a ? without the
 | 
						|
					   matching : in a <c>?<s>:<s>
 | 
						|
					   construct */
 | 
						|
   register char  *t_ptr;		/* used for copying tokens */
 | 
						|
   int             type_code;		/* the type of token, returned
 | 
						|
					   by lexi */
 | 
						|
 | 
						|
   int             last_else = 0;	/* true iff last keyword was an
 | 
						|
					   else */
 | 
						|
 | 
						|
 | 
						|
   /*-----------------------------------------------*\
 | 
						|
    |		      INITIALIZATION		      |
 | 
						|
    \*-----------------------------------------------*/
 | 
						|
 | 
						|
 | 
						|
   ps.p_stack[0] = stmt;		/* this is the parser's stack */
 | 
						|
   ps.last_nl = true;			/* this is true if the last
 | 
						|
					   thing scanned was a newline */
 | 
						|
   ps.last_token = semicolon;
 | 
						|
   combuf = (char *) malloc(bufsize);
 | 
						|
   labbuf = (char *) malloc(bufsize);
 | 
						|
   codebuf = (char *) malloc(bufsize);
 | 
						|
   l_com = combuf + bufsize - 5;
 | 
						|
   l_lab = labbuf + bufsize - 5;
 | 
						|
   l_code = codebuf + bufsize - 5;
 | 
						|
   combuf[0] = codebuf[0] = labbuf[0] = ' ';	/* set up code, label,
 | 
						|
						   and comment buffers */
 | 
						|
   combuf[1] = codebuf[1] = labbuf[1] = '\0';
 | 
						|
   ps.else_if = 1;			/* Default else-if special
 | 
						|
					   processing to on */
 | 
						|
   s_lab = e_lab = labbuf + 1;
 | 
						|
   s_code = e_code = codebuf + 1;
 | 
						|
   s_com = e_com = combuf + 1;
 | 
						|
 | 
						|
   buf_ptr = buf_end = in_buffer;
 | 
						|
   line_no = 1;
 | 
						|
   had_eof = ps.in_decl = ps.decl_on_line = break_comma = false;
 | 
						|
   sp_sw = force_nl = false;
 | 
						|
   ps.in_or_st = false;
 | 
						|
   ps.bl_line = true;
 | 
						|
   dec_ind = 0;
 | 
						|
   di_stack[ps.dec_nest = 0] = 0;
 | 
						|
   ps.want_blank = ps.in_stmt = ps.ind_stmt = false;
 | 
						|
 | 
						|
 | 
						|
   scase = ps.pcase = false;
 | 
						|
   squest = 0;
 | 
						|
   sc_end = 0;
 | 
						|
   bp_save = 0;
 | 
						|
   be_save = 0;
 | 
						|
 | 
						|
   output = 0;
 | 
						|
 | 
						|
 | 
						|
 | 
						|
   /*--------------------------------------------------*\
 | 
						|
    |   		COMMAND LINE SCAN		 |
 | 
						|
    \*--------------------------------------------------*/
 | 
						|
 | 
						|
#ifdef undef
 | 
						|
   max_col = 78;			/* -l78 */
 | 
						|
   lineup_to_parens = 1;		/* -lp */
 | 
						|
   ps.ljust_decl = 0;			/* -ndj */
 | 
						|
   ps.com_ind = 33;			/* -c33 */
 | 
						|
   star_comment_cont = 1;		/* -sc */
 | 
						|
   ps.ind_size = 8;			/* -i8 */
 | 
						|
   verbose = 0;
 | 
						|
   ps.decl_indent = 16;			/* -di16 */
 | 
						|
   ps.indent_parameters = 1;		/* -ip */
 | 
						|
   ps.decl_com_ind = 0;			/* if this is not set to some
 | 
						|
					   positive value by an arg, we
 | 
						|
					   will set this equal to
 | 
						|
					   ps.com_ind */
 | 
						|
   btype_2 = 1;				/* -br */
 | 
						|
   cuddle_else = 1;			/* -ce */
 | 
						|
   ps.unindent_displace = 0;		/* -d0 */
 | 
						|
   ps.case_indent = 0;			/* -cli0 */
 | 
						|
   format_col1_comments = 1;		/* -fc1 */
 | 
						|
   procnames_start_line = 1;		/* -psl */
 | 
						|
   proc_calls_space = 0;		/* -npcs */
 | 
						|
   comment_delimiter_on_blankline = 1;	/* -cdb */
 | 
						|
   ps.leave_comma = 1;			/* -nbc */
 | 
						|
#endif
 | 
						|
 | 
						|
   for (i = 1; i < argc; ++i)
 | 
						|
      if (strcmp(argv[i], "-npro") == 0)
 | 
						|
	 break;
 | 
						|
   set_defaults();
 | 
						|
   if (i >= argc)
 | 
						|
      set_profile();
 | 
						|
 | 
						|
   for (i = 1; i < argc; ++i)
 | 
						|
   {
 | 
						|
 | 
						|
      /* look thru args (if any) for changes to defaults */
 | 
						|
      if (argv[i][0] != '-')
 | 
						|
      {					/* no flag on parameter */
 | 
						|
	 if (input == 0)
 | 
						|
	 {				/* we must have the input file */
 | 
						|
	    in_name = argv[i];		/* remember name of input file */
 | 
						|
	    input = fopen(in_name, "r");
 | 
						|
	    if (input == 0)
 | 
						|
	    {				/* check for open error */
 | 
						|
	       fprintf(stderr, "indent: can't open %s\n", argv[i]);
 | 
						|
	       exit(1);
 | 
						|
	    }
 | 
						|
	    continue;
 | 
						|
	 } else if (output == 0)
 | 
						|
	 {				/* we have the output file */
 | 
						|
	    out_name = argv[i];		/* remember name of output file */
 | 
						|
	    if (strcmp(in_name, out_name) == 0)
 | 
						|
	    {				/* attempt to overwrite the
 | 
						|
					   file */
 | 
						|
	       fprintf(stderr, "indent: input and output files must be different\n");
 | 
						|
	       exit(1);
 | 
						|
	    }
 | 
						|
	    output = fopen(out_name, "w");
 | 
						|
	    if (output == 0)
 | 
						|
	    {				/* check for create error */
 | 
						|
	       fprintf(stderr, "indent: can't create %s\n", argv[i]);
 | 
						|
	       exit(1);
 | 
						|
	    }
 | 
						|
	    continue;
 | 
						|
	 }
 | 
						|
	 fprintf(stderr, "indent: unknown parameter: %s\n", argv[i]);
 | 
						|
	 exit(1);
 | 
						|
      } else
 | 
						|
	 set_option(argv[i]);
 | 
						|
   }					/* end of for */
 | 
						|
   if (input == 0)
 | 
						|
   {
 | 
						|
      fprintf(stderr, "indent: usage: indent file [ outfile ] [ options ]\n");
 | 
						|
      exit(1);
 | 
						|
   }
 | 
						|
   if (output == 0)
 | 
						|
      if (troff)
 | 
						|
	 output = stdout;
 | 
						|
      else
 | 
						|
      {
 | 
						|
	 out_name = in_name;
 | 
						|
	 bakcopy();
 | 
						|
      }
 | 
						|
   if (ps.com_ind <= 1)
 | 
						|
      ps.com_ind = 2;			/* dont put normal comments
 | 
						|
					   before column 2 */
 | 
						|
   if (troff)
 | 
						|
   {
 | 
						|
      if (bodyf.font[0] == 0)
 | 
						|
	 parsefont(&bodyf, "R");
 | 
						|
      if (scomf.font[0] == 0)
 | 
						|
	 parsefont(&scomf, "I");
 | 
						|
      if (blkcomf.font[0] == 0)
 | 
						|
	 blkcomf = scomf, blkcomf.size += 2;
 | 
						|
      if (boxcomf.font[0] == 0)
 | 
						|
	 boxcomf = blkcomf;
 | 
						|
      if (stringf.font[0] == 0)
 | 
						|
	 parsefont(&stringf, "L");
 | 
						|
      if (keywordf.font[0] == 0)
 | 
						|
	 parsefont(&keywordf, "B");
 | 
						|
      writefdef(&bodyf, 'B');
 | 
						|
      writefdef(&scomf, 'C');
 | 
						|
      writefdef(&blkcomf, 'L');
 | 
						|
      writefdef(&boxcomf, 'X');
 | 
						|
      writefdef(&stringf, 'S');
 | 
						|
      writefdef(&keywordf, 'K');
 | 
						|
   }
 | 
						|
   if (bk_max_col <= 0)
 | 
						|
      bk_max_col = max_col;
 | 
						|
   if (ps.decl_com_ind <= 0)		/* if not specified by user,
 | 
						|
					   set this */
 | 
						|
      ps.decl_com_ind = ps.ljust_decl ? (ps.com_ind <= 10 ? 2 : ps.com_ind - 8) : ps.com_ind;
 | 
						|
   if (continuation_indent == 0)
 | 
						|
      continuation_indent = ps.ind_size;
 | 
						|
   fill_buffer();			/* get first batch of stuff
 | 
						|
					   into input buffer */
 | 
						|
 | 
						|
   parse(semicolon);
 | 
						|
   {
 | 
						|
      register char  *p = buf_ptr;
 | 
						|
      register        col = 1;
 | 
						|
 | 
						|
      while (1)
 | 
						|
      {
 | 
						|
	 if (*p == ' ')
 | 
						|
	    col++;
 | 
						|
	 else if (*p == '\t')
 | 
						|
	    col = ((col - 1) & ~7) + 9;
 | 
						|
	 else
 | 
						|
	    break;
 | 
						|
	 p++;
 | 
						|
      };
 | 
						|
      if (col > ps.ind_size)
 | 
						|
	 ps.ind_level = ps.i_l_follow = col / ps.ind_size;
 | 
						|
   }
 | 
						|
   if (troff)
 | 
						|
   {
 | 
						|
      register char  *p = in_name, *beg = in_name;
 | 
						|
 | 
						|
      while (*p)
 | 
						|
	 if (*p++ == '/')
 | 
						|
	    beg = p;
 | 
						|
      fprintf(output, ".Fn \"%s\"\n", beg);
 | 
						|
   }
 | 
						|
   /* START OF MAIN LOOP */
 | 
						|
 | 
						|
   while (1)
 | 
						|
   {					/* this is the main loop.  it
 | 
						|
					   will go until we reach eof */
 | 
						|
      int             is_procname;
 | 
						|
 | 
						|
      type_code = lexi();		/* lexi reads one token.  The
 | 
						|
					   actual characters read are
 | 
						|
					   stored in "token". lexi
 | 
						|
					   returns a code indicating
 | 
						|
					   the type of token */
 | 
						|
      is_procname = ps.procname[0];
 | 
						|
 | 
						|
      /* The following code moves everything following an if (), while
 | 
						|
         (), else, etc. up to the start of the following stmt to a
 | 
						|
         buffer. This allows proper handling of both kinds of brace
 | 
						|
         placement. */
 | 
						|
 | 
						|
      flushed_nl = false;
 | 
						|
      while (ps.search_brace)
 | 
						|
      {					/* if we scanned an if(),
 | 
						|
					   while(), etc., we might need
 | 
						|
					   to copy stuff into a buffer
 | 
						|
					   we must loop, copying stuff
 | 
						|
					   into save_com, until we find
 | 
						|
					   the start of the stmt which
 | 
						|
					   follows the if, or whatever */
 | 
						|
	 switch (type_code)
 | 
						|
	 {
 | 
						|
	 case newline:
 | 
						|
	    ++line_no;
 | 
						|
	    flushed_nl = true;
 | 
						|
	 case form_feed:
 | 
						|
	    break;			/* form feeds and newlines
 | 
						|
					   found here will be ignored */
 | 
						|
 | 
						|
	 case lbrace:			/* this is a brace that starts
 | 
						|
					   the compound stmt */
 | 
						|
	    if (sc_end == 0)
 | 
						|
	    {				/* ignore buffering if a
 | 
						|
					   comment wasnt stored up */
 | 
						|
	       ps.search_brace = false;
 | 
						|
	       goto check_type;
 | 
						|
	    }
 | 
						|
	    if (btype_2)
 | 
						|
	    {
 | 
						|
	       save_com[0] = '{';	/* we either want to put the
 | 
						|
					   brace right after the if */
 | 
						|
	       goto sw_buffer;		/* go to common code to get out
 | 
						|
					   of this loop */
 | 
						|
	    }
 | 
						|
/*
 | 
						|
 * Something is buffered up in save_com, and -bl processing is in effect.
 | 
						|
 * Add the brace after the comment so it will come out on the next line.
 | 
						|
 */
 | 
						|
	    flushed_nl = 0;	/* comment can start on the same line */
 | 
						|
	    *sc_end++ = '\n';	/* break line after comment */
 | 
						|
	    *sc_end++ = '{';
 | 
						|
	    goto sw_buffer;
 | 
						|
 | 
						|
	 case comment:			/* we have a comment, so we
 | 
						|
					   must copy it into the buffer */
 | 
						|
	    if (!flushed_nl || sc_end != 0)
 | 
						|
	    {
 | 
						|
	       if (sc_end == 0)
 | 
						|
	       {			/* if this is the first
 | 
						|
					   comment, we must set up the
 | 
						|
					   buffer */
 | 
						|
		  save_com[0] = save_com[1] = ' ';
 | 
						|
		  sc_end = &(save_com[2]);
 | 
						|
	       } else
 | 
						|
	       {
 | 
						|
		  *sc_end++ = '\n';	/* add newline between comments */
 | 
						|
		  *sc_end++ = ' ';
 | 
						|
		  --line_no;
 | 
						|
	       }
 | 
						|
	       *sc_end++ = '/';		/* copy in start of comment */
 | 
						|
	       *sc_end++ = '*';
 | 
						|
 | 
						|
	       for (;;)
 | 
						|
	       {			/* loop until we get to the end
 | 
						|
					   of the comment */
 | 
						|
		  *sc_end = *buf_ptr++;
 | 
						|
		  if (buf_ptr >= buf_end)
 | 
						|
		     fill_buffer();
 | 
						|
 | 
						|
		  if (*sc_end++ == '*' && *buf_ptr == '/')
 | 
						|
		     break;		/* we are at end of comment */
 | 
						|
 | 
						|
		  if (sc_end >= &(save_com[sc_size]))
 | 
						|
		  {			/* check for temp buffer
 | 
						|
					   overflow */
 | 
						|
		     diag(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever.");
 | 
						|
		     fflush(output);
 | 
						|
		     exit(1);
 | 
						|
		  }
 | 
						|
	       }
 | 
						|
	       *sc_end++ = '/';		/* add ending slash */
 | 
						|
	       if (++buf_ptr >= buf_end)/* get past / in buffer */
 | 
						|
		  fill_buffer();
 | 
						|
	       break;
 | 
						|
	    }
 | 
						|
	 default:			/* it is the start of a normal
 | 
						|
					   statment */
 | 
						|
	    if (flushed_nl)		/* if we flushed a newline,
 | 
						|
					   make sure it is put back */
 | 
						|
	       force_nl = true;
 | 
						|
	    if ((type_code == sp_paren && *token == 'i'
 | 
						|
		    && last_else && ps.else_if)
 | 
						|
		|| (type_code == sp_nparen && *token == 'e'
 | 
						|
		    && e_code != s_code && e_code[-1] == '}'))
 | 
						|
	       force_nl = false;
 | 
						|
 | 
						|
	    if (sc_end == 0)
 | 
						|
	    {				/* ignore buffering if comment
 | 
						|
					   wasnt saved up */
 | 
						|
	       ps.search_brace = false;
 | 
						|
	       goto check_type;
 | 
						|
	    }
 | 
						|
	    if (force_nl)
 | 
						|
	    {				/* if we should insert a nl
 | 
						|
					   here, put it into the buffer */
 | 
						|
	       force_nl = false;
 | 
						|
	       --line_no;		/* this will be re-increased
 | 
						|
					   when the nl is read from the
 | 
						|
					   buffer */
 | 
						|
	       *sc_end++ = '\n';
 | 
						|
	       *sc_end++ = ' ';
 | 
						|
	       if (verbose && !flushed_nl)	/* print error msg if
 | 
						|
						   the line was not
 | 
						|
						   already broken */
 | 
						|
		  diag(0, "Line broken");
 | 
						|
	       flushed_nl = false;
 | 
						|
	    }
 | 
						|
	    for (t_ptr = token; *t_ptr; ++t_ptr)
 | 
						|
	       *sc_end++ = *t_ptr;	/* copy token into temp buffer */
 | 
						|
	    ps.procname[0] = 0;
 | 
						|
 | 
						|
      sw_buffer:
 | 
						|
	    ps.search_brace = false;	/* stop looking for start of
 | 
						|
					   stmt */
 | 
						|
	    bp_save = buf_ptr;		/* save current input buffer */
 | 
						|
	    be_save = buf_end;
 | 
						|
	    buf_ptr = save_com;		/* fix so that subsequent calls
 | 
						|
					   to lexi will take tokens out
 | 
						|
					   of save_com */
 | 
						|
	    *sc_end++ = ' ';		/* add trailing blank, just in
 | 
						|
					   case */
 | 
						|
	    buf_end = sc_end;
 | 
						|
	    sc_end = 0;
 | 
						|
	    break;
 | 
						|
	 }				/* end of switch */
 | 
						|
	 if (type_code != 0)		/* we must make this check,
 | 
						|
					   just in case there was an
 | 
						|
					   unexpected EOF */
 | 
						|
	    type_code = lexi();		/* read another token */
 | 
						|
	 /* if (ps.search_brace) ps.procname[0] = 0; */
 | 
						|
	 if ((is_procname = ps.procname[0]) && flushed_nl
 | 
						|
	     && !proc_str_line && ps.in_decl
 | 
						|
	     && type_code == ident)
 | 
						|
	    flushed_nl = 0;
 | 
						|
      }					/* end of while (search_brace) */
 | 
						|
      last_else = 0;
 | 
						|
check_type:
 | 
						|
      if (type_code == 0)
 | 
						|
      {					/* we got eof */
 | 
						|
	 if (s_lab != e_lab || s_code != e_code
 | 
						|
	     || s_com != e_com)		/* must dump end of line */
 | 
						|
	    dump_line();
 | 
						|
	 if (ps.tos > 1)		/* check for balanced braces */
 | 
						|
	    diag(1, "Stuff missing from end of file.");
 | 
						|
 | 
						|
	 if (verbose)
 | 
						|
	 {
 | 
						|
	    printf("There were %d output lines and %d comments\n",
 | 
						|
		   ps.out_lines, ps.out_coms);
 | 
						|
	    printf("(Lines with comments)/(Lines with code): %6d\n",
 | 
						|
		   ps.com_lines / code_lines);
 | 
						|
	 }
 | 
						|
	 fflush(output);
 | 
						|
	 exit(found_err);
 | 
						|
      }
 | 
						|
      if (
 | 
						|
	  (type_code != comment) &&
 | 
						|
	  (type_code != newline) &&
 | 
						|
	  (type_code != preesc) &&
 | 
						|
	  (type_code != form_feed))
 | 
						|
      {
 | 
						|
	 if (force_nl &&
 | 
						|
	     (type_code != semicolon) &&
 | 
						|
	     (type_code != lbrace || !btype_2))
 | 
						|
	 {
 | 
						|
	    /* we should force a broken line here */
 | 
						|
	    if (verbose && !flushed_nl)
 | 
						|
	       diag(0, "Line broken");
 | 
						|
	    flushed_nl = false;
 | 
						|
	    dump_line();
 | 
						|
	    ps.want_blank = false;	/* dont insert blank at line
 | 
						|
					   start */
 | 
						|
	    force_nl = false;
 | 
						|
	 }
 | 
						|
	 ps.in_stmt = true;		/* turn on flag which causes an
 | 
						|
					   extra level of indentation.
 | 
						|
					   this is turned off by a ; or
 | 
						|
					   '}' */
 | 
						|
	 if (s_com != e_com)
 | 
						|
	 {				/* the turkey has embedded a
 | 
						|
					   comment in a line. fix it */
 | 
						|
	    *e_code++ = ' ';
 | 
						|
	    for (t_ptr = s_com; *t_ptr; ++t_ptr)
 | 
						|
	    {
 | 
						|
	       if (e_code >= l_code)
 | 
						|
	       {
 | 
						|
		  register        nsize = l_code - s_code + 400;
 | 
						|
		  codebuf = (char *) realloc(codebuf, nsize);
 | 
						|
		  e_code = codebuf + (e_code - s_code) + 1;
 | 
						|
		  l_code = codebuf + nsize - 5;
 | 
						|
		  s_code = codebuf + 1;
 | 
						|
	       }
 | 
						|
	       *e_code++ = *t_ptr;
 | 
						|
	    }
 | 
						|
	    *e_code++ = ' ';
 | 
						|
	    *e_code = '\0';		/* null terminate code sect */
 | 
						|
	    ps.want_blank = false;
 | 
						|
	    e_com = s_com;
 | 
						|
	 }
 | 
						|
      } else if (type_code != comment)	/* preserve force_nl thru a
 | 
						|
					   comment */
 | 
						|
	 force_nl = false;		/* cancel forced newline after
 | 
						|
					   newline, form feed, etc */
 | 
						|
 | 
						|
 | 
						|
 | 
						|
      /*-----------------------------------------------------*\
 | 
						|
        |	   do switch on type of token scanned		|
 | 
						|
        \*-----------------------------------------------------*/
 | 
						|
      if (e_code >= l_code)
 | 
						|
      {
 | 
						|
	 register        nsize = l_code - s_code + 400;
 | 
						|
	 codebuf = (char *) realloc(codebuf, nsize);
 | 
						|
	 e_code = codebuf + (e_code - s_code) + 1;
 | 
						|
	 l_code = codebuf + nsize - 5;
 | 
						|
	 s_code = codebuf + 1;
 | 
						|
      }
 | 
						|
      switch (type_code)
 | 
						|
      {					/* now, decide what to do with
 | 
						|
					   the token */
 | 
						|
 | 
						|
      case form_feed:			/* found a form feed in line */
 | 
						|
	 ps.use_ff = true;		/* a form feed is treated much
 | 
						|
					   like a newline */
 | 
						|
	 dump_line();
 | 
						|
	 ps.want_blank = false;
 | 
						|
	 break;
 | 
						|
 | 
						|
      case newline:
 | 
						|
	 if (ps.last_token != comma || ps.p_l_follow > 0
 | 
						|
	     || !ps.leave_comma || ps.block_init || !break_comma || s_com != e_com)
 | 
						|
	 {
 | 
						|
	    dump_line();
 | 
						|
	    ps.want_blank = false;
 | 
						|
	 }
 | 
						|
	 ++line_no;			/* keep track of input line
 | 
						|
					   number */
 | 
						|
	 break;
 | 
						|
 | 
						|
      case lparen:			/* got a '(' or '[' */
 | 
						|
	 ++ps.p_l_follow;		/* count parens to make Healy
 | 
						|
					   happy */
 | 
						|
	 if (ps.want_blank && *token != '[' &&
 | 
						|
	     (ps.last_token != ident || proc_calls_space
 | 
						|
	      || (ps.its_a_keyword && (!ps.sizeof_keyword || Bill_Shannon))))
 | 
						|
	    *e_code++ = ' ';
 | 
						|
	 if (ps.in_decl && !ps.block_init)
 | 
						|
	    if (troff && !ps.dumped_decl_indent && !is_procname && ps.last_token == decl)
 | 
						|
	    {
 | 
						|
	       ps.dumped_decl_indent = 1;
 | 
						|
	       sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token);
 | 
						|
	       e_code += strlen(e_code);
 | 
						|
	    } else
 | 
						|
	    {
 | 
						|
	       while ((e_code - s_code) < dec_ind)
 | 
						|
	       {
 | 
						|
		  if (e_code >= l_code)
 | 
						|
		  {
 | 
						|
		     register        nsize = l_code - s_code + 400;
 | 
						|
		     codebuf = (char *) realloc(codebuf, nsize);
 | 
						|
		     e_code = codebuf + (e_code - s_code) + 1;
 | 
						|
		     l_code = codebuf + nsize - 5;
 | 
						|
		     s_code = codebuf + 1;
 | 
						|
		  }
 | 
						|
		  *e_code++ = ' ';
 | 
						|
	       }
 | 
						|
	       *e_code++ = token[0];
 | 
						|
	    }
 | 
						|
	 else
 | 
						|
	    *e_code++ = token[0];
 | 
						|
	 ps.paren_indents[ps.p_l_follow - 1] = e_code - s_code;
 | 
						|
	 if (sp_sw && ps.p_l_follow == 1 && ex_expr_indent
 | 
						|
	     && ps.paren_indents[0] < 2 * ps.ind_size)
 | 
						|
	    ps.paren_indents[0] = 2 * ps.ind_size;
 | 
						|
	 ps.want_blank = false;
 | 
						|
	 if (ps.in_or_st && *token == '(' && ps.tos <= 2)
 | 
						|
	 {
 | 
						|
	    /* this is a kluge to make sure that declarations will be
 | 
						|
	       aligned right if proc decl has an explicit type on it,
 | 
						|
	       i.e. "int a(x) {..." */
 | 
						|
	    parse(semicolon);		/* I said this was a kluge... */
 | 
						|
	    ps.in_or_st = false;	/* turn off flag for structure
 | 
						|
					   decl or initialization */
 | 
						|
	 }
 | 
						|
	 if (ps.sizeof_keyword)
 | 
						|
	    ps.sizeof_mask |= 1 << ps.p_l_follow;
 | 
						|
	 break;
 | 
						|
 | 
						|
      case rparen:			/* got a ')' or ']' */
 | 
						|
	 if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.sizeof_mask)
 | 
						|
	 {
 | 
						|
	    ps.last_u_d = true;
 | 
						|
	    ps.cast_mask &= (1 << ps.p_l_follow) - 1;
 | 
						|
	 }
 | 
						|
	 ps.sizeof_mask &= (1 << ps.p_l_follow) - 1;
 | 
						|
	 if (--ps.p_l_follow < 0)
 | 
						|
	 {
 | 
						|
	    ps.p_l_follow = 0;
 | 
						|
	    diag(0, "Extra %c", *token);
 | 
						|
	 }
 | 
						|
	 if (e_code == s_code)		/* if the paren starts the line */
 | 
						|
	    ps.paren_level = ps.p_l_follow;	/* then indent it */
 | 
						|
 | 
						|
	 *e_code++ = token[0];
 | 
						|
	 ps.want_blank = true;
 | 
						|
 | 
						|
	 if (sp_sw && (ps.p_l_follow == 0))
 | 
						|
	 {				/* check for end of if (...),
 | 
						|
					   or some such */
 | 
						|
	    sp_sw = false;
 | 
						|
	    force_nl = true;		/* must force newline after if */
 | 
						|
	    ps.last_u_d = true;		/* inform lexi that a following
 | 
						|
					   operator is unary */
 | 
						|
	    ps.in_stmt = false;		/* dont use stmt continuation
 | 
						|
					   indentation */
 | 
						|
 | 
						|
	    parse(hd_type);		/* let parser worry about if,
 | 
						|
					   or whatever */
 | 
						|
	 }
 | 
						|
	 ps.search_brace = btype_2;	/* this should insure that
 | 
						|
					   constructs such as
 | 
						|
					   main(){...} and int[]{...}
 | 
						|
					   have their braces put in the
 | 
						|
					   right place */
 | 
						|
	 break;
 | 
						|
 | 
						|
      case unary_op:			/* this could be any unary
 | 
						|
					   operation */
 | 
						|
	 if (ps.want_blank)
 | 
						|
	    *e_code++ = ' ';
 | 
						|
 | 
						|
	 if (troff && !ps.dumped_decl_indent && ps.in_decl && !is_procname)
 | 
						|
	 {
 | 
						|
	    sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token);
 | 
						|
	    ps.dumped_decl_indent = 1;
 | 
						|
	    e_code += strlen(e_code);
 | 
						|
	 } else
 | 
						|
	 {
 | 
						|
	    char           *res = token;
 | 
						|
 | 
						|
	    if (ps.in_decl && !ps.block_init)
 | 
						|
	    {				/* if this is a unary op in a
 | 
						|
					   declaration, we should
 | 
						|
					   indent this token */
 | 
						|
	       for (i = 0; token[i]; ++i);	/* find length of token */
 | 
						|
	       while ((e_code - s_code) < (dec_ind - i))
 | 
						|
	       {
 | 
						|
		  if (e_code >= l_code)
 | 
						|
		  {
 | 
						|
		     register        nsize = l_code - s_code + 400;
 | 
						|
		     codebuf = (char *) realloc(codebuf, nsize);
 | 
						|
		     e_code = codebuf + (e_code - s_code) + 1;
 | 
						|
		     l_code = codebuf + nsize - 5;
 | 
						|
		     s_code = codebuf + 1;
 | 
						|
		  }
 | 
						|
		  *e_code++ = ' ';	/* pad it */
 | 
						|
	       }
 | 
						|
	    }
 | 
						|
	    if (troff && token[0] == '-' && token[1] == '>')
 | 
						|
	       res = "\\(->";
 | 
						|
	    for (t_ptr = res; *t_ptr; ++t_ptr)
 | 
						|
	    {
 | 
						|
	       if (e_code >= l_code)
 | 
						|
	       {
 | 
						|
		  register        nsize = l_code - s_code + 400;
 | 
						|
		  codebuf = (char *) realloc(codebuf, nsize);
 | 
						|
		  e_code = codebuf + (e_code - s_code) + 1;
 | 
						|
		  l_code = codebuf + nsize - 5;
 | 
						|
		  s_code = codebuf + 1;
 | 
						|
	       }
 | 
						|
	       *e_code++ = *t_ptr;
 | 
						|
	    }
 | 
						|
	 }
 | 
						|
	 ps.want_blank = false;
 | 
						|
	 break;
 | 
						|
 | 
						|
      case binary_op:			/* any binary operation */
 | 
						|
	 if (ps.want_blank)
 | 
						|
	    *e_code++ = ' ';
 | 
						|
	 {
 | 
						|
	    char           *res = token;
 | 
						|
 | 
						|
	    if (troff)
 | 
						|
	       switch (token[0])
 | 
						|
	       {
 | 
						|
	       case '<':
 | 
						|
		  if (token[1] == '=')
 | 
						|
		     res = "\\(<=";
 | 
						|
		  break;
 | 
						|
	       case '>':
 | 
						|
		  if (token[1] == '=')
 | 
						|
		     res = "\\(>=";
 | 
						|
		  break;
 | 
						|
	       case '!':
 | 
						|
		  if (token[1] == '=')
 | 
						|
		     res = "\\(!=";
 | 
						|
		  break;
 | 
						|
	       case '|':
 | 
						|
		  if (token[1] == '|')
 | 
						|
		     res = "\\(br\\(br";
 | 
						|
		  else if (token[1] == 0)
 | 
						|
		     res = "\\(br";
 | 
						|
		  break;
 | 
						|
	       }
 | 
						|
	    for (t_ptr = res; *t_ptr; ++t_ptr)
 | 
						|
	    {
 | 
						|
	       if (e_code >= l_code)
 | 
						|
	       {
 | 
						|
		  register        nsize = l_code - s_code + 400;
 | 
						|
		  codebuf = (char *) realloc(codebuf, nsize);
 | 
						|
		  e_code = codebuf + (e_code - s_code) + 1;
 | 
						|
		  l_code = codebuf + nsize - 5;
 | 
						|
		  s_code = codebuf + 1;
 | 
						|
	       }
 | 
						|
	       *e_code++ = *t_ptr;	/* move the operator */
 | 
						|
	    }
 | 
						|
	 }
 | 
						|
	 ps.want_blank = true;
 | 
						|
	 break;
 | 
						|
 | 
						|
      case postop:			/* got a trailing ++ or -- */
 | 
						|
	 *e_code++ = token[0];
 | 
						|
	 *e_code++ = token[1];
 | 
						|
	 ps.want_blank = true;
 | 
						|
	 break;
 | 
						|
 | 
						|
      case question:			/* got a ? */
 | 
						|
	 squest++;			/* this will be used when a
 | 
						|
					   later colon appears so we
 | 
						|
					   can distinguish the
 | 
						|
					   <c>?<n>:<n> construct */
 | 
						|
	 if (ps.want_blank)
 | 
						|
	    *e_code++ = ' ';
 | 
						|
	 *e_code++ = '?';
 | 
						|
	 ps.want_blank = true;
 | 
						|
	 break;
 | 
						|
 | 
						|
      case casestmt:			/* got word 'case' or 'default' */
 | 
						|
	 scase = true;			/* so we can process the later
 | 
						|
					   colon properly */
 | 
						|
	 goto copy_id;
 | 
						|
 | 
						|
      case colon:			/* got a ':' */
 | 
						|
	 if (squest > 0)
 | 
						|
	 {				/* it is part of the <c>?<n>:
 | 
						|
					   <n> construct */
 | 
						|
	    --squest;
 | 
						|
	    if (ps.want_blank)
 | 
						|
	       *e_code++ = ' ';
 | 
						|
	    *e_code++ = ':';
 | 
						|
	    ps.want_blank = true;
 | 
						|
	    break;
 | 
						|
	 }
 | 
						|
	 if (ps.in_decl)
 | 
						|
	 {
 | 
						|
	    *e_code++ = ':';
 | 
						|
	    ps.want_blank = false;
 | 
						|
	    break;
 | 
						|
	 }
 | 
						|
	 ps.in_stmt = false;		/* seeing a label does not
 | 
						|
					   imply we are in a stmt */
 | 
						|
	 for (t_ptr = s_code; *t_ptr; ++t_ptr)
 | 
						|
	    *e_lab++ = *t_ptr;		/* turn everything so far into
 | 
						|
					   a label */
 | 
						|
	 e_code = s_code;
 | 
						|
	 *e_lab++ = ':';
 | 
						|
	 *e_lab++ = ' ';
 | 
						|
	 *e_lab = '\0';
 | 
						|
 | 
						|
	 force_nl = ps.pcase = scase;	/* ps.pcase will be used by
 | 
						|
					   dump_line to decide how to
 | 
						|
					   indent the label. force_nl
 | 
						|
					   will force a case n: to be
 | 
						|
					   on a line by itself */
 | 
						|
	 scase = false;
 | 
						|
	 ps.want_blank = false;
 | 
						|
	 break;
 | 
						|
 | 
						|
      case semicolon:			/* got a ';' */
 | 
						|
	 ps.in_or_st = false;		/* we are not in an
 | 
						|
					   initialization or structure
 | 
						|
					   declaration */
 | 
						|
	 scase = false;			/* these will only need
 | 
						|
					   resetting in a error */
 | 
						|
	 squest = 0;
 | 
						|
	 if (ps.last_token == rparen)
 | 
						|
	    ps.in_par_decl = 0;
 | 
						|
	 ps.cast_mask = 0;
 | 
						|
	 ps.sizeof_mask = 0;
 | 
						|
	 ps.block_init = 0;
 | 
						|
	 ps.block_init_level = 0;
 | 
						|
	 ps.just_saw_decl--;
 | 
						|
 | 
						|
	 if (ps.in_decl && s_code == e_code && !ps.block_init)
 | 
						|
	    while ((e_code - s_code) < (dec_ind - 1))
 | 
						|
	    {
 | 
						|
	       if (e_code >= l_code)
 | 
						|
	       {
 | 
						|
		  register        nsize = l_code - s_code + 400;
 | 
						|
		  codebuf = (char *) realloc(codebuf, nsize);
 | 
						|
		  e_code = codebuf + (e_code - s_code) + 1;
 | 
						|
		  l_code = codebuf + nsize - 5;
 | 
						|
		  s_code = codebuf + 1;
 | 
						|
	       }
 | 
						|
	       *e_code++ = ' ';
 | 
						|
	    }
 | 
						|
 | 
						|
	 ps.in_decl = (ps.dec_nest > 0);/* if we were in a first level
 | 
						|
					   structure declaration, we
 | 
						|
					   arent any more */
 | 
						|
 | 
						|
	 if ((!sp_sw || hd_type != forstmt) && ps.p_l_follow > 0)
 | 
						|
	 {
 | 
						|
 | 
						|
	    /* This should be true iff there were unbalanced parens in
 | 
						|
	       the stmt.  It is a bit complicated, because the
 | 
						|
	       semicolon might be in a for stmt */
 | 
						|
	    diag(1, "Unbalanced parens");
 | 
						|
	    ps.p_l_follow = 0;
 | 
						|
	    if (sp_sw)
 | 
						|
	    {				/* this is a check for a if,
 | 
						|
					   while, etc. with unbalanced
 | 
						|
					   parens */
 | 
						|
	       sp_sw = false;
 | 
						|
	       parse(hd_type);		/* dont lose the if, or
 | 
						|
					   whatever */
 | 
						|
	    }
 | 
						|
	 }
 | 
						|
	 *e_code++ = ';';
 | 
						|
	 ps.want_blank = true;
 | 
						|
	 ps.in_stmt = (ps.p_l_follow > 0);	/* we are no longer in
 | 
						|
						   the middle of a stmt */
 | 
						|
 | 
						|
	 if (!sp_sw)
 | 
						|
	 {				/* if not if for (;;) */
 | 
						|
	    parse(semicolon);		/* let parser know about end of
 | 
						|
					   stmt */
 | 
						|
	    force_nl = true;		/* force newline after a end of
 | 
						|
					   stmt */
 | 
						|
	 }
 | 
						|
	 break;
 | 
						|
 | 
						|
      case lbrace:			/* got a '{' */
 | 
						|
	 ps.in_stmt = false;		/* dont indent the {} */
 | 
						|
	 if (!ps.block_init)
 | 
						|
	    force_nl = true;		/* force other stuff on same
 | 
						|
					   line as '{' onto new line */
 | 
						|
	 else if (ps.block_init_level <= 0)
 | 
						|
	    ps.block_init_level = 1;
 | 
						|
	 else
 | 
						|
	    ps.block_init_level++;
 | 
						|
 | 
						|
	 if (s_code != e_code && !ps.block_init)
 | 
						|
	 {
 | 
						|
	    if (!btype_2)
 | 
						|
	    {
 | 
						|
	       dump_line();
 | 
						|
	       ps.want_blank = false;
 | 
						|
	    } else if (ps.in_par_decl && !ps.in_or_st)
 | 
						|
	    {
 | 
						|
	       ps.i_l_follow = 0;
 | 
						|
	       dump_line();
 | 
						|
	       ps.want_blank = false;
 | 
						|
	    }
 | 
						|
	 }
 | 
						|
	 if (ps.in_par_decl)
 | 
						|
	    prefix_blankline_requested = 0;
 | 
						|
 | 
						|
	 if (ps.p_l_follow > 0)
 | 
						|
	 {				/* check for preceeding
 | 
						|
					   unbalanced parens */
 | 
						|
	    diag(1, "Unbalanced parens");
 | 
						|
	    ps.p_l_follow = 0;
 | 
						|
	    if (sp_sw)
 | 
						|
	    {				/* check for unclosed if, for,
 | 
						|
					   etc. */
 | 
						|
	       sp_sw = false;
 | 
						|
	       parse(hd_type);
 | 
						|
	       ps.ind_level = ps.i_l_follow;
 | 
						|
	    }
 | 
						|
	 }
 | 
						|
	 if (s_code == e_code)
 | 
						|
	    ps.ind_stmt = false;	/* dont put extra indentation
 | 
						|
					   on line with '{' */
 | 
						|
	 if (ps.in_decl && ps.in_or_st)
 | 
						|
	 {				/* this is either a structure
 | 
						|
					   declaration or an init */
 | 
						|
	    di_stack[ps.dec_nest++] = dec_ind;
 | 
						|
	    /* ?		dec_ind = 0; */
 | 
						|
	 } else
 | 
						|
	 {
 | 
						|
	    ps.decl_on_line = false;	/* we cant be in the middle of
 | 
						|
					   a declaration, so dont do
 | 
						|
					   special indentation of
 | 
						|
					   comments */
 | 
						|
	    if (bl_at_proctop
 | 
						|
		&& ps.in_par_decl)
 | 
						|
	       postfix_blankline_requested = 1;
 | 
						|
	    ps.in_par_decl = 0;
 | 
						|
	 }
 | 
						|
	 dec_ind = 0;
 | 
						|
	 parse(lbrace);			/* let parser know about this */
 | 
						|
	 if (ps.want_blank)		/* put a blank before '{' if
 | 
						|
					   '{' is not at start of line */
 | 
						|
	    *e_code++ = ' ';
 | 
						|
	 ps.want_blank = false;
 | 
						|
	 *e_code++ = '{';
 | 
						|
	 ps.just_saw_decl = 0;
 | 
						|
	 break;
 | 
						|
 | 
						|
      case rbrace:			/* got a '}' */
 | 
						|
	 if (ps.p_stack[ps.tos] == decl && !ps.block_init)	/* semicolons can be
 | 
						|
								   omitted in
 | 
						|
								   declarations */
 | 
						|
	    parse(semicolon);
 | 
						|
	 if (ps.p_l_follow)
 | 
						|
	 {				/* check for unclosed if, for,
 | 
						|
					   else. */
 | 
						|
	    diag(1, "Unbalanced parens");
 | 
						|
	    ps.p_l_follow = 0;
 | 
						|
	    sp_sw = false;
 | 
						|
	 }
 | 
						|
	 ps.just_saw_decl = 0;
 | 
						|
	 ps.block_init_level--;
 | 
						|
	 if (s_code != e_code && !ps.block_init)
 | 
						|
	 {				/* '}' must be first on line */
 | 
						|
	    if (verbose)
 | 
						|
	       diag(0, "Line broken");
 | 
						|
	    dump_line();
 | 
						|
	 }
 | 
						|
	 *e_code++ = '}';
 | 
						|
	 ps.want_blank = true;
 | 
						|
	 ps.in_stmt = ps.ind_stmt = false;
 | 
						|
	 if (ps.dec_nest > 0)
 | 
						|
	 {				/* we are in multi-level
 | 
						|
					   structure declaration */
 | 
						|
	    dec_ind = di_stack[--ps.dec_nest];
 | 
						|
	    if (ps.dec_nest == 0 && !ps.in_par_decl)
 | 
						|
	       ps.just_saw_decl = 2;
 | 
						|
	    ps.in_decl = true;
 | 
						|
	 }
 | 
						|
	 prefix_blankline_requested = 0;
 | 
						|
	 parse(rbrace);			/* let parser know about this */
 | 
						|
	 ps.search_brace = cuddle_else && ps.p_stack[ps.tos] == ifhead
 | 
						|
	    && ps.il[ps.tos] >= ps.ind_level;
 | 
						|
	 if (ps.tos <= 1 && bl_a_procs && ps.dec_nest <= 0)
 | 
						|
	    postfix_blankline_requested = 1;
 | 
						|
	 break;
 | 
						|
 | 
						|
      case swstmt:			/* got keyword "switch" */
 | 
						|
	 sp_sw = true;
 | 
						|
	 hd_type = swstmt;		/* keep this for when we have
 | 
						|
					   seen the expression */
 | 
						|
	 goto copy_id;			/* go move the token into
 | 
						|
					   buffer */
 | 
						|
 | 
						|
      case sp_paren:			/* token is if, while, for */
 | 
						|
	 sp_sw = true;			/* the interesting stuff is
 | 
						|
					   done after the expression is
 | 
						|
					   scanned */
 | 
						|
	 hd_type = (*token == 'i' ? ifstmt :
 | 
						|
		    (*token == 'w' ? whilestmt : forstmt));
 | 
						|
 | 
						|
	 /* remember the type of header for later use by parser */
 | 
						|
	 goto copy_id;			/* copy the token into line */
 | 
						|
 | 
						|
      case sp_nparen:			/* got else, do */
 | 
						|
	 ps.in_stmt = false;
 | 
						|
	 if (*token == 'e')
 | 
						|
	 {
 | 
						|
	    if (e_code != s_code && (!cuddle_else || e_code[-1] != '}'))
 | 
						|
	    {
 | 
						|
	       if (verbose)
 | 
						|
		  diag(0, "Line broken");
 | 
						|
	       dump_line();		/* make sure this starts a line */
 | 
						|
	       ps.want_blank = false;
 | 
						|
	    }
 | 
						|
	    force_nl = true;		/* also, following stuff must
 | 
						|
					   go onto new line */
 | 
						|
	    last_else = 1;
 | 
						|
	    parse(elselit);
 | 
						|
	 } else
 | 
						|
	 {
 | 
						|
	    if (e_code != s_code)
 | 
						|
	    {				/* make sure this starts a line */
 | 
						|
	       if (verbose)
 | 
						|
		  diag(0, "Line broken");
 | 
						|
	       dump_line();
 | 
						|
	       ps.want_blank = false;
 | 
						|
	    }
 | 
						|
	    force_nl = true;		/* also, following stuff must
 | 
						|
					   go onto new line */
 | 
						|
	    last_else = 0;
 | 
						|
	    parse(dolit);
 | 
						|
	 }
 | 
						|
	 goto copy_id;			/* move the token into line */
 | 
						|
 | 
						|
      case decl:			/* we have a declaration type
 | 
						|
					   (int, register, etc.) */
 | 
						|
	 parse(decl);			/* let parser worry about
 | 
						|
					   indentation */
 | 
						|
	 if (ps.last_token == rparen && ps.tos <= 1)
 | 
						|
	 {
 | 
						|
	    ps.in_par_decl = 1;
 | 
						|
	    if (s_code != e_code)
 | 
						|
	    {
 | 
						|
	       dump_line();
 | 
						|
	       ps.want_blank = 0;
 | 
						|
	    }
 | 
						|
	 }
 | 
						|
	 if (ps.in_par_decl && ps.indent_parameters && ps.dec_nest == 0)
 | 
						|
	 {
 | 
						|
	    ps.ind_level = ps.i_l_follow = 1;
 | 
						|
	    ps.ind_stmt = 0;
 | 
						|
	 }
 | 
						|
	 ps.in_or_st = true;		/* this might be a structure or
 | 
						|
					   initialization declaration */
 | 
						|
	 ps.in_decl = ps.decl_on_line = true;
 | 
						|
	 if ( /* !ps.in_or_st && */ ps.dec_nest <= 0)
 | 
						|
	    ps.just_saw_decl = 2;
 | 
						|
	 prefix_blankline_requested = 0;
 | 
						|
	 for (i = 0; token[i++];);	/* get length of token */
 | 
						|
 | 
						|
	 /* dec_ind = e_code - s_code + (ps.decl_indent>i ?
 | 
						|
	    ps.decl_indent : i); */
 | 
						|
	 dec_ind = ps.decl_indent > 0 ? ps.decl_indent : i;
 | 
						|
	 goto copy_id;
 | 
						|
 | 
						|
      case ident:			/* got an identifier or
 | 
						|
					   constant */
 | 
						|
	 if (ps.in_decl)
 | 
						|
	 {				/* if we are in a declaration,
 | 
						|
					   we must indent identifier */
 | 
						|
	    if (ps.want_blank)
 | 
						|
	       *e_code++ = ' ';
 | 
						|
	    ps.want_blank = false;
 | 
						|
	    if (is_procname == 0 || !proc_str_line)
 | 
						|
	    {
 | 
						|
	       if (!ps.block_init)
 | 
						|
		  if (troff && !ps.dumped_decl_indent)
 | 
						|
		  {
 | 
						|
		     sprintf(e_code, "\n.De %dp+\200p\n", dec_ind * 7);
 | 
						|
		     ps.dumped_decl_indent = 1;
 | 
						|
		     e_code += strlen(e_code);
 | 
						|
		  } else
 | 
						|
		     while ((e_code - s_code) < dec_ind)
 | 
						|
		     {
 | 
						|
			if (e_code >= l_code)
 | 
						|
			{
 | 
						|
			   register        nsize = l_code - s_code + 400;
 | 
						|
			   codebuf = (char *) realloc(codebuf, nsize);
 | 
						|
			   e_code = codebuf + (e_code - s_code) + 1;
 | 
						|
			   l_code = codebuf + nsize - 5;
 | 
						|
			   s_code = codebuf + 1;
 | 
						|
			}
 | 
						|
			*e_code++ = ' ';
 | 
						|
		     }
 | 
						|
	    } else
 | 
						|
	    {
 | 
						|
	       if (dec_ind && s_code != e_code)
 | 
						|
		  dump_line();
 | 
						|
	       dec_ind = 0;
 | 
						|
	       ps.want_blank = false;
 | 
						|
	    }
 | 
						|
	 } else if (sp_sw && ps.p_l_follow == 0)
 | 
						|
	 {
 | 
						|
	    sp_sw = false;
 | 
						|
	    force_nl = true;
 | 
						|
	    ps.last_u_d = true;
 | 
						|
	    ps.in_stmt = false;
 | 
						|
	    parse(hd_type);
 | 
						|
	 }
 | 
						|
   copy_id:
 | 
						|
	 if (ps.want_blank)
 | 
						|
	    *e_code++ = ' ';
 | 
						|
	 if (troff && ps.its_a_keyword)
 | 
						|
	 {
 | 
						|
	    e_code = chfont(&bodyf, &keywordf, e_code);
 | 
						|
	    for (t_ptr = token; *t_ptr; ++t_ptr)
 | 
						|
	    {
 | 
						|
	       if (e_code >= l_code)
 | 
						|
	       {
 | 
						|
		  register        nsize = l_code - s_code + 400;
 | 
						|
		  codebuf = (char *) realloc(codebuf, nsize);
 | 
						|
		  e_code = codebuf + (e_code - s_code) + 1;
 | 
						|
		  l_code = codebuf + nsize - 5;
 | 
						|
		  s_code = codebuf + 1;
 | 
						|
	       }
 | 
						|
	       *e_code++ = keywordf.allcaps && islower(*t_ptr)
 | 
						|
		  ? toupper(*t_ptr) : *t_ptr;
 | 
						|
	    }
 | 
						|
	    e_code = chfont(&keywordf, &bodyf, e_code);
 | 
						|
	 } else
 | 
						|
	    for (t_ptr = token; *t_ptr; ++t_ptr)
 | 
						|
	    {
 | 
						|
	       if (e_code >= l_code)
 | 
						|
	       {
 | 
						|
		  register        nsize = l_code - s_code + 400;
 | 
						|
		  codebuf = (char *) realloc(codebuf, nsize);
 | 
						|
		  e_code = codebuf + (e_code - s_code) + 1;
 | 
						|
		  l_code = codebuf + nsize - 5;
 | 
						|
		  s_code = codebuf + 1;
 | 
						|
	       }
 | 
						|
	       *e_code++ = *t_ptr;
 | 
						|
	    }
 | 
						|
	 ps.want_blank = true;
 | 
						|
	 break;
 | 
						|
 | 
						|
      case period:			/* treat a period kind of like
 | 
						|
					   a binary operation */
 | 
						|
	 *e_code++ = '.';		/* move the period into line */
 | 
						|
	 ps.want_blank = false;		/* dont put a blank after a
 | 
						|
					   period */
 | 
						|
	 break;
 | 
						|
 | 
						|
      case comma:
 | 
						|
	 ps.want_blank = (s_code != e_code);	/* only put blank after
 | 
						|
						   comma if comma does
 | 
						|
						   not start the line */
 | 
						|
	 if (ps.in_decl && is_procname == 0 && !ps.block_init)
 | 
						|
	    while ((e_code - s_code) < (dec_ind - 1))
 | 
						|
	    {
 | 
						|
	       if (e_code >= l_code)
 | 
						|
	       {
 | 
						|
		  register        nsize = l_code - s_code + 400;
 | 
						|
		  codebuf = (char *) realloc(codebuf, nsize);
 | 
						|
		  e_code = codebuf + (e_code - s_code) + 1;
 | 
						|
		  l_code = codebuf + nsize - 5;
 | 
						|
		  s_code = codebuf + 1;
 | 
						|
	       }
 | 
						|
	       *e_code++ = ' ';
 | 
						|
	    }
 | 
						|
 | 
						|
	 *e_code++ = ',';
 | 
						|
	 if (ps.p_l_follow == 0)
 | 
						|
	 {
 | 
						|
	    if (ps.block_init_level <= 0)
 | 
						|
	       ps.block_init = 0;
 | 
						|
	    if (break_comma && !ps.leave_comma)
 | 
						|
	       force_nl = true;
 | 
						|
	 }
 | 
						|
	 break;
 | 
						|
 | 
						|
      case preesc:			/* got the character '#' */
 | 
						|
	 if ((s_com != e_com) ||
 | 
						|
	     (s_lab != e_lab) ||
 | 
						|
	     (s_code != e_code))
 | 
						|
	    dump_line();
 | 
						|
	 *e_lab++ = '#';		/* move whole line to 'label'
 | 
						|
					   buffer */
 | 
						|
	 {
 | 
						|
	    int             in_comment = 0;
 | 
						|
	    int             com_start = 0;
 | 
						|
	    char            quote = 0;
 | 
						|
	    int             com_end = 0;
 | 
						|
 | 
						|
	    while (*buf_ptr != '\n' || in_comment)
 | 
						|
	    {
 | 
						|
	       if (e_lab >= l_lab)
 | 
						|
	       {
 | 
						|
		  register        nsize = l_lab - s_lab + 400;
 | 
						|
		  labbuf = (char *) realloc(labbuf, nsize);
 | 
						|
		  e_lab = labbuf + (e_lab - s_lab) + 1;
 | 
						|
		  l_lab = labbuf + nsize - 5;
 | 
						|
		  s_lab = labbuf + 1;
 | 
						|
	       }
 | 
						|
	       *e_lab = *buf_ptr++;
 | 
						|
	       if (buf_ptr >= buf_end)
 | 
						|
		  fill_buffer();
 | 
						|
	       switch (*e_lab++)
 | 
						|
	       {
 | 
						|
	       case BACKSLASH:
 | 
						|
		  if (troff)
 | 
						|
		     *e_lab++ = BACKSLASH;
 | 
						|
		  if (!in_comment)
 | 
						|
		  {
 | 
						|
		     *e_lab++ = *buf_ptr++;
 | 
						|
		     if (buf_ptr >= buf_end)
 | 
						|
			fill_buffer();
 | 
						|
		  }
 | 
						|
		  break;
 | 
						|
	       case '/':
 | 
						|
		  if (*buf_ptr == '*' && !in_comment && !quote)
 | 
						|
		  {
 | 
						|
		     in_comment = 1;
 | 
						|
		     *e_lab++ = *buf_ptr++;
 | 
						|
		     com_start = e_lab - s_lab - 2;
 | 
						|
		  }
 | 
						|
		  break;
 | 
						|
	       case '"':
 | 
						|
		  if (quote == '"')
 | 
						|
		     quote = 0;
 | 
						|
		  break;
 | 
						|
	       case '\'':
 | 
						|
		  if (quote == '\'')
 | 
						|
		     quote = 0;
 | 
						|
		  break;
 | 
						|
	       case '*':
 | 
						|
		  if (*buf_ptr == '/' && in_comment)
 | 
						|
		  {
 | 
						|
		     in_comment = 0;
 | 
						|
		     *e_lab++ = *buf_ptr++;
 | 
						|
		     com_end = e_lab - s_lab;
 | 
						|
		  }
 | 
						|
		  break;
 | 
						|
	       }
 | 
						|
	    }
 | 
						|
 | 
						|
	    while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
 | 
						|
	       e_lab--;
 | 
						|
	    if (e_lab - s_lab == com_end && bp_save == 0)
 | 
						|
	    {				/* comment on preprocessor line */
 | 
						|
	       if (sc_end == 0)		/* if this is the first
 | 
						|
					   comment, we must set up the
 | 
						|
					   buffer */
 | 
						|
		  sc_end = &(save_com[0]);
 | 
						|
	       else
 | 
						|
	       {
 | 
						|
		  *sc_end++ = '\n';	/* add newline between comments */
 | 
						|
		  *sc_end++ = ' ';
 | 
						|
		  --line_no;
 | 
						|
	       }
 | 
						|
	       memcpy(sc_end, s_lab + com_start, com_end - com_start);
 | 
						|
	       sc_end += com_end - com_start;
 | 
						|
	       if (sc_end >= &save_com[sc_size])
 | 
						|
		  abort();
 | 
						|
	       e_lab = s_lab + com_start;
 | 
						|
	       while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
 | 
						|
		  e_lab--;
 | 
						|
	       bp_save = buf_ptr;	/* save current input buffer */
 | 
						|
	       be_save = buf_end;
 | 
						|
	       buf_ptr = save_com;	/* fix so that subsequent calls
 | 
						|
					   to lexi will take tokens out
 | 
						|
					   of save_com */
 | 
						|
	       *sc_end++ = ' ';		/* add trailing blank, just in
 | 
						|
					   case */
 | 
						|
	       buf_end = sc_end;
 | 
						|
	       sc_end = 0;
 | 
						|
	    }
 | 
						|
	    *e_lab = '\0';		/* null terminate line */
 | 
						|
	    ps.pcase = false;
 | 
						|
	 }
 | 
						|
 | 
						|
	 if (strncmp(s_lab, "#if", 3) == 0)
 | 
						|
	 {
 | 
						|
	    if (bl_around)
 | 
						|
	    {
 | 
						|
	       register        c;
 | 
						|
	       prefix_blankline_requested++;
 | 
						|
	       while ((c = getc(input)) == '\n');
 | 
						|
	       ungetc(c, input);
 | 
						|
	    }
 | 
						|
	    if (ifdef_level < sizeof state_stack / sizeof state_stack[0])
 | 
						|
	    {
 | 
						|
	       match_state[ifdef_level].tos = -1;
 | 
						|
	       state_stack[ifdef_level++] = ps;
 | 
						|
	    } else
 | 
						|
	       diag(1, "#if stack overflow");
 | 
						|
	 } else if (strncmp(s_lab, "#else", 5) == 0)
 | 
						|
	    if (ifdef_level <= 0)
 | 
						|
	       diag(1, "Unmatched #else");
 | 
						|
	    else
 | 
						|
	    {
 | 
						|
	       match_state[ifdef_level - 1] = ps;
 | 
						|
	       ps = state_stack[ifdef_level - 1];
 | 
						|
	    }
 | 
						|
	 else if (strncmp(s_lab, "#endif", 6) == 0)
 | 
						|
	 {
 | 
						|
	    if (ifdef_level <= 0)
 | 
						|
	       diag(1, "Unmatched #endif");
 | 
						|
	    else
 | 
						|
	    {
 | 
						|
	       ifdef_level--;
 | 
						|
 | 
						|
#ifdef undef
 | 
						|
	       /* This match needs to be more intelligent before the
 | 
						|
	          message is useful */
 | 
						|
	       if (match_state[ifdef_level].tos >= 0
 | 
						|
		   && bcmp(&ps, &match_state[ifdef_level], sizeof ps))
 | 
						|
		  diag(0, "Syntactically inconsistant #ifdef alternatives.");
 | 
						|
#endif
 | 
						|
	    }
 | 
						|
	    if (bl_around)
 | 
						|
	    {
 | 
						|
	       postfix_blankline_requested++;
 | 
						|
	       n_real_blanklines = 0;
 | 
						|
	    }
 | 
						|
	 }
 | 
						|
	 break;				/* subsequent processing of the
 | 
						|
					   newline character will cause
 | 
						|
					   the line to be printed */
 | 
						|
 | 
						|
      case comment:			/* we have gotten a / *  this is
 | 
						|
					   a biggie */
 | 
						|
	 if (flushed_nl)
 | 
						|
	 {				/* we should force a broken
 | 
						|
					   line here */
 | 
						|
	    flushed_nl = false;
 | 
						|
	    dump_line();
 | 
						|
	    ps.want_blank = false;	/* dont insert blank at line
 | 
						|
					   start */
 | 
						|
	    force_nl = false;
 | 
						|
	 }
 | 
						|
	 pr_comment();
 | 
						|
	 break;
 | 
						|
      }					/* end of big switch stmt */
 | 
						|
 | 
						|
      *e_code = '\0';			/* make sure code section is
 | 
						|
					   null terminated */
 | 
						|
      if (type_code != comment && type_code != newline && type_code != preesc)
 | 
						|
	 ps.last_token = type_code;
 | 
						|
   }					/* end of main while (1) loop */
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * copy input file to backup file if in_name is /blah/blah/blah/file, then
 | 
						|
 * backup file will be ".Bfile" then make the backup file the input and
 | 
						|
 * original input file the output
 | 
						|
 */
 | 
						|
void bakcopy()
 | 
						|
{
 | 
						|
   int             n, bakchn;
 | 
						|
   char            buff[8 * 1024];
 | 
						|
   register char  *p;
 | 
						|
 | 
						|
   /* construct file name .Bfile */
 | 
						|
   for (p = in_name; *p; p++);		/* skip to end of string */
 | 
						|
   while (p > in_name && *p != '/')	/* find last '/' */
 | 
						|
      p--;
 | 
						|
   if (*p == '/')
 | 
						|
      p++;
 | 
						|
   sprintf(bakfile, "%s.BAK", p);
 | 
						|
   if (strlen(p) >= NAME_SIZE) *bakfile ^= 040;	/* toggle char */
 | 
						|
 | 
						|
   /* copy in_name to backup file */
 | 
						|
   bakchn = creat(bakfile, 0600);
 | 
						|
   if (bakchn < 0)
 | 
						|
   {
 | 
						|
      fprintf(stderr, "indent: can't create backup file \"%s\"\n", bakfile);
 | 
						|
      exit(1);
 | 
						|
   }
 | 
						|
   while (n = read(fileno(input), buff, sizeof buff))
 | 
						|
      if (write(bakchn, buff, n) != n)
 | 
						|
      {
 | 
						|
	 fprintf(stderr, "indent: error writing backup file \"%s\"\n",
 | 
						|
		 bakfile);
 | 
						|
	 exit(1);
 | 
						|
      }
 | 
						|
   if (n < 0)
 | 
						|
   {
 | 
						|
      fprintf(stderr, "indent: error reading input file \"%s\"\n", in_name);
 | 
						|
      exit(1);
 | 
						|
   }
 | 
						|
   close(bakchn);
 | 
						|
   fclose(input);
 | 
						|
 | 
						|
   /* re-open backup file as the input file */
 | 
						|
   input = fopen(bakfile, "r");
 | 
						|
   if (input == 0)
 | 
						|
   {
 | 
						|
      fprintf(stderr, "indent: can't re-open backup file\n");
 | 
						|
      exit(1);
 | 
						|
   }
 | 
						|
   /* now the original input file will be the output */
 | 
						|
   output = fopen(in_name, "w");
 | 
						|
   if (output == 0)
 | 
						|
   {
 | 
						|
      fprintf(stderr, "indent: can't create %s\n", in_name);
 | 
						|
      unlink(bakfile);
 | 
						|
      exit(1);
 | 
						|
   }
 | 
						|
}
 |