1 /** \file
2  * handletoken.c  GNU indent, processing of tokens returned by the parser.
3  *
4  * Copyright (c) 2015 Tim Hentenaar. All rights reserved.<br>
5  * Copyright (c) 2013 Łukasz Stelmach.  All rights reserved.<br>
6  * Copyright (c) 1999, 2000 Carlo Wood.  All rights reserved. <br>
7  * Copyright (c) 1994, 1996, 1997 Joseph Arceneaux.  All rights reserved. <br>
8  * Copyright (c) 1992, 2002, 2008, 2014 Free Software Foundation, Inc.  All rights reserved. <br>
9  *
10  * Copyright (c) 1980 The Regents of the University of California. <br>
11  * Copyright (c) 1976 Board of Trustees of the University of Illinois. All rights reserved.
12  * Copyright (c) 1985 Sun Microsystems, Inc.
13  *   All rights reserved.<br>
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions
17  * are met:
18  * - 1. Redistributions of source code must retain the above copyright
19  *    notice, this list of conditions and the following disclaimer.
20  * - 2. Redistributions in binary form must reproduce the above copyright
21  *    notice, this list of conditions and the following disclaimer in the
22  *    documentation and/or other materials provided with the distribution.
23  * - 3. Neither the name of the University nor the names of its contributors
24  *    may be used to endorse or promote products derived from this software
25  *    without specific prior written permission.<br>
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37  * SUCH DAMAGE.
38  *
39  * This program is distributed in the hope that it will be useful,
40  * but WITHOUT ANY WARRANTY; without even the implied warranty of
41  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
42  * GNU General Public License for more details.
43  *
44  * You should have received a copy of the GNU General Public License
45  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
46  *
47  * Updates:
48  * - 2002-08-05: Matthias <moh@itec.uni-klu.ac.at> and Eric Lloyd <ewlloyd@neta.com>
49  *             Added support for -brf to place function opening brace after function
50  *             declaration.
51  * - 28 Sep 2003 Erik de Castro Lopo
52  *             Fixed Bug#212320: --blank-lines-after-proceduresdoes not work
53  * - 28 Sep 2003 Erik de Castro Lopo
54  *             Fixed Bug#206785: indent segfaults on the attached file
55  * - 28 Sep 2003 Geoffrey Lee <glee@bogus.example.com>
56  *             Fixed Bug#205692: indent: [patch] fix garble shown in locale(fwd)
57  * - 2008-03-08 DI Re-baselined on the more acceptable (license-wise) OpenBSD release 3.4.
58  *
59  */
60 
61 #include "sys.h"
62 
63 #include <string.h>
64 #include <ctype.h>
65 #include <stdlib.h>
66 #include "indent.h"
67 #include "backup.h"
68 #include "code_io.h"
69 #include "globs.h"
70 #include "parse.h"
71 #include "comments.h"
72 #include "args.h"
73 #include "output.h"
74 #include "handletoken.h"
75 
76 RCSTAG_CC ("$GNU$");
77 
78 /**
79  * Expand a buffer to hold more chars, aligned on a
80  * 1 KB boundary.
81  */
need_chars(buf_ty * bp,size_t needed)82 extern void need_chars(buf_ty * bp, size_t needed)
83 {
84     size_t current_size = (size_t)(bp->end - bp->ptr);
85 
86     if (current_size + needed >= (size_t)bp->size)
87     {
88         bp->size = ((current_size + needed) & (size_t)~1023);
89         bp->ptr = xrealloc(bp->ptr, bp->size);
90         if (bp->ptr == NULL)
91         {
92             fatal (_("Ran out of memory"), 0);
93         }
94 
95         bp->end = bp->ptr + current_size;
96     }
97 }
98 
99 /**
100  *
101  */
check_code_size(void)102 extern void check_code_size(void)
103 {
104     if (e_code >= l_code)
105     {
106         int nsize = l_code - s_code + 400;
107         codebuf   = xrealloc(codebuf, nsize);
108         e_code    = codebuf + (e_code - s_code) + 1;
109         l_code    = codebuf + nsize - 5;
110         s_code    = codebuf + 1;
111     }
112 }
113 
114 /**
115  *
116  */
117 
check_lab_size(void)118 static void check_lab_size(void)
119 {
120     if (e_lab >= l_lab)
121     {
122         int nsize  = l_lab - s_lab + 400;
123         labbuf = xrealloc(labbuf, nsize);
124         e_lab  = labbuf + (e_lab - s_lab) + 1;
125         l_lab  = labbuf + nsize - 5;
126         s_lab  = labbuf + 1;
127     }
128 }
129 
130 /**
131  *
132  */
133 
copy_id(const codes_ty type_code,BOOLEAN * force_nl,exit_values_ty * file_exit_value,const bb_code_ty can_break)134 static void copy_id(
135     const codes_ty   type_code,
136     BOOLEAN        * force_nl,
137     exit_values_ty * file_exit_value,
138     const bb_code_ty can_break)
139 {
140     char           * t_ptr;
141 
142     if (parser_state_tos->want_blank)
143     {
144         set_buf_break (bb_ident, paren_target);
145         *(e_code++) = ' ';
146     }
147     else if (can_break)
148     {
149         set_buf_break (can_break, paren_target);
150     }
151     else
152     {
153     }
154 
155     if (s_code == e_code)
156     {
157         s_code_corresponds_to = token;
158     }
159 
160     for (t_ptr = token; t_ptr < token_end; ++t_ptr)
161     {
162         check_code_size();
163         *(e_code++) = *t_ptr;
164     }
165 
166     *e_code = '\0'; /* null terminate code sect */
167 
168     parser_state_tos->want_blank = true;
169 
170     /* Handle the options -nsaf, -nsai and -nsaw */
171 
172     if ((type_code == sp_paren) &&
173         ((!settings.space_after_if && (*token == 'i')) ||
174          (!settings.space_after_for && (*token == 'f')) ||
175          (!settings.space_after_while && (*token == 'w'))))
176     {
177         parser_state_tos->want_blank = false;
178     }
179 
180     /* If the token is one of the GNU gettext macro's '_' or 'N_'
181      * then we don't want a blank */
182 
183     if ((((token_end - token) == 1) && (*token == '_')) ||
184         (((token_end - token) == 2) && (*token == 'N') &&
185          (token[1] == '_')))
186     {
187         parser_state_tos->want_blank = false;
188     }
189 
190     /* If the token is va_dcl, it appears without a semicolon, so we
191      * need to pretend that one was there.  */
192 
193     if (((token_end - token) == 6) && (strncmp (token, "va_dcl", 6) == 0))
194     {
195         parser_state_tos->in_or_st = 0;
196         parser_state_tos->just_saw_decl--;
197         parser_state_tos->in_decl = false;
198 
199         do
200         {
201             if (parse (semicolon) != total_success)
202             {
203                 *file_exit_value = indent_error;
204             }
205         } while(0);
206 
207         *force_nl = true;
208     }
209 }
210 
211 /**
212  *
213  */
214 
handle_token_form_feed(BOOLEAN * pbreak_line)215 static void handle_token_form_feed(
216     BOOLEAN * pbreak_line)
217 {
218     parser_state_tos->use_ff = true;        /* a form feed is treated
219                                              * much like a newline */
220     dump_line (true, &paren_target, pbreak_line);
221     parser_state_tos->want_blank = false;
222 }
223 
224 /**
225  * 2002-06-13 D.Ingamells Reset force_nl if the line is dumped.
226  */
227 
handle_token_newline(BOOLEAN * force_nl,BOOLEAN * pbreak_line)228 static void handle_token_newline(
229     BOOLEAN * force_nl,
230     BOOLEAN * pbreak_line)
231 {
232 
233     if (s_lab != e_lab && *s_lab == '#')
234     {
235         dump_line (true, &paren_target, pbreak_line);
236 
237         if (s_code == e_code)
238         {
239             parser_state_tos->want_blank = false;
240         }
241 
242         *force_nl = false;
243     }
244     else
245     {
246         if ( ( (parser_state_tos->last_token != comma) ||
247                !settings.leave_comma ||
248                !break_comma ||
249                (parser_state_tos->p_l_follow > 0) ||
250                parser_state_tos->block_init ||
251                (s_com != e_com)) &&
252              ( ( (parser_state_tos->last_token != rbrace) ||
253                  !(settings.braces_on_struct_decl_line &&
254                    parser_state_tos->in_decl))))
255         {
256             /* Attempt to detect the newline before a procedure name,
257              * and if e.g., K&R style, leave the procedure on the
258              * same line as the type. */
259 
260             if (!settings.procnames_start_line &&
261                 (s_lab == e_lab) &&
262                 (parser_state_tos->last_token != lparen) &&
263                 (parser_state_tos->last_token != semicolon) &&
264                 (parser_state_tos->last_token != comma) &&
265                 (parser_state_tos->last_rw == rw_decl) &&
266                 (parser_state_tos->last_rw_depth == 0) &&
267                 (!parser_state_tos->block_init) &&
268                 (parser_state_tos->in_decl))
269             {
270                 /* Put a space between the type and the procedure name,
271                  * unless it was a pointer type and the user doesn't
272                  * want such spaces after '*'. */
273 
274                 if (!((e_code > s_code) &&
275                       (e_code[-1] == '*')))
276                 {
277                     parser_state_tos->want_blank = true;
278                 }
279             }
280 
281             if (!parser_state_tos->in_stmt ||
282                 (s_com != e_com) ||
283                 embedded_comment_on_line)
284             {
285                 dump_line (true, &paren_target, pbreak_line);
286 
287                 if (s_code == e_code)
288                 {
289                     parser_state_tos->want_blank = false;
290                 }
291 
292                 *force_nl = false;
293             }
294         }
295     }
296 
297     /* If we were on the line with a #else or a #endif, we aren't
298      * anymore.  */
299 
300     else_or_endif = false;
301     ++line_no;              /* keep track of input line number */
302 }
303 
304 /**
305  *
306  */
307 
handle_token_lparen(BOOLEAN * force_nl,BOOLEAN * sp_sw,int * dec_ind,BOOLEAN * pbreak_line)308 static void handle_token_lparen(
309     BOOLEAN       * force_nl,
310     BOOLEAN       * sp_sw,
311     int           * dec_ind,
312     BOOLEAN       * pbreak_line)
313 {
314     /* Braces in initializer lists should be put on new lines. This is
315      * necessary so that -gnu does not cause things like char
316      * *this_is_a_string_array[] = { "foo", "this_string_does_not_fit",
317      * "nor_does_this_rather_long_string" } which is what happens
318      * because we are trying to line the strings up with the
319      * parentheses, and those that are too long are moved to the right
320      * an ugly amount.
321      *
322      * However, if the current line is empty, the left brace is
323      * already on a new line, so don't molest it.
324      */
325 
326     if ((*token == '{') && ((s_code != e_code) ||
327                               (s_com  != e_com)  ||
328                               (s_lab  != e_lab)))
329     {
330         dump_line (true, &paren_target, pbreak_line);
331 
332         /* Do not put a space before the '{'.  */
333 
334         parser_state_tos->want_blank = false;
335     }
336 
337     /* Count parens so we know how deep we are.  */
338 
339     ++parser_state_tos->p_l_follow;
340 
341     if (parser_state_tos->p_l_follow >= parser_state_tos->paren_indents_size)
342     {
343         parser_state_tos->paren_indents_size *= 2;
344         parser_state_tos->paren_indents =
345                 xrealloc(parser_state_tos->paren_indents,
346                          parser_state_tos->paren_indents_size * sizeof(short));
347     }
348 
349     parser_state_tos->paren_depth++;
350 
351 	/* In the case of nested function pointer declarations, let's ensure
352 	 * we output a ' ' between the decl word and the lparen, but NOT
353 	 * between the following rparen and lparen.
354 	 */
355     if (parser_state_tos->is_func_ptr_decl && !settings.proc_calls_space)
356         parser_state_tos->want_blank = (*(token - 1) != ')' && *(token - 1) != ' ');
357 
358     if (parser_state_tos->want_blank &&
359         (*token != '[') &&
360         ( (parser_state_tos->last_token != ident) ||
361           settings.proc_calls_space ||
362           (parser_state_tos->its_a_keyword &&
363            (!parser_state_tos->sizeof_keyword || settings.blank_after_sizeof))))
364     {
365         set_buf_break (bb_proc_call, paren_target);
366         *(e_code++) = ' ';
367         *e_code = '\0';     /* null terminate code sect */
368     }
369     else
370     {
371         set_buf_break (bb_proc_call, paren_target);
372     }
373 
374 	/* Remember if this looks like a function pointer decl. */
375 	if (*(token + 1) == '*' &&
376 	    parser_state_tos->last_rw == rw_decl &&
377 	    (parser_state_tos->last_token == decl ||
378 	     parser_state_tos->last_token == unary_op))
379 	        parser_state_tos->is_func_ptr_decl = true;
380 
381     if (parser_state_tos->in_decl && !parser_state_tos->block_init)
382     {
383         if ((*token != '[') && !buf_break_used)
384         {
385             while ((e_code - s_code) < *dec_ind)
386             {
387                 check_code_size();
388                 set_buf_break (bb_dec_ind, paren_target);
389                 *(e_code++) = ' ';
390             }
391 
392             *(e_code++) = token[0];
393             parser_state_tos->ind_stmt = false;
394         }
395         else
396         {
397             *(e_code++) = token[0];
398         }
399     }
400     else
401     {
402         *(e_code++) = token[0];
403     }
404 
405     if (settings.parentheses_space && *token != '[')
406     {
407         *(e_code++) = ' ';
408     }
409 
410     parser_state_tos->paren_indents[parser_state_tos->p_l_follow - 1] =
411             e_code - s_code;
412 
413     if (*sp_sw && (parser_state_tos->p_l_follow == 1) &&
414         settings.extra_expression_indent &&
415         (parser_state_tos->paren_indents[0] < 2 * settings.ind_size))
416     {
417         parser_state_tos->paren_indents[0] = 2 * settings.ind_size;
418     }
419 
420     parser_state_tos->want_blank = false;
421 
422     if ((parser_state_tos->in_or_st == 1) && *token == '(')
423     {
424         /* this is a kludge to make sure that declarations will be
425          * correctly aligned if proc decl has an explicit type on it, i.e.
426          * "int a(x) {..." */
427 
428         parse_lparen_in_decl ();
429 
430         /* Turn off flag for structure decl or initialization.  */
431 
432         parser_state_tos->in_or_st = 0;
433     }
434 
435     /* For declarations, if user wants all fn decls broken, force that
436      * now.
437      */
438 
439     if ((*token == '(')                   &&
440         settings.break_function_decl_args &&
441         parser_state_tos->in_stmt         &&
442         parser_state_tos->in_decl         &&
443         (parser_state_tos->paren_depth == 1))
444     {
445         dump_line(true, &paren_target, pbreak_line);
446         *force_nl = false;
447 
448         paren_target = parser_state_tos->paren_depth * settings.ind_size + 1;
449         parser_state_tos->paren_indents[parser_state_tos->p_l_follow - 1] = -paren_target;
450     }
451 
452     if (parser_state_tos->sizeof_keyword)
453     {
454         parser_state_tos->sizeof_mask |= 1 << parser_state_tos->p_l_follow;
455     }
456 
457     /* The '(' that starts a cast can never be preceded by an
458      * indentifier or decl.  There is an exception immediately
459      * following a return.  To prevent that influence from going
460      * too far, it is reset by a following ident in lexi.c.
461      */
462 
463     if ((parser_state_tos->last_token == decl) ||
464         ((parser_state_tos->last_token == ident) &&
465          (parser_state_tos->last_rw != rw_return)))
466     {
467         parser_state_tos->noncast_mask |=
468                 1 << parser_state_tos->p_l_follow;
469     }
470     else
471     {
472         parser_state_tos->noncast_mask &=
473                 ~(1 << parser_state_tos->p_l_follow);
474     }
475 }
476 
477 /**
478  *
479  */
480 
handle_token_rparen(BOOLEAN * force_nl,BOOLEAN * sp_sw,codes_ty * hd_type,BOOLEAN * last_token_ends_sp,exit_values_ty * file_exit_value,BOOLEAN * pbreak_line)481 static void handle_token_rparen(
482    BOOLEAN        * force_nl,
483    BOOLEAN        * sp_sw,
484    codes_ty       * hd_type,
485    BOOLEAN        * last_token_ends_sp,
486    exit_values_ty * file_exit_value,
487    BOOLEAN        * pbreak_line)
488 {
489     char tmpchar[2], *tmp;
490 
491     parser_state_tos->paren_depth--;
492 
493     /* For declarations, if user wants close of fn decls broken, force that
494      * now.
495      */
496     if ((*token == ')')                   &&
497         settings.break_function_decl_args_end &&
498         !parser_state_tos->in_or_st       &&
499          parser_state_tos->in_stmt        &&
500         parser_state_tos->in_decl         &&
501         (parser_state_tos->paren_depth == 0))
502     {
503         if ((s_code != e_code) || (s_lab != e_lab) || (s_com != e_com))
504         {
505             dump_line(true, &paren_target, pbreak_line);
506         }
507 
508         paren_target = parser_state_tos->paren_depth * settings.ind_size;
509         parser_state_tos->paren_indents[parser_state_tos->p_l_follow - 1] = paren_target;
510         parser_state_tos->ind_stmt = 0;
511     }
512 
513     if (parser_state_tos->
514         cast_mask & (1 << parser_state_tos->
515                      p_l_follow) & ~parser_state_tos->sizeof_mask)
516     {
517         parser_state_tos->last_u_d = true;
518         parser_state_tos->cast_mask &=
519                 (1 << parser_state_tos->p_l_follow) - 1;
520         if (!parser_state_tos->cast_mask && settings.cast_space)
521         {
522             parser_state_tos->want_blank = true;
523         }
524         else
525         {
526             parser_state_tos->want_blank = false;
527             parser_state_tos->can_break = bb_cast;
528         }
529 
530         /* Check for a C99 compound literal */
531         tmp = token + 1;
532         while (isspace(*tmp)) tmp++;
533         if (*tmp == '{')
534             parser_state_tos->block_init = 3;
535     }
536     else if (parser_state_tos->in_decl &&
537              !parser_state_tos->block_init &&
538              (parser_state_tos->paren_depth == 0))
539     {
540         parser_state_tos->want_blank = true;
541     }
542     else
543     {
544       /* what ? */
545     }
546 
547     parser_state_tos->sizeof_mask &=
548             (1 << parser_state_tos->p_l_follow) - 1;
549 
550     if (--parser_state_tos->p_l_follow < 0)
551     {
552         parser_state_tos->p_l_follow = 0;
553         tmpchar[0] = *token; tmpchar[1] = '\0';
554         WARNING(_("Extra %s"), tmpchar, NULL);
555     }
556 
557     /* if the paren starts the line, then indent it */
558 
559     if (e_code == s_code)
560     {
561         int level = parser_state_tos->p_l_follow;
562 
563         parser_state_tos->paren_level = level;
564         if (level > 0)
565         {
566             paren_target = -parser_state_tos->paren_indents[level - 1];
567         }
568         else
569         {
570             paren_target = 0;
571         }
572     }
573 
574     if (settings.parentheses_space && *token != ']')
575     {
576         *(e_code++) = ' ';
577     }
578 
579     *(e_code++) = token[0];
580 
581     /* Something is setting want_blank to false whereas we need to emit
582      * a space if we have a single-line conditional, so make sure we
583      * indicate that we want a space before the next identifier.
584      */
585     if (settings.allow_single_line_conditionals && *(token - 1) == ')'
586         && *(token + 2) != '{' && !parser_state_tos->paren_depth)
587     {
588         parser_state_tos->want_blank = true;
589     }
590 
591     /* check for end of if (...), or some such */
592 
593     if (*sp_sw && (parser_state_tos->p_l_follow == 0))
594     {
595         /* Indicate that we have just left the parenthesized expression
596          * of a while, if, or for, unless we are getting out of the
597          * parenthesized expression of the while of a do-while loop.
598          * (do-while is different because a semicolon immediately
599          * following this will not indicate a null loop body).  */
600 
601         if (parser_state_tos->p_stack[parser_state_tos->tos] != dohead)
602         {
603             *last_token_ends_sp = 2;
604         }
605 
606         *sp_sw = false;
607         *force_nl = !settings.allow_single_line_conditionals;
608         parser_state_tos->last_u_d = true;  /* inform lexi that a
609                                              * following operator is
610                                              * unary */
611         parser_state_tos->in_stmt = false;  /* dont use stmt
612                                              * continuation
613                                              * indentation */
614 
615         if (parse (*hd_type) != total_success)
616         {
617             *file_exit_value = indent_error;
618         }
619     }
620 
621     /* this should ensure that constructs such as main(){...} and
622      * int[]{...} have their braces put in the right place
623      */
624 
625     parser_state_tos->search_brace = settings.btype_2;
626 }
627 
628 /**
629  *
630  */
631 
handle_token_unary_op(int * dec_ind,const bb_code_ty can_break)632 static void handle_token_unary_op(
633     int            * dec_ind,
634     const bb_code_ty can_break)
635 {
636     char           * t_ptr;
637 
638     if (parser_state_tos->want_blank &&
639         !(parser_state_tos->in_decl &&
640           !settings.pointer_align_right &&
641           *token == '*'))
642     {
643         set_buf_break (bb_unary_op, paren_target);
644         *(e_code++) = ' ';
645         *e_code = '\0';     /* null terminate code sect */
646         parser_state_tos->want_blank = false;
647     }
648     else if (can_break)
649     {
650         set_buf_break (can_break, paren_target);
651     }
652     else
653     {
654       /* what ? */
655     }
656 
657     {
658         char *res = token;
659         char *res_end = token_end;
660 
661         /* if this is a unary op in a declaration, we should
662          * indent this token */
663 
664         if ((parser_state_tos->paren_depth == 0) &&
665             parser_state_tos->in_decl && !buf_break_used &&
666             !parser_state_tos->block_init)
667         {
668             while ((e_code - s_code) < (*dec_ind - (token_end - token)))
669             {
670                 check_code_size();
671                 set_buf_break (bb_dec_ind, paren_target);
672                 *(e_code++) = ' ';
673             }
674 
675             parser_state_tos->ind_stmt = false;
676         }
677         else
678         {
679            /* avoid "- --a" becoming "---a" */
680 
681             if ((parser_state_tos->last_token == unary_op) &&
682                 (e_code > s_code) &&
683                  *res != '!' &&
684                 (*(e_code - 1) == *res))
685             {
686                 *(e_code++) = ' ';
687             }
688         }
689 
690         for (t_ptr = res; t_ptr < res_end; ++t_ptr)
691         {
692             check_code_size();
693             *(e_code++) = *t_ptr;
694         }
695 
696         if (parser_state_tos->want_blank &&
697             !(parser_state_tos->in_decl &&
698               settings.pointer_align_right &&
699               *token == '*'))
700         {
701             set_buf_break (bb_unary_op, paren_target);
702             *(e_code++) = ' ';
703         }
704 
705         *e_code = '\0';     /* null terminate code sect */
706     }
707 
708     parser_state_tos->want_blank = false;
709 }
710 
711 /**
712  *
713  */
714 
handle_token_binary_op(const bb_code_ty can_break)715 static void handle_token_binary_op(
716     const bb_code_ty can_break)
717 {
718     char           * t_ptr;
719 
720     if (parser_state_tos->want_blank        ||
721         (e_code > s_code && *e_code != ' '))
722     {
723         set_buf_break (bb_binary_op, paren_target);
724         *(e_code++) = ' ';
725         *e_code = '\0';     /* null terminate code sect */
726     }
727     else if (can_break)
728     {
729         set_buf_break (can_break, paren_target);
730     }
731     else
732     {
733       /* what ? */
734     }
735 
736     {
737         char *res = token;
738         char *res_end = token_end;
739 
740         for (t_ptr = res; t_ptr < res_end; ++t_ptr)
741         {
742             check_code_size();
743             *(e_code++) = *t_ptr;     /* move the operator */
744         }
745     }
746 
747 #if 1
748     if (*token == '=')
749     {
750         parser_state_tos->in_decl = false;
751 
752     }
753 #endif
754 
755     parser_state_tos->want_blank = true;
756 }
757 
758 /**
759  *
760  */
761 
handle_token_postop(void)762 static void handle_token_postop(void)
763 {
764     *(e_code++) = token[0];
765     *(e_code++) = token[1];
766     parser_state_tos->want_blank = true;
767 }
768 
769 /**
770  *
771  */
772 
handle_token_question(const bb_code_ty can_break)773 static void handle_token_question(
774    const bb_code_ty can_break)
775 {
776     squest++;               /* this will be used when a later colon
777                              * appears so we can distinguish the
778                              * <c>?<n>:<n> construct */
779 
780     if (parser_state_tos->want_blank)
781     {
782         set_buf_break (bb_question, paren_target);
783         *(e_code++) = ' ';
784     }
785     else if (can_break)
786     {
787         set_buf_break (can_break, paren_target);
788     }
789     else
790     {
791       /* what ? */
792     }
793 
794     *(e_code++) = '?';
795     parser_state_tos->want_blank = true;
796     *e_code = '\0'; /* null terminate code sect */
797 }
798 
799 /**
800  *
801  */
802 
handle_token_casestmt(BOOLEAN * scase,exit_values_ty * file_exit_value)803 static void handle_token_casestmt(
804    BOOLEAN        * scase,
805    exit_values_ty * file_exit_value)
806 {
807     *scase = true;           /* so we can process the later colon
808                               * properly */
809     do
810     {
811         if (parse (casestmt) != total_success)
812         {
813             *file_exit_value = indent_error;
814         }
815     } while(0);       /* Let parser know about it */
816 
817 }
818 
819 /**
820  *
821  */
822 
handle_token_colon(BOOLEAN * scase,BOOLEAN * force_nl,int * dec_ind,const bb_code_ty can_break,BOOLEAN * pbreak_line)823 static void handle_token_colon(
824    BOOLEAN        * scase,
825    BOOLEAN        * force_nl,
826    int            * dec_ind,
827    const bb_code_ty can_break,
828    BOOLEAN        * pbreak_line)
829 {
830     char           * t_ptr;
831 
832     if (squest > 0)
833     {
834         /* it is part of the <c> ? <n> : <n> construct */
835 
836         --squest;
837         if (parser_state_tos->want_blank)
838         {
839             set_buf_break (bb_colon, paren_target);
840             *(e_code++) = ' ';
841         }
842         else if (can_break)
843         {
844             set_buf_break (can_break, paren_target);
845         }
846         else
847         {
848           /* what ? */
849         }
850 
851         *(e_code++) = ':';
852         *e_code = '\0';     /* null terminate code sect */
853         parser_state_tos->want_blank = true;
854     }
855     else
856     {
857         /*            __ e_code
858          *           |
859          * "  private:\n"                     C++, treat as label.
860          *  ^^^        ^
861          *  |          |
862          *  |          `- buf_ptr (in different buffer though!)
863          *  `- s_code
864          *
865          * or
866          *
867          * "  unsigned int private:4\n"       C/C++, treat as bits.
868          */
869 
870         if (parser_state_tos->in_decl)
871         {
872             if (!(((e_code - s_code > 6) &&
873                    !strncmp (&buf_ptr[-8], "private:", 8)) &&
874                   !isdigit (*buf_ptr)) &&
875                 !(((e_code - s_code > 8) &&
876                    !strncmp (&buf_ptr[-10], "protected:", 10)) &&
877                   !isdigit (*buf_ptr)) &&
878                 !(((e_code - s_code > 5) &&
879                    !strncmp (&buf_ptr[-7], "public:", 7)) &&
880                   !isdigit (*buf_ptr)))
881             {
882                 *(e_code++) = ':';
883                 parser_state_tos->want_blank = false;
884                 return;
885             }
886             else if (*s_code == ' ')
887             {
888                 /*
889                  * It is possible that dec_ind spaces have been inserted before
890                  * the `public:' etc. label because indent thinks it's of the
891                  * type:
892                  */
893                 /*
894                  * Only now we see the '4' isn't there.
895                  * Remove those spaces:
896                  */
897 
898                 char *p1 = s_code;
899                 char *p2 = s_code + *dec_ind;
900 
901                 while (p2 < e_code)
902                 {
903                     *p1++ = *p2++;
904                 }
905 
906                 e_code -= *dec_ind;
907                 *e_code = '\0';
908             }
909             else
910             {
911               /* what ? */
912             }
913         }
914 
915         parser_state_tos->in_stmt = false;      /* seeing a label does not
916                                                  * imply we are in a stmt */
917         for (t_ptr = s_code; *t_ptr; ++t_ptr)
918         {
919             check_lab_size();
920             *e_lab++ = *t_ptr;  /* turn everything so far into a label */
921         }
922 
923         e_code = s_code;
924         clear_buf_break_list (pbreak_line); /* This is bullshit for C code, because
925                                              * normally a label doesn't have breakpoints
926                                              * at all of course.  But in the case of
927                                              * wrong code, not clearing the list can make
928                                              * indent core dump. */
929         *e_lab++ = ':';
930         set_buf_break (bb_label, paren_target);
931         *e_lab++ = ' ';
932         *e_lab = '\0';
933 
934         /* parser_state_tos->pcas e will be used by dump_line to decide
935          * how to indent the label. force_nl will force a case n: to be
936          * on a line by itself */
937 
938         *force_nl = parser_state_tos->pcase = *scase;
939         *scase = false;
940         parser_state_tos->want_blank = false;
941     }
942 }
943 
944 /**
945  *
946  */
947 
handle_token_doublecolon(void)948 static void handle_token_doublecolon(void)
949 {
950     *(e_code++) = ':';
951     *(e_code++) = ':';
952     parser_state_tos->want_blank = false;
953     parser_state_tos->can_break = bb_doublecolon;
954     parser_state_tos->last_u_d = true;
955     parser_state_tos->saw_double_colon = true;
956 }
957 
958 /**
959  *
960  */
961 
handle_token_semicolon(BOOLEAN * scase,BOOLEAN * force_nl,BOOLEAN * sp_sw,int * dec_ind,BOOLEAN * last_token_ends_sp,exit_values_ty * file_exit_value)962 static void handle_token_semicolon(
963     BOOLEAN        * scase,
964     BOOLEAN        * force_nl,
965     BOOLEAN        * sp_sw,
966     int            * dec_ind,
967     BOOLEAN        * last_token_ends_sp,
968     exit_values_ty * file_exit_value)
969 {
970     parser_state_tos->in_or_st = 0;
971     parser_state_tos->saw_double_colon = false;
972     *scase = false;
973     squest = 0;
974 
975     /* The following code doesn't seem to do much good. Just because
976      * we've found something like extern int foo();    or int (*foo)();
977      * doesn't mean we are out of a declaration.  Now if it was serving
978      * some purpose we'll have to address that.... if
979      * (parser_state_tos->last_token == rparen)
980      * parser_state_tos->in_parameter_declaration = 0; */
981 
982     parser_state_tos->cast_mask = 0;
983     parser_state_tos->sizeof_mask = 0;
984     parser_state_tos->block_init = 0;
985     parser_state_tos->block_init_level = 0;
986     parser_state_tos->just_saw_decl--;
987     parser_state_tos->is_func_ptr_decl = false;
988 
989     if (parser_state_tos->in_decl &&
990         (s_code == e_code) && !buf_break_used &&
991         !parser_state_tos->block_init)
992     {
993         while ((e_code - s_code) < (*dec_ind - 1))
994         {
995             check_code_size();
996             set_buf_break (bb_dec_ind, paren_target);
997             *(e_code++) = ' ';
998         }
999 
1000         parser_state_tos->ind_stmt = false;
1001     }
1002 
1003     *e_code = '\0'; /* null terminate code sect */
1004 
1005     /* if we were in a first level structure declaration,
1006      * we aren't any more */
1007 
1008     parser_state_tos->in_decl = (parser_state_tos->dec_nest > 0) ? true : false;
1009 
1010     /* If we have a semicolon following an if, while, or for, and the
1011      * user wants us to, we should insert a space (to show that there
1012      * is a null statement there).  */
1013 
1014     if (*last_token_ends_sp && settings.space_sp_semicolon)
1015     {
1016         *(e_code++) = ' ';
1017     }
1018 
1019     *(e_code++) = ';';
1020     *e_code = '\0'; /* null terminate code sect */
1021     parser_state_tos->want_blank = true;
1022 
1023     /* we are no longer in the middle of a stmt */
1024 
1025     parser_state_tos->in_stmt = (parser_state_tos->p_l_follow > 0);
1026 
1027     if (!*sp_sw)
1028     {                       /* if not if for (;;) */
1029         do
1030         {
1031             if (parse (semicolon) != total_success)
1032             {
1033                 *file_exit_value = indent_error;
1034             }
1035         } while(0);
1036 
1037         *force_nl = true;    /* force newline after a end of stmt */
1038     }
1039 }
1040 
1041 /**
1042  *
1043  */
1044 
handle_token_lbrace(BOOLEAN * force_nl,int * dec_ind,exit_values_ty * file_exit_value,BOOLEAN * pbreak_line)1045 static void handle_token_lbrace(
1046    BOOLEAN        * force_nl,
1047    int            * dec_ind,
1048    exit_values_ty * file_exit_value,
1049    BOOLEAN        * pbreak_line)
1050 {
1051     parser_state_tos->saw_double_colon = false;
1052 
1053     /* If the last token was a binary_op (probably =) then we're
1054      * likely starting an initializer or initializer list.
1055      */
1056     if (parser_state_tos->last_token == binary_op)
1057         parser_state_tos->block_init = 1;
1058 
1059     if (!parser_state_tos->block_init)
1060     {
1061         *force_nl = true;    /* force other stuff on same line as '{' onto
1062                               * new line */
1063         parser_state_tos->in_stmt = false;  /* dont indent the '{' */
1064     }
1065     else
1066     {
1067         /* dont indent the '{' unless it is followed by more code. */
1068 
1069         char *p = buf_ptr;
1070 
1071         for (;;)
1072         {
1073             p = skip_horiz_space(p);
1074 
1075             if (*p == EOL || (*p == '/' && p[1] == '/'))
1076             {
1077                 parser_state_tos->in_stmt = false;
1078                 break;
1079             }
1080             else if (*p == '/' && p[1] == '*')
1081             {
1082                 p += 2;
1083                 /* skip over comment */
1084 
1085                 while (*p && *p != EOL && (*p != '*' || p[1] != '/'))
1086                 {
1087                     ++p;
1088                 }
1089 
1090                 if (!*p || *p == EOL)
1091                 {
1092                     parser_state_tos->in_stmt = false;
1093                     break;
1094                 }
1095                 p += 2;
1096 
1097                 if (!*p)
1098                 {
1099                     break;
1100                 }
1101             }
1102             else
1103             {
1104                 break;
1105             }
1106 
1107         }
1108 
1109         if (parser_state_tos->block_init_level <= 0)
1110         {
1111             parser_state_tos->block_init_level = 1;
1112         }
1113         else
1114         {
1115             parser_state_tos->block_init_level++;
1116         }
1117     }
1118 
1119     if (s_code != e_code && parser_state_tos->block_init != 1)
1120     {
1121         if ((!parser_state_tos->in_decl && !settings.btype_2) ||
1122             (parser_state_tos->in_decl &&
1123              !settings.braces_on_struct_decl_line &&
1124              !settings.braces_on_func_def_line))
1125         {
1126             dump_line (true, &paren_target, pbreak_line);
1127             parser_state_tos->want_blank = false;
1128         }
1129         else
1130         {
1131             if (parser_state_tos->in_parameter_declaration &&
1132                 !parser_state_tos->in_or_st)
1133             {
1134                 parser_state_tos->i_l_follow = 0;
1135 
1136                 if (!settings.braces_on_func_def_line)
1137                 {
1138                     dump_line (true, &paren_target, pbreak_line);
1139                 }
1140                 else
1141                 {
1142                     *(e_code++) = ' ';
1143                 }
1144 
1145                 parser_state_tos->want_blank = false;
1146             }
1147             else
1148             {
1149                 parser_state_tos->want_blank = true;
1150             }
1151         }
1152     }
1153 
1154     if (parser_state_tos->in_parameter_declaration)
1155     {
1156         prefix_blankline_requested = 0;
1157     }
1158 
1159     if (s_code == e_code)
1160     {
1161         parser_state_tos->ind_stmt = false; /* dont put extra indentation
1162                                                on line with '{' */
1163     }
1164 
1165     if (parser_state_tos->in_decl && parser_state_tos->in_or_st)
1166     {
1167         /* This is a structure declaration.  */
1168         if (parser_state_tos->dec_nest >= di_stack_alloc)
1169         {
1170             di_stack_alloc *= 2;
1171             di_stack = xrealloc(di_stack,
1172                                 di_stack_alloc * sizeof(*di_stack));
1173         }
1174 
1175         di_stack[parser_state_tos->dec_nest++] = *dec_ind;
1176     }
1177     else
1178     {
1179         parser_state_tos->in_decl = false;
1180         parser_state_tos->decl_on_line = false;     /* we cant be in the
1181                                                      * middle of a
1182                                                      * declaration, so dont
1183                                                      * do special
1184                                                      * indentation of
1185                                                      * comments */
1186 
1187         parser_state_tos->in_parameter_declaration = 0;
1188     }
1189 
1190     *dec_ind = 0;
1191 
1192     /* We are no longer looking for an initializer or structure. Needed
1193      * so that the '=' in "enum bar {a = 1" does not get interpreted as
1194      * the start of an initializer.  */
1195 
1196     parser_state_tos->in_or_st = 0;
1197 
1198     do
1199     {
1200         if (parse (lbrace) != total_success)
1201         {
1202             *file_exit_value = indent_error;
1203         }
1204     } while(0);
1205 
1206     set_buf_break (bb_lbrace, paren_target);
1207 
1208     if (parser_state_tos->want_blank && s_code != e_code)
1209     {
1210         /* put a blank before '{' if '{' is not at start of line */
1211 
1212         *(e_code++) = ' ';
1213     }
1214 
1215     parser_state_tos->want_blank = false;
1216     *(e_code++) = '{';
1217     *e_code = '\0'; /* null terminate code sect */
1218 
1219     parser_state_tos->just_saw_decl = 0;
1220 
1221     if (parser_state_tos->block_init &&
1222         (parser_state_tos->block_init_level >= 2))
1223     {
1224         /* Treat the indentation of the second '{' as a '('
1225          * in * struct foo { { bar }, ... } */
1226 
1227         if (++parser_state_tos->p_l_follow >=
1228             parser_state_tos->paren_indents_size)
1229         {
1230             parser_state_tos->paren_indents_size *= 2;
1231             parser_state_tos->paren_indents =
1232                     xrealloc(parser_state_tos->paren_indents,
1233                              parser_state_tos->paren_indents_size *
1234                              sizeof(short));
1235         }
1236 
1237         ++parser_state_tos->paren_depth;
1238         parser_state_tos->paren_indents[parser_state_tos->p_l_follow -
1239                                         1] = e_code - s_code;
1240         if (settings.spaces_around_initializers)
1241             parser_state_tos->want_blank = true;
1242     }
1243     else if (parser_state_tos->block_init &&
1244              (parser_state_tos->block_init_level == 1))
1245     {
1246         /* Put a blank after the first '{' */
1247 
1248         parser_state_tos->want_blank = true;
1249     }
1250     else
1251     {
1252       /* what ? */
1253     }
1254 }
1255 
1256 /**
1257  *
1258  */
1259 
handle_token_rbrace(BOOLEAN * force_nl,int * dec_ind,exit_values_ty * file_exit_value,BOOLEAN * pbreak_line)1260 static void handle_token_rbrace(
1261     BOOLEAN        * force_nl,
1262     int            * dec_ind,
1263     exit_values_ty * file_exit_value,
1264     BOOLEAN        * pbreak_line)
1265 {
1266     char tmpchar[2];
1267 
1268     /* semicolons can be omitted in declarations */
1269     if (((parser_state_tos->p_stack[parser_state_tos->tos] == decl) &&
1270          !parser_state_tos->block_init) ||
1271         /* ANSI C forbids label at end of compound statement, but we don't I guess :/ */
1272         (parser_state_tos->p_stack[parser_state_tos->tos] == casestmt))
1273     {
1274         if (parse (semicolon) != total_success)
1275         {
1276             *file_exit_value = indent_error;
1277         }
1278     }
1279 
1280     parser_state_tos->just_saw_decl = 0;
1281     parser_state_tos->ind_stmt = false;
1282     parser_state_tos->in_stmt  = false;
1283     parser_state_tos->block_init_level--;
1284 
1285     if ((parser_state_tos->block_init_level == 0)
1286         && (s_code != e_code))
1287     {
1288         /* Found closing brace of declaration initialisation, with
1289          * code on the same line before the brace */
1290 
1291         if (parser_state_tos->matching_brace_on_same_line < 0)
1292         {
1293             /* The matching '{' is not on the same line:
1294              * put the '}' on its own line. */
1295 
1296             dump_line (true, &paren_target, pbreak_line);
1297         }
1298         else
1299         {
1300             /* Put a space before the '}' */
1301             set_buf_break (bb_rbrace, paren_target);
1302             *(e_code++) = ' ';
1303         }
1304     }
1305     else if (parser_state_tos->block_init_level == 1
1306              && settings.spaces_around_initializers)
1307     {
1308              /* Put a space before the '}' */
1309             set_buf_break (bb_rbrace, paren_target);
1310             *(e_code++) = ' ';
1311     }
1312 
1313     *(e_code++) = '}';
1314     parser_state_tos->want_blank = true;
1315 
1316     if (parser_state_tos->block_init &&
1317         (parser_state_tos->block_init_level > 0))
1318     {
1319         /* We were treating this { } as normal ( ) */
1320 
1321         --parser_state_tos->paren_depth;
1322 
1323         if (--parser_state_tos->p_l_follow < 0)
1324         {
1325             parser_state_tos->p_l_follow = 0;
1326             tmpchar[0] = *token;
1327             tmpchar[1] = '\0';
1328             WARNING(_("Extra %s"), tmpchar, NULL);
1329         }
1330     }
1331     else if (parser_state_tos->dec_nest > 0)
1332     {
1333         /* we are in multi-level structure
1334          * declaration */
1335 
1336         *dec_ind = di_stack[--parser_state_tos->dec_nest];
1337 
1338         if ((parser_state_tos->dec_nest == 0) &&
1339             !parser_state_tos->in_parameter_declaration)
1340         {
1341             parser_state_tos->just_saw_decl = 2;
1342         }
1343 
1344         parser_state_tos->in_decl = true;
1345     }
1346     else
1347     {
1348       /* what ? */
1349     }
1350 
1351     prefix_blankline_requested = 0;
1352 
1353     if (parse (rbrace) != total_success)
1354     {
1355         *file_exit_value = indent_error;
1356     }
1357 
1358     parser_state_tos->search_brace =
1359             (settings.cuddle_else &&
1360              (parser_state_tos->p_stack[parser_state_tos->tos] == ifhead)) ||
1361             (settings.cuddle_do_while &&
1362              (parser_state_tos->p_stack[parser_state_tos->tos] == dohead));
1363 
1364     if (parser_state_tos->p_stack[parser_state_tos->tos] == stmtl)
1365     {
1366         if ( (parser_state_tos->last_rw != rw_struct_like) &&
1367              (parser_state_tos->last_rw != rw_enum) &&
1368              (parser_state_tos->last_rw != rw_decl) )
1369         {
1370             *force_nl = true;
1371         }
1372 #if 0
1373         else if (!settings.braces_on_struct_decl_line &&
1374                  (parser_state_tos->block_init != 1))
1375         {
1376             *force_nl = true;
1377         }
1378         else
1379         {
1380           /* what ? */
1381         }
1382 #endif
1383     }
1384 
1385     if ( (parser_state_tos->p_stack[parser_state_tos->tos] == ifhead) ||
1386          ( (parser_state_tos->p_stack[parser_state_tos->tos] == dohead) &&
1387            !settings.cuddle_do_while && !settings.btype_2))
1388     {
1389         *force_nl = true;
1390     }
1391 
1392     if (!parser_state_tos->in_decl && (parser_state_tos->tos <= 0) &&
1393         settings.blanklines_after_procs && (parser_state_tos->dec_nest <= 0))
1394     {
1395         postfix_blankline_requested = 1;
1396         postfix_blankline_requested_code =
1397                 parser_state_tos->in_decl ? decl : rbrace;
1398     }
1399 }
1400 
1401 /**
1402  *
1403  */
1404 
handle_token_swstmt(BOOLEAN * sp_sw,codes_ty * hd_type)1405 static void handle_token_swstmt(
1406     BOOLEAN        * sp_sw,
1407     codes_ty       * hd_type)
1408 {
1409 
1410     *sp_sw = true;
1411     *hd_type = swstmt;       /* keep this for when we have seen the
1412                               * expression */
1413     parser_state_tos->in_decl = false;
1414 }
1415 
1416 /**
1417  *
1418  */
1419 
handle_token_sp_paren(BOOLEAN * sp_sw,codes_ty * hd_type)1420 static void handle_token_sp_paren(
1421     BOOLEAN        * sp_sw,
1422     codes_ty       * hd_type)
1423 {
1424     /* the interesting stuff is done after the expression is scanned */
1425     *sp_sw = true;
1426 
1427     /* remember the type of header for later use by parser */
1428     *hd_type =
1429             (*token == 'i' ? ifstmt : (*token == 'w' ? whilestmt : forstmt));
1430 }
1431 
1432 /**
1433  *
1434  */
1435 
handle_token_nparen(BOOLEAN * force_nl,exit_values_ty * file_exit_value,BOOLEAN * last_else,BOOLEAN * pbreak_line)1436 static void handle_token_nparen(
1437     BOOLEAN        * force_nl,
1438     exit_values_ty * file_exit_value,
1439     BOOLEAN        * last_else,
1440     BOOLEAN        * pbreak_line)
1441 {
1442     parser_state_tos->in_stmt = false;
1443     if (*token == 'e')
1444     {
1445         if (e_code != s_code && (!settings.cuddle_else || e_code[-1] != '}'))
1446         {
1447             if (settings.verbose)
1448             {
1449                 WARNING(_("Line broken"), NULL, NULL);
1450             }
1451 
1452             dump_line (true, &paren_target, pbreak_line);       /* make sure this starts a line */
1453             parser_state_tos->want_blank = false;
1454         }
1455 
1456         /* This will be over ridden when next we read an `if' */
1457 
1458         *force_nl = true;    /* also, following stuff must go onto new
1459                               * line */
1460         *last_else = 1;
1461 
1462         if (parse (elselit) != total_success)
1463         {
1464             *file_exit_value = indent_error;
1465         }
1466     }
1467     else
1468     {
1469         if (e_code != s_code)
1470         {
1471             /* make sure this starts a line */
1472 
1473             if (settings.verbose)
1474             {
1475                 WARNING(_("Line broken"), NULL, NULL);
1476             }
1477 
1478             dump_line (true, &paren_target, pbreak_line);
1479             parser_state_tos->want_blank = false;
1480         }
1481 
1482         *force_nl = true;    /* also, following stuff must go onto new
1483                               * line */
1484         *last_else = 0;
1485 
1486         if (parse (dolit) != total_success)
1487         {
1488             *file_exit_value = indent_error;
1489         }
1490     }
1491 }
1492 
1493 /**
1494  *
1495  */
1496 
handle_token_overloaded(const bb_code_ty can_break)1497 static void handle_token_overloaded(
1498     const bb_code_ty can_break)
1499 {
1500     char           * t_ptr;
1501 
1502     if (parser_state_tos->want_blank)
1503     {
1504         set_buf_break (bb_overloaded, paren_target);
1505         *(e_code++) = ' ';
1506     }
1507     else if (can_break)
1508     {
1509         set_buf_break (can_break, paren_target);
1510     }
1511     else
1512     {
1513       /* what ? */
1514     }
1515 
1516     parser_state_tos->want_blank = true;
1517 
1518     for (t_ptr = token; t_ptr < token_end; ++t_ptr)
1519     {
1520         check_code_size();
1521         *(e_code++) = *t_ptr;
1522     }
1523 
1524     *e_code = '\0'; /* null terminate code sect */
1525 }
1526 
1527 /**
1528  *
1529  */
1530 
handle_token_decl(int * dec_ind,exit_values_ty * file_exit_value,BOOLEAN * pbreak_line)1531 static void handle_token_decl(
1532     int            * dec_ind,
1533     exit_values_ty * file_exit_value,
1534     BOOLEAN        * pbreak_line)
1535 {
1536     /* handle C++ const function declarations like
1537      * const MediaDomainList PVR::get_itsMediaDomainList() const
1538      * {
1539      * return itsMediaDomainList;
1540      * }
1541      * by ignoring "const" just after a parameter list */
1542 
1543     if ((parser_state_tos->last_token == rparen) &&
1544         parser_state_tos->in_parameter_declaration &&
1545         parser_state_tos->saw_double_colon &&
1546         !strncmp (token, "const", 5))
1547     {
1548         set_buf_break (bb_const_qualifier, paren_target);
1549     }
1550     else
1551     {
1552 
1553         if (!parser_state_tos->sizeof_mask)
1554         {
1555             if (parse (decl) != total_success)
1556             {
1557                 *file_exit_value = indent_error;
1558             }
1559         }
1560 
1561         if ((parser_state_tos->last_token == rparen) &&
1562             (parser_state_tos->tos <= 1))
1563         {
1564             parser_state_tos->in_parameter_declaration = 1;
1565 
1566             if (s_code != e_code)
1567             {
1568                 dump_line (true, &paren_target, pbreak_line);
1569                 parser_state_tos->want_blank = false;
1570             }
1571         }
1572 
1573         if (parser_state_tos->in_parameter_declaration &&
1574             (parser_state_tos->dec_nest == 0) &&
1575             (parser_state_tos->p_l_follow == 0))
1576         {
1577             parser_state_tos->ind_level = parser_state_tos->i_l_follow =
1578                     settings.indent_parameters;
1579 
1580             parser_state_tos->ind_stmt = false;
1581         }
1582 
1583         /* in_or_st set for struct or initialization decl. Don't set it if
1584          * we're in ansi prototype */
1585 
1586         if (!parser_state_tos->paren_depth)
1587         {
1588             parser_state_tos->in_or_st = 1;
1589         }
1590 
1591         if (!parser_state_tos->sizeof_mask)
1592         {
1593             parser_state_tos->in_decl      = true;
1594             parser_state_tos->decl_on_line = true;
1595 
1596             if (parser_state_tos->dec_nest <= 0)
1597             {
1598                 parser_state_tos->just_saw_decl = 2;
1599             }
1600         }
1601 
1602 #if 0
1603         /* Erik de Castro Lopo Sun, 28 Sep 2003:
1604          * I don't know what this is supposed to do, but I do know that it
1605          * breaks the operation of the blanklines_after_procs setting in
1606          * situations like this where a blank line is supposed to be inserted
1607          * between the two functions:
1608          *
1609          *     int func1 (void)
1610          *     {
1611          *         return 42 ;
1612          *     }
1613          *     static int func2 (void)
1614          *     {
1615          *         return 43 ;
1616          *     }
1617          *
1618          * If this code is removed, the regression tests still pass (except
1619          * for one which needs to be modified because a blank line is
1620          * inserted as it should be.
1621          */
1622 
1623         if (prefix_blankline_requested &&
1624             ((parser_state_tos->block_init != 0) ||
1625              (parser_state_tos->block_init_level != -1) ||
1626              (parser_state_tos->last_token != rbrace) ||
1627              (e_code != s_code) ||
1628              (e_lab  != s_lab)  ||
1629              (e_com  != s_com)))
1630         {
1631             prefix_blankline_requested = 0;
1632         }
1633 #endif
1634         *dec_ind = settings.decl_indent > 0 ? settings.decl_indent :
1635                                               token_end - token + 1; /* get length of token plus 1 */
1636     }
1637 }
1638 
1639 /**
1640  *
1641  */
1642 
handle_token_ident(BOOLEAN * force_nl,BOOLEAN * sp_sw,codes_ty * hd_type,int * dec_ind,exit_values_ty * file_exit_value,const bb_code_ty can_break,BOOLEAN is_procname_definition,BOOLEAN * pbreak_line)1643 static void handle_token_ident(
1644     BOOLEAN        * force_nl,
1645     BOOLEAN        * sp_sw,
1646     codes_ty       * hd_type,
1647     int            * dec_ind,
1648     exit_values_ty * file_exit_value,
1649     const bb_code_ty can_break,
1650     BOOLEAN          is_procname_definition,
1651     BOOLEAN        * pbreak_line)
1652 {
1653     /* If we are in a declaration, we must indent identifier. But not
1654      * inside the parentheses of an ANSI function declaration.  */
1655 
1656     if (parser_state_tos->in_decl &&
1657         (parser_state_tos->p_l_follow == 0) &&
1658         (parser_state_tos->last_token != rbrace))
1659     {
1660         if (parser_state_tos->want_blank)
1661         {
1662             set_buf_break (bb_ident, paren_target);
1663             *(e_code++) = ' ';
1664             *e_code = '\0'; /* null terminate code sect */
1665         }
1666         else if (can_break)
1667         {
1668             set_buf_break (can_break, paren_target);
1669         }
1670         else
1671         {
1672           /* what ? */
1673         }
1674 
1675         parser_state_tos->want_blank = false;
1676 
1677         if ((is_procname_definition == false) ||
1678             (!settings.procnames_start_line && (s_code != e_code)))
1679         {
1680             if (!parser_state_tos->block_init && !buf_break_used)
1681             {
1682                 if (is_procname_definition)
1683                 {
1684                     *dec_ind = 0;
1685                 }
1686 
1687                 while ((e_code - s_code) < *dec_ind)
1688                 {
1689                     check_code_size();
1690                     set_buf_break (bb_dec_ind, paren_target);
1691                     *(e_code++) = ' ';
1692                 }
1693 
1694                 *e_code = '\0';     /* null terminate code sect */
1695                 parser_state_tos->ind_stmt = false;
1696             }
1697         }
1698         else
1699         {
1700             if ((s_code != e_code) &&
1701                 (parser_state_tos->last_token != doublecolon))
1702             {
1703                 dump_line(true, &paren_target, pbreak_line);
1704             }
1705 
1706             *dec_ind = 0;
1707             parser_state_tos->want_blank = false;
1708         }
1709     }
1710     else if (*sp_sw && parser_state_tos->p_l_follow == 0)
1711     {
1712         *sp_sw = false;
1713         *force_nl = true;
1714         parser_state_tos->last_u_d = true;
1715         parser_state_tos->in_stmt = false;
1716 
1717         if (parse (*hd_type) != total_success)
1718         {
1719             *file_exit_value = indent_error;
1720         }
1721     }
1722     else
1723     {
1724       /* what ? */
1725     }
1726 }
1727 
1728 /**
1729  *
1730  */
1731 
handle_token_struct_delim(void)1732 static void handle_token_struct_delim(void)
1733 {
1734     char           * t_ptr;
1735     for (t_ptr = token; t_ptr < token_end; ++t_ptr)
1736     {
1737         check_code_size();
1738         *(e_code++) = *t_ptr;
1739     }
1740 
1741     parser_state_tos->want_blank = false;   /* dont put a blank after a
1742                                              * period */
1743     parser_state_tos->can_break = bb_struct_delim;
1744 }
1745 
1746 /**
1747  *
1748  */
1749 
handle_token_comma(BOOLEAN * force_nl,int * dec_ind,BOOLEAN is_procname_definition)1750 static void handle_token_comma(
1751     BOOLEAN        * force_nl,
1752     int            * dec_ind,
1753     BOOLEAN          is_procname_definition)
1754 {
1755     parser_state_tos->want_blank = true;
1756 
1757     if ((parser_state_tos->paren_depth == 0) &&
1758         parser_state_tos->in_decl &&
1759         !buf_break_used && (is_procname_definition == false) &&
1760         !parser_state_tos->block_init)
1761     {
1762         while ((e_code - s_code) < (*dec_ind - 1))
1763         {
1764             check_code_size();
1765             set_buf_break (bb_dec_ind, paren_target);
1766             *(e_code++) = ' ';
1767         }
1768 
1769         parser_state_tos->ind_stmt = false;
1770     }
1771 
1772     *(e_code++) = ',';
1773 
1774     if (parser_state_tos->p_l_follow == 0)
1775     {
1776         if (parser_state_tos->block_init_level <= 0)
1777         {
1778             parser_state_tos->block_init = 0;
1779         }
1780 
1781         /* If we are in a declaration, and either the user wants all
1782          * comma'd declarations broken, or the line is getting too
1783          * long, break the line.  */
1784 
1785         if (break_comma && !settings.leave_comma)
1786         {
1787             *force_nl = true;
1788         }
1789     }
1790 
1791     if (parser_state_tos->block_init)
1792     {
1793         parser_state_tos->in_stmt = false;  /* Don't indent after comma */
1794     }
1795 
1796     /* For declarations, if user wants all fn decls broken, force that
1797      * now. */
1798 
1799     if (settings.break_function_decl_args &&
1800         (!parser_state_tos->in_or_st &&
1801          parser_state_tos->in_stmt && parser_state_tos->in_decl))
1802     {
1803         *force_nl = true;
1804     }
1805 
1806 }
1807 
1808 /**
1809  *
1810  */
1811 
1812 
handle_token_preesc(exit_values_ty * file_exit_value,BOOLEAN * pbreak_line)1813 static void handle_token_preesc(
1814     exit_values_ty * file_exit_value,
1815     BOOLEAN        * pbreak_line)
1816 {
1817     char * t_ptr;
1818     char * p;
1819 
1820     if ((s_com != e_com) || (s_lab != e_lab) || (s_code != e_code))
1821     {
1822         dump_line(true, &paren_target, pbreak_line);
1823     }
1824 
1825     {
1826         int in_comment = 0;
1827         int in_cplus_comment = 0;
1828         int com_start = 0;
1829         char quote = 0;
1830         int com_end = 0;
1831 
1832         /* ANSI allows spaces between '#' and preprocessor directives.
1833          * If the user specified "-lps" and there are such spaces,
1834          * they will be part of `token', otherwise `token' is just
1835          * '#'. */
1836 
1837         for (t_ptr = token; t_ptr < token_end; ++t_ptr)
1838         {
1839             check_lab_size();
1840             *e_lab++ = *t_ptr;
1841         }
1842 
1843         while (!had_eof && (*buf_ptr != EOL || in_comment))
1844         {
1845             check_lab_size();
1846             *e_lab = *buf_ptr++;
1847 
1848             if (buf_ptr >= buf_end)
1849             {
1850                 fill_buffer();
1851             }
1852 
1853             switch (*e_lab++)
1854             {
1855             case BACKSLASH:
1856                 if (!in_comment && !in_cplus_comment)
1857                 {
1858                     *e_lab++ = *buf_ptr++;
1859                     if (buf_ptr >= buf_end)
1860                     {
1861                         fill_buffer();
1862                     }
1863                 }
1864                 break;
1865 
1866             case '/':
1867                 if (((*buf_ptr == '*') ||
1868                      (*buf_ptr == '/')) &&
1869                     !in_comment && !in_cplus_comment && !quote)
1870                 {
1871                     save_com.column = current_column () - 1;
1872 
1873                     if (*buf_ptr == '/')
1874                     {
1875                         in_cplus_comment = 1;
1876                     }
1877                     else
1878                     {
1879                         in_comment = 1;
1880                     }
1881 
1882                     *e_lab++ = *buf_ptr++;
1883                     com_start = e_lab - s_lab - 2;
1884 
1885                     /* Store the column that corresponds with the start
1886                      * of the buffer */
1887 
1888                     if (save_com.ptr == save_com.end)
1889                     {
1890                         save_com.start_column = current_column () - 2;
1891                     }
1892                 }
1893                 break;
1894 
1895             case '"':
1896             case '\'':
1897                 if (!quote)
1898                 {
1899                     quote = e_lab[-1];
1900                 }
1901                 else if (e_lab[-1] == quote)
1902                 {
1903                     quote = 0;
1904                 }
1905                 else
1906                 {
1907                   /* what ? */
1908                 }
1909 
1910                 break;
1911 
1912             case '*':
1913                 if (*buf_ptr == '/' && in_comment)
1914                 {
1915                     in_comment = 0;
1916                     *e_lab++ = *buf_ptr++;
1917                     com_end = e_lab - s_lab;
1918                 }
1919                 break;
1920             }
1921         }
1922 
1923         while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == TAB))
1924         {
1925             e_lab--;
1926         }
1927 
1928 
1929         if (in_cplus_comment)   /* Should we also check in_comment? -jla */
1930         {
1931             in_cplus_comment = 0;
1932             *e_lab++ = *buf_ptr++;
1933             com_end = e_lab - s_lab;
1934         }
1935 
1936         if (e_lab - s_lab == com_end && bp_save == 0)
1937         {
1938             /* comment on preprocessor line */
1939 
1940             if (save_com.end != save_com.ptr)
1941             {
1942                 need_chars (&save_com, 2);
1943                 *save_com.end++ = EOL;  /* add newline between
1944                                          * comments */
1945                 *save_com.end++ = ' ';
1946                 save_com.len += 2;
1947                 --line_no;
1948             }
1949 
1950             need_chars (&save_com, com_end - com_start + 1);
1951             strncpy (save_com.end, s_lab + com_start,
1952                      com_end - com_start);
1953             save_com.end[com_end - com_start] = '\0';
1954             save_com.end += com_end - com_start;
1955             save_com.len += com_end - com_start;
1956 
1957             e_lab = s_lab + com_start;
1958 
1959             while ((e_lab > s_lab) &&
1960                    ((e_lab[-1] == ' ') || (e_lab[-1] == TAB)))
1961             {
1962                 e_lab--;
1963             }
1964 
1965 
1966             /* Switch input buffers so that calls to lexi() will
1967              * read from our save buffer. */
1968 
1969             bp_save = buf_ptr;
1970             be_save = buf_end;
1971             buf_ptr = save_com.ptr;
1972             need_chars (&save_com, 1);
1973             buf_end = save_com.end;
1974             save_com.end = save_com.ptr;        /* make save_com empty */
1975         }
1976 
1977         *e_lab = '\0';  /* null terminate line */
1978         parser_state_tos->pcase = false;
1979     }
1980 
1981     p = s_lab + 1;
1982 
1983     p = skip_horiz_space(p);
1984 
1985     if (strncmp (p, "if", 2) == 0)
1986     {
1987         if (settings.blanklines_around_conditional_compilation)
1988         {
1989             prefix_blankline_requested++;
1990             prefix_blankline_requested_code = preesc;
1991 
1992             while (*in_prog_pos++ == EOL)
1993             {
1994             }
1995 
1996             in_prog_pos--;
1997         }
1998 
1999         {
2000             /* Push a copy of the parser_state onto the stack. All
2001              * manipulations will use the copy at the top of stack, and
2002              * then we can return to the previous state by popping the
2003              * stack.  */
2004 
2005             parser_state_ty *new;
2006 
2007             new = xmalloc(sizeof(parser_state_ty));
2008             memcpy(new, parser_state_tos, sizeof(parser_state_ty));
2009 
2010             /* We need to copy the dynamically allocated arrays in the
2011              * struct parser_state too.  */
2012 
2013             new->p_stack = xmalloc(parser_state_tos->p_stack_size *
2014                                    sizeof(codes_ty));
2015             memcpy(new->p_stack, parser_state_tos->p_stack,
2016                    (parser_state_tos->p_stack_size * sizeof(codes_ty)));
2017 
2018             new->il = xmalloc(parser_state_tos->p_stack_size *
2019                               sizeof (int));
2020             memcpy(new->il, parser_state_tos->il,
2021                    parser_state_tos->p_stack_size * sizeof(int));
2022 
2023             new->cstk = xmalloc(parser_state_tos->p_stack_size * sizeof(int));
2024             memcpy(new->cstk, parser_state_tos->cstk,
2025                    parser_state_tos->p_stack_size * sizeof(int));
2026 
2027             new->paren_indents = xmalloc(parser_state_tos->paren_indents_size *
2028                                          sizeof (short));
2029             memcpy(new->paren_indents,parser_state_tos->paren_indents,
2030                    (parser_state_tos->paren_indents_size * sizeof(short)));
2031 
2032             new->next = parser_state_tos;
2033             parser_state_tos = new;
2034             /* GDB_HOOK_parser_state_tos */
2035         }
2036     }
2037     else if ((strncmp (p, "else", 4) == 0) ||
2038              (strncmp (p, "elif", 4) == 0))
2039     {
2040         /* When we get #else, we want to restore the parser state to
2041          * what it was before the matching #if, so that things get
2042          * lined up with the code before the #if.  However, we do not
2043          * want to pop the stack; we just want to copy the second to
2044          * top elt of the stack because when we encounter the #endif,
2045          * it will pop the stack.  */
2046 
2047         else_or_endif = (strncmp (p, "else", 4) == 0);
2048         prefix_blankline_requested = 0;
2049 
2050         if (parser_state_tos->next)
2051         {
2052             /* First save the addresses of the arrays for the top of
2053              * stack.  */
2054 
2055             codes_ty * tos_p_stack       = parser_state_tos->p_stack;
2056             int      * tos_il            = parser_state_tos->il;
2057             int      * tos_cstk          = parser_state_tos->cstk;
2058             short    * tos_paren_indents =
2059                     parser_state_tos->paren_indents;
2060             parser_state_ty * second = parser_state_tos->next;
2061 
2062             (void) memcpy (parser_state_tos, second,
2063                            sizeof (parser_state_ty));
2064             parser_state_tos->next = second;
2065 
2066             /* Now copy the arrays from the second to top of stack to
2067              * the top of stack.  */
2068 
2069             /* Since the p_stack, etc. arrays only grow, never shrink,
2070              * we know that they will be big enough to fit the array
2071              * from the second to top of stack.  */
2072 
2073             parser_state_tos->p_stack = tos_p_stack;
2074             (void) memcpy (parser_state_tos->p_stack,
2075                            parser_state_tos->next->p_stack,
2076                            parser_state_tos->p_stack_size *
2077                            sizeof (codes_ty));
2078 
2079             parser_state_tos->il = tos_il;
2080             (void) memcpy (parser_state_tos->il,
2081                            parser_state_tos->next->il,
2082                            (parser_state_tos->p_stack_size *
2083                             sizeof (int)));
2084 
2085             parser_state_tos->cstk = tos_cstk;
2086             (void) memcpy (parser_state_tos->cstk,
2087                            parser_state_tos->next->cstk,
2088                            (parser_state_tos->p_stack_size *
2089                             sizeof (int)));
2090 
2091             parser_state_tos->paren_indents = tos_paren_indents;
2092             (void) memcpy (parser_state_tos->paren_indents,
2093                            parser_state_tos->next->paren_indents,
2094                            (parser_state_tos->paren_indents_size *
2095                             sizeof (short)));
2096         }
2097         else
2098         {
2099             ERROR (else_or_endif ? _("Unmatched #else") :
2100                    _("Unmatched #elif"), 0, 0);
2101             *file_exit_value = indent_error;
2102         }
2103     }
2104     else if (strncmp (p, "endif", 5) == 0)
2105     {
2106         else_or_endif = true;
2107         prefix_blankline_requested = 0;
2108         /* We want to remove the second to top elt on the stack, which
2109          * was put there by #if and was used to restore the stack at
2110          * the #else (if there was one). We want to leave the top of
2111          * stack unmolested so that the state which we have been using
2112          * is unchanged.  */
2113 
2114         if (parser_state_tos->next)
2115         {
2116             parser_state_ty *second = parser_state_tos->next;
2117 
2118             parser_state_tos->next = second->next;
2119             xfree(second->p_stack);
2120             xfree(second->il);
2121             xfree(second->cstk);
2122             xfree(second->paren_indents);
2123             xfree(second);
2124         }
2125         else
2126         {
2127             ERROR (_("Unmatched #endif"), 0, 0);
2128             *file_exit_value = indent_error;
2129         }
2130 
2131         if (settings.blanklines_around_conditional_compilation)
2132         {
2133             postfix_blankline_requested++;
2134             postfix_blankline_requested_code = preesc;
2135             n_real_blanklines = 0;
2136         }
2137     }
2138     else
2139     {
2140       /* what ? */
2141     }
2142 
2143     /* Don't put a blank line after declarations if they are directly
2144      * followed by an #else or #endif -Run */
2145 
2146     if (else_or_endif && prefix_blankline_requested_code == decl)
2147     {
2148         prefix_blankline_requested = 0;
2149     }
2150 
2151     /* Normally, subsequent processing of the newline character
2152      * causes the line to be printed.  The following clause handles
2153      * a special case (comma-separated declarations separated
2154      * by the preprocessor lines) where this doesn't happen. */
2155 
2156     if ((parser_state_tos->last_token == comma) &&
2157         (parser_state_tos->p_l_follow <= 0) &&
2158         settings.leave_comma &&
2159         !parser_state_tos->block_init &&
2160         break_comma && (s_com == e_com))
2161     {
2162         dump_line(true, &paren_target, pbreak_line);
2163         parser_state_tos->want_blank = false;
2164     }
2165 
2166 }
2167 
2168 /**
2169  *
2170  */
2171 
2172 
handle_token_comment(BOOLEAN * force_nl,BOOLEAN * flushed_nl,BOOLEAN * pbreak_line)2173 static void handle_token_comment(
2174     BOOLEAN        * force_nl,
2175     BOOLEAN        * flushed_nl,
2176     BOOLEAN        * pbreak_line)
2177 {
2178             if (parser_state_tos->last_saw_nl && (s_code != e_code))
2179             {
2180                 *flushed_nl = false;
2181                 dump_line(true, &paren_target, pbreak_line);
2182                 parser_state_tos->want_blank = false;
2183                 *force_nl = false;
2184             }
2185             print_comment (&paren_target, pbreak_line);
2186 }
2187 
2188 /**
2189  *
2190  */
2191 
2192 
handle_token_attribute(void)2193 static void handle_token_attribute(void)
2194 {
2195     char           * t_ptr;
2196 
2197     if (s_code != e_code)
2198     {
2199         set_buf_break (bb_attribute, paren_target);
2200         *(e_code++) = ' ';
2201     }
2202 
2203     for (t_ptr = token; t_ptr < token_end; ++t_ptr)
2204     {
2205         check_code_size();
2206         *(e_code++) = *t_ptr;
2207     }
2208 
2209     parser_state_tos->in_decl = false;
2210     parser_state_tos->want_blank = settings.blank_after_sizeof;
2211 }
2212 
2213 /**
2214  *
2215  */
2216 
2217 
handle_the_token(const codes_ty type_code,BOOLEAN * scase,BOOLEAN * force_nl,BOOLEAN * sp_sw,BOOLEAN * flushed_nl,codes_ty * hd_type,int * dec_ind,BOOLEAN * last_token_ends_sp,exit_values_ty * file_exit_value,const bb_code_ty can_break,BOOLEAN * last_else,BOOLEAN is_procname_definition,BOOLEAN * pbreak_line)2218 extern void handle_the_token(
2219     const codes_ty   type_code,
2220     BOOLEAN        * scase,
2221     BOOLEAN        * force_nl,
2222     BOOLEAN        * sp_sw,
2223     BOOLEAN        * flushed_nl,
2224     codes_ty       * hd_type,
2225     int            * dec_ind,
2226     BOOLEAN        * last_token_ends_sp,
2227     exit_values_ty * file_exit_value,
2228     const bb_code_ty can_break,
2229     BOOLEAN        * last_else,
2230     BOOLEAN          is_procname_definition,
2231     BOOLEAN        * pbreak_line)
2232 {
2233     switch (type_code)
2234     {
2235     case form_feed:     /* found a form feed in line */
2236        handle_token_form_feed(pbreak_line);
2237        break;
2238 
2239     case newline:
2240        handle_token_newline(force_nl, pbreak_line);
2241        break;
2242 
2243     case lparen:
2244        handle_token_lparen(force_nl, sp_sw, dec_ind, pbreak_line);
2245        break;
2246 
2247     case rparen:
2248        handle_token_rparen(force_nl, sp_sw, hd_type, last_token_ends_sp,
2249                            file_exit_value, pbreak_line);
2250        break;
2251 
2252     case unary_op:
2253       /* this could be any unary operation */
2254        handle_token_unary_op( dec_ind, can_break);
2255        break;
2256 
2257     case binary_op:
2258       /* any binary operation */
2259        handle_token_binary_op(can_break);
2260        break;
2261 
2262     case postop:
2263       /* got a trailing ++ or -- */
2264        handle_token_postop();
2265        break;
2266 
2267     case question:
2268       /* got a ? */
2269        handle_token_question(can_break);
2270        break;
2271 
2272     case casestmt:
2273       /* got word 'case' or 'default' */
2274        handle_token_casestmt(scase, file_exit_value);
2275        copy_id(type_code, force_nl, file_exit_value,
2276                can_break);
2277        break;
2278 
2279     case colon:
2280       /* got a ':' */
2281        handle_token_colon(scase, force_nl, dec_ind, can_break,
2282                           pbreak_line);
2283        break;
2284 
2285     case doublecolon:
2286       /* Deal with C++ Class::Method */
2287        handle_token_doublecolon();
2288        break;
2289 
2290     case semicolon:
2291       /* we are not in an initialization or structure declaration */
2292        handle_token_semicolon(scase, force_nl, sp_sw, dec_ind,
2293                               last_token_ends_sp, file_exit_value);
2294        break;
2295 
2296     case lbrace:
2297       /* got a '{' */
2298        handle_token_lbrace(force_nl, dec_ind, file_exit_value,
2299                            pbreak_line);
2300        break;
2301 
2302     case rbrace:
2303       /* got a '}' */
2304        handle_token_rbrace(force_nl, dec_ind, file_exit_value,
2305                            pbreak_line);
2306 
2307        break;
2308 
2309     case swstmt:
2310       /* got keyword "switch" */
2311        handle_token_swstmt(sp_sw, hd_type);
2312        copy_id(type_code, force_nl, file_exit_value, can_break);
2313        break;
2314 
2315     case sp_paren:
2316       /* token is if, while, for */
2317        handle_token_sp_paren(sp_sw,  hd_type);
2318        copy_id(type_code, force_nl, file_exit_value, can_break);
2319        break;
2320 
2321     case sp_else:
2322       /* got else */
2323     case sp_nparen:
2324       /* got do */
2325        handle_token_nparen(force_nl, file_exit_value, last_else,
2326                            pbreak_line);
2327        copy_id(type_code, force_nl, file_exit_value, can_break);
2328        break;
2329 
2330     case overloaded:
2331       /* Handle C++ operator overloading like:
2332        *
2333        * Class foo::operator = ()"
2334        *
2335        * This is just like a decl, but we need to remember this
2336        * token type. */
2337 
2338        handle_token_overloaded(can_break);
2339        break;
2340 
2341     case decl:
2342       /* we have a declaration type (int, register, etc.) */
2343 
2344        handle_token_decl(dec_ind, file_exit_value,
2345                          pbreak_line);
2346 
2347        copy_id(type_code, force_nl, file_exit_value, can_break);
2348        break;
2349 
2350     case cpp_operator:
2351       /* Handle C++ operator overloading.  See case overloaded above. */
2352     case ident:
2353       /* got an identifier or constant */
2354        handle_token_ident(force_nl,  sp_sw, hd_type,
2355                           dec_ind, file_exit_value,
2356                           can_break, is_procname_definition,
2357                           pbreak_line);
2358 
2359        copy_id(type_code, force_nl, file_exit_value, can_break);
2360 
2361        break;
2362 
2363     case struct_delim:
2364        handle_token_struct_delim();
2365        break;
2366 
2367     case comma:
2368        handle_token_comma(force_nl, dec_ind,
2369                           is_procname_definition);
2370        break;
2371 
2372     case preesc:
2373       /* got the character '#' */
2374        handle_token_preesc(file_exit_value,
2375                            pbreak_line);
2376        break;
2377 
2378     case comment:
2379     case cplus_comment:
2380       /* A C or C++ comment. */
2381        handle_token_comment(force_nl, flushed_nl,
2382                             pbreak_line);
2383        break;
2384 
2385       /* An __attribute__ qualifier */
2386     case attribute:
2387        handle_token_attribute();
2388        break;
2389 
2390     default:
2391        abort ();
2392     }                       /* end of big switch stmt */
2393 }
2394 
2395 
2396 
2397 
2398