home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / program / d / indent / !Indent / c / comment < prev    next >
Encoding:
Text File  |  1991-02-20  |  12.6 KB  |  416 lines

  1. /*
  2.  * Copyright (c) 1985 Sun Microsystems, Inc.
  3.  * Copyright (c) 1980 The Regents of the University of California.
  4.  * Copyright (c) 1976 Board of Trustees of the University of Illinois.
  5.  * All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms are permitted
  8.  * provided that the above copyright notice and this paragraph are
  9.  * duplicated in all such forms and that any documentation,
  10.  * advertising materials, and other materials related to such
  11.  * distribution and use acknowledge that the software was developed
  12.  * by the University of California, Berkeley, the University of Illinois,
  13.  * Urbana, and Sun Microsystems, Inc.  The name of either University
  14.  * or Sun Microsystems may not be used to endorse or promote products
  15.  * derived from this software without specific prior written permission.
  16.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  17.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  18.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19.  */
  20.  
  21. #ifndef lint
  22. static char sccsid[] = "@(#)pr_comment.c    5.9 (Berkeley) 9/15/88";
  23. #endif /* not lint */
  24.  
  25. /*
  26.  * NAME:
  27.  *    pr_comment
  28.  *
  29.  * FUNCTION:
  30.  *    This routine takes care of scanning and printing comments.
  31.  *
  32.  * ALGORITHM:
  33.  *    1) Decide where the comment should be aligned, and if lines should
  34.  *       be broken.
  35.  *    2) If lines should not be broken and filled, just copy up to end of
  36.  *       comment.
  37.  *    3) If lines should be filled, then scan thru input_buffer copying
  38.  *       characters to com_buf.  Remember where the last blank, tab, or
  39.  *       newline was.  When line is filled, print up to last blank and
  40.  *       continue copying.
  41.  *
  42.  * HISTORY:
  43.  *    November 1976    D A Willcox of CAC    Initial coding
  44.  *    12/6/76        D A Willcox of CAC    Modification to handle
  45.  *                        UNIX-style comments
  46.  *
  47.  */
  48.  
  49. /*
  50.  * this routine processes comments.  It makes an attempt to keep comments from
  51.  * going over the max line length.  If a line is too long, it moves everything
  52.  * from the last blank to the next comment line.  Blanks and tabs from the
  53.  * beginning of the input line are removed
  54.  */
  55.  
  56. #include <stdlib.h>
  57. #include "externs.h"
  58. #include "comment.h"
  59.  
  60.  
  61. void pr_comment()
  62. {
  63.     int         now_col;    /* column we are in now */
  64.     int         adj_max_col;    /* Adjusted max_col for when we decide to
  65.                  * spill comments over the right margin */
  66.     char       *last_bl;    /* points to the last blank in the output
  67.                  * buffer */
  68.     char       *t_ptr;        /* used for moving string */
  69.     int         unix_comment;    /* tri-state variable used to decide if it is
  70.                  * a unix-style comment. 0 means only blanks
  71.                  * since /*, 1 means regular style comment, 2
  72.                  * means unix style comment */
  73.     int         break_delim = comment_delimiter_on_blankline;
  74.     int         l_just_saw_decl = parser_state_tos->just_saw_decl;
  75.     /*
  76.      * int         parser_state_tos->last_nl = 0;    /* true iff the last significant thing
  77.      * weve seen is a newline
  78.      */
  79.     int         one_liner = 1;    /* true iff this comment is a one-liner */
  80.     adj_max_col = max_col;
  81.     parser_state_tos->just_saw_decl = 0;
  82.     last_bl = 0;        /* no blanks found so far */
  83.     parser_state_tos->box_com = false;        /* at first, assume that we are not in
  84.                      * a boxed comment or some other
  85.                      * comment that should not be touched */
  86.     ++parser_state_tos->out_coms;        /* keep track of number of comments */
  87.     unix_comment = 1;        /* set flag to let us figure out if there is a
  88.                  * unix-style comment ** DISABLED: use 0 to
  89.                  * reenable this hack! */
  90.  
  91.     /* Figure where to align and how to treat the comment */
  92.  
  93.     if (parser_state_tos->col_1 && !format_col1_comments) {    /* if comment starts in column
  94.                          * 1 it should not be touched */
  95.     parser_state_tos->box_com = true;
  96.     parser_state_tos->com_col = 1;
  97.     }
  98.     else {
  99.     if (*buf_ptr == '-' || *buf_ptr == '*' || !format_comments) {
  100.         parser_state_tos->box_com = true;    /* a comment with a '-' or '*' immediately
  101.                  * after the /* is assumed to be a boxed
  102.                  * comment */
  103.         break_delim = 0;
  104.     }
  105.     if ( /* parser_state_tos->bl_line && */ (s_lab == e_lab) && (s_code == e_code)) {
  106.         /* klg: check only if this line is blank */
  107.         /*
  108.          * If this (*and previous lines are*) blank, dont put comment way
  109.          * out at left
  110.          */
  111.         parser_state_tos->com_col = (parser_state_tos->ind_level - unindent_displace) + 1;
  112.         adj_max_col = block_comment_max_col;
  113.         if (parser_state_tos->com_col <= 1)
  114.         parser_state_tos->com_col = 1 + !format_col1_comments;
  115.     }
  116.     else {
  117.         register int target_col;
  118.         break_delim = 0;
  119.         if (s_code != e_code)
  120.         target_col = count_spaces(compute_code_target(), s_code);
  121.         else {
  122.         target_col = 1;
  123.         if (s_lab != e_lab)
  124.             target_col = count_spaces(compute_label_target(), s_lab);
  125.         }
  126.         parser_state_tos->com_col = parser_state_tos->decl_on_line || parser_state_tos->ind_level == 0 ? decl_com_ind : com_ind;
  127.         /* If we are already past the position for the comment,
  128.            put it at the next tab stop.  */
  129.         if (parser_state_tos->com_col < target_col)
  130.         parser_state_tos->com_col = ((target_col + 7) & ~7) + 1;
  131.         if (else_or_endif)
  132.           {
  133.         parser_state_tos->com_col = else_endif_col;
  134.         else_or_endif = false;
  135.         /* We want the comment to appear one space after the #else
  136.            or #endif.  */
  137.         if (parser_state_tos->com_col < target_col)
  138.           parser_state_tos->com_col = target_col + 1;
  139.           }
  140.         if (parser_state_tos->com_col + 24 > adj_max_col)
  141.         adj_max_col = parser_state_tos->com_col + 24;
  142.     }
  143.     }
  144.     if (parser_state_tos->box_com) {
  145.     buf_ptr[-2] = 0;
  146.     parser_state_tos->n_comment_delta = 1 - count_spaces(1, cur_line);
  147.     buf_ptr[-2] = '/';
  148.     }
  149.     else {
  150.     parser_state_tos->n_comment_delta = 0;
  151.     while (*buf_ptr == ' ' || *buf_ptr == '\t')
  152.         buf_ptr++;
  153.     }
  154.     parser_state_tos->comment_delta = 0;
  155.     *e_com++ = '/';        /* put '/*' into buffer */
  156.     *e_com++ = '*';
  157.     if (*buf_ptr != ' ' && !parser_state_tos->box_com)
  158.     *e_com++ = ' ';
  159.  
  160.     *e_com = '\0';
  161.     if (troff) {
  162.     now_col = 1;
  163.     adj_max_col = 80;
  164.     }
  165.     else
  166.     now_col = count_spaces(parser_state_tos->com_col, s_com);    /* figure what column we
  167.                              * would be in if we
  168.                              * printed the comment
  169.                              * now */
  170.  
  171.     /* Start to copy the comment */
  172.  
  173.     while (1) {            /* this loop will go until the comment is
  174.                  * copied */
  175.     if (*buf_ptr > 040 && *buf_ptr != '*')
  176.         parser_state_tos->last_nl = 0;
  177.     check_com_size;
  178.     switch (*buf_ptr) {    /* this checks for various spcl cases */
  179.     case 014:        /* check for a form feed */
  180.         if (!parser_state_tos->box_com) {    /* in a text comment, break the line here */
  181.         parser_state_tos->use_ff = true;
  182.         /* fix so dump_line uses a form feed */
  183.         dump_line();
  184.         last_bl = 0;
  185.         *e_com++ = ' ';
  186.         *e_com++ = '*';
  187.         *e_com++ = ' ';
  188.         while (*++buf_ptr == ' ' || *buf_ptr == '\t');
  189.         }
  190.         else {
  191.         if (++buf_ptr >= buf_end)
  192.             fill_buffer();
  193.         *e_com++ = 014;
  194.         }
  195.         break;
  196.  
  197.     case '\n':
  198.         if (had_eof) {    /* check for unexpected eof */
  199.         printf("Unterminated comment\n");
  200.         *e_com = '\0';
  201.         dump_line();
  202.         return;
  203.         }
  204.         one_liner = 0;
  205.         if (parser_state_tos->box_com || parser_state_tos->last_nl) {    /* if this is a boxed comment,
  206.                          * we dont ignore the newline */
  207.         if (s_com == e_com) {
  208.             *e_com++ = ' ';
  209.             *e_com++ = ' ';
  210.         }
  211.         *e_com = '\0';
  212.         if (!parser_state_tos->box_com && e_com - s_com > 3) {
  213.             if (break_delim == 1 && s_com[0] == '/'
  214.                 && s_com[1] == '*' && s_com[2] == ' ') {
  215.             char       *t = e_com;
  216.             break_delim = 2;
  217.             e_com = s_com + 2;
  218.             *e_com = 0;
  219.             if (blanklines_before_blockcomments)
  220.                 prefix_blankline_requested = 1;
  221.             dump_line();
  222.             e_com = t;
  223.             s_com[0] = s_com[1] = s_com[2] = ' ';
  224.             }
  225.             dump_line();
  226.             check_com_size;
  227.             *e_com++ = ' ';
  228.             *e_com++ = ' ';
  229.         }
  230.         dump_line();
  231.         now_col = parser_state_tos->com_col;
  232.         }
  233.         else {
  234.         parser_state_tos->last_nl = 1;
  235.         if (unix_comment != 1) {    /* we not are in unix_style
  236.                          * comment */
  237.             if (unix_comment == 0 && s_code == e_code) {
  238.             /*
  239.              * if it is a UNIX-style comment, ignore the
  240.              * requirement that previous line be blank for
  241.              * unindention
  242.              */
  243.             parser_state_tos->com_col = ((parser_state_tos->ind_level - unindent_displace)
  244.                       + ind_size);
  245.             if (parser_state_tos->com_col <= 1)
  246.                 parser_state_tos->com_col = 2;
  247.             }
  248.             unix_comment = 2;    /* permanently remember that we are in
  249.                      * this type of comment */
  250.             dump_line();
  251.             ++line_no;
  252.             now_col = parser_state_tos->com_col;
  253.             *e_com++ = ' ';
  254.             /*
  255.              * fix so that the star at the start of the line will line
  256.              * up
  257.              */
  258.             do        /* flush leading white space */
  259.             if (++buf_ptr >= buf_end)
  260.                 fill_buffer();
  261.             while (*buf_ptr == ' ' || *buf_ptr == '\t');
  262.             break;
  263.         }
  264.         if (*(e_com - 1) == ' ' || *(e_com - 1) == '\t')
  265.             last_bl = e_com - 1;
  266.         /*
  267.          * if there was a space at the end of the last line, remember
  268.          * where it was
  269.          */
  270.         else {        /* otherwise, insert one */
  271.             last_bl = e_com;
  272.             check_com_size;
  273.             *e_com++ = ' ';
  274.             ++now_col;
  275.         }
  276.         }
  277.         ++line_no;        /* keep track of input line number */
  278.         if (!parser_state_tos->box_com) {
  279.         int         nstar = 1;
  280.         do {        /* flush any blanks and/or tabs at start of
  281.                  * next line */
  282.             if (++buf_ptr >= buf_end)
  283.             fill_buffer();
  284.             if (*buf_ptr == '*' && --nstar >= 0) {
  285.             if (++buf_ptr >= buf_end)
  286.                 fill_buffer();
  287.             if (*buf_ptr == '/')
  288.                 goto end_of_comment;
  289.             }
  290.         } while (*buf_ptr == ' ' || *buf_ptr == '\t');
  291.         }
  292.         else if (++buf_ptr >= buf_end)
  293.         fill_buffer();
  294.         break;        /* end of case for newline */
  295.  
  296.     case '*':        /* must check for possibility of being at end
  297.                  * of comment */
  298.         if (++buf_ptr >= buf_end)    /* get to next char after * */
  299.         fill_buffer();
  300.  
  301.         if (unix_comment == 0)    /* set flag to show we are not in
  302.                      * unix-style comment */
  303.         unix_comment = 1;
  304.  
  305.         if (*buf_ptr == '/') {    /* it is the end!!! */
  306.     end_of_comment:
  307.         if (++buf_ptr >= buf_end)
  308.             fill_buffer();
  309.  
  310.         if (*(e_com - 1) != ' ' && !parser_state_tos->box_com) {    /* insure blank before
  311.                                  * end */
  312.             *e_com++ = ' ';
  313.             ++now_col;
  314.         }
  315.         if (break_delim == 1 && !one_liner && s_com[0] == '/'
  316.             && s_com[1] == '*' && s_com[2] == ' ') {
  317.             char       *t = e_com;
  318.             break_delim = 2;
  319.             e_com = s_com + 2;
  320.             *e_com = 0;
  321.             if (blanklines_before_blockcomments)
  322.             prefix_blankline_requested = 1;
  323.             dump_line();
  324.             e_com = t;
  325.             s_com[0] = s_com[1] = s_com[2] = ' ';
  326.         }
  327.         if (break_delim == 2 && e_com > s_com + 3
  328.              /* now_col > adj_max_col - 2 && !parser_state_tos->box_com */ ) {
  329.             *e_com = '\0';
  330.             dump_line();
  331.             now_col = parser_state_tos->com_col;
  332.         }
  333.         check_com_size;
  334.         *e_com++ = '*';
  335.         *e_com++ = '/';
  336.         *e_com = '\0';
  337.         parser_state_tos->just_saw_decl = l_just_saw_decl;
  338.         return;
  339.         }
  340.         else {        /* handle isolated '*' */
  341.         *e_com++ = '*';
  342.         ++now_col;
  343.         }
  344.         break;
  345.     default:        /* we have a random char */
  346.         if (unix_comment == 0 && *buf_ptr != ' ' && *buf_ptr != '\t')
  347.         unix_comment = 1;    /* we are not in unix-style comment */
  348.  
  349.         *e_com = *buf_ptr++;
  350.         if (buf_ptr >= buf_end)
  351.         fill_buffer();
  352.  
  353.         if (*e_com == '\t')    /* keep track of column */
  354.         now_col = ((now_col - 1) & tabmask) + tabsize + 1;
  355.         else if (*e_com == '\b')    /* this is a backspace */
  356.         --now_col;
  357.         else
  358.         ++now_col;
  359.  
  360.         if (*e_com == ' ' || *e_com == '\t')
  361.         last_bl = e_com;
  362.         /* remember we saw a blank */
  363.  
  364.         ++e_com;
  365.         if (now_col > adj_max_col && !parser_state_tos->box_com && unix_comment == 1 && e_com[-1] > ' ') {
  366.         /*
  367.          * the comment is too long, it must be broken up
  368.          */
  369.         if (break_delim == 1 && s_com[0] == '/'
  370.             && s_com[1] == '*' && s_com[2] == ' ') {
  371.             char       *t = e_com;
  372.             break_delim = 2;
  373.             e_com = s_com + 2;
  374.             *e_com = 0;
  375.             if (blanklines_before_blockcomments)
  376.             prefix_blankline_requested = 1;
  377.             dump_line();
  378.             e_com = t;
  379.             s_com[0] = s_com[1] = s_com[2] = ' ';
  380.         }
  381.         if (last_bl == 0) {    /* we have seen no blanks */
  382.             last_bl = e_com;    /* fake it */
  383.             *e_com++ = ' ';
  384.         }
  385.         *e_com = '\0';    /* print what we have */
  386.         *last_bl = '\0';
  387.         while (last_bl > s_com && last_bl[-1] < 040)
  388.             *--last_bl = 0;
  389.         e_com = last_bl;
  390.         dump_line();
  391.  
  392.         *e_com++ = ' ';    /* add blanks for continuation */
  393.         *e_com++ = ' ';
  394.         *e_com++ = ' ';
  395.  
  396.         t_ptr = last_bl + 1;
  397.         last_bl = 0;
  398.         if (t_ptr >= e_com) {
  399.             while (*t_ptr == ' ' || *t_ptr == '\t')
  400.             t_ptr++;
  401.             while (*t_ptr != '\0') {    /* move unprinted part of
  402.                          * comment down in buffer */
  403.             if (*t_ptr == ' ' || *t_ptr == '\t')
  404.                 last_bl = e_com;
  405.             *e_com++ = *t_ptr++;
  406.             }
  407.         }
  408.         *e_com = '\0';
  409.         now_col = count_spaces(parser_state_tos->com_col, s_com);    /* recompute current
  410.                                  * position */
  411.         }
  412.         break;
  413.     }
  414.     }
  415. }
  416.