home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 4 / DATAFILE_PDCD4.iso / utilities / utilsf / indent / Source / c / io < prev    next >
Encoding:
Text File  |  1995-10-27  |  15.3 KB  |  625 lines

  1. /*
  2.  * Copyright 1989 Object Design, Inc.
  3.  * Copyright (c) 1985 Sun Microsystems, Inc.
  4.  * Copyright (c) 1980 The Regents of the University of California.
  5.  * Copyright (c) 1976 Board of Trustees of the University of Illinois.
  6.  * All rights reserved.
  7.  *
  8.  * Redistribution and use in source and binary forms are permitted
  9.  * provided that the above copyright notice and this paragraph are
  10.  * duplicated in all such forms and that any documentation,
  11.  * advertising materials, and other materials related to such
  12.  * distribution and use acknowledge that the software was developed
  13.  * by the University of California, Berkeley, the University of Illinois,
  14.  * Urbana, and Sun Microsystems, Inc.  The name of either University
  15.  * or Sun Microsystems may not be used to endorse or promote products
  16.  * derived from this software without specific prior written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  19.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  */
  21.  
  22. /* Archimedes port by Steven Flintham
  23.    Wednesday 25th October 1995
  24.    Friday 27th October 1995 */
  25.  
  26. #ifndef lint
  27. static char sccsid[] = "@(#)io.c    5.10 (Berkeley) 9/15/88";
  28. #endif /* not lint */
  29.  
  30. #ifndef __riscos /* SF */
  31. #include "indent_globs.h"
  32. #else
  33. #include "indntglobs.h"
  34. #endif /* __riscos */
  35. #include <ctype.h>
  36.  
  37.  
  38. int         comment_open;
  39. static      paren_target;
  40.  
  41. dump_line()
  42. {                /* dump_line is the routine that actually
  43.                  * effects the printing of the new source. It
  44.                  * prints the label section, followed by the
  45.                  * code section with the appropriate nesting
  46.                  * level, followed by any comments */
  47.     register int cur_col,
  48.                 target_col;
  49.     static      not_first_line;
  50.  
  51.     if (ps.procname[0]) {
  52.     if (troff) {
  53.         if (comment_open) {
  54.         comment_open = 0;
  55.         fprintf(output, ".*/\n");
  56.         }
  57.         fprintf(output, ".Pr \"%s\"\n", ps.procname);
  58.     }
  59.     ps.ind_level = 0;
  60.     ps.procname[0] = 0;
  61.     }
  62.     if (s_code == e_code && s_lab == e_lab && s_com == e_com) {
  63.     if (suppress_blanklines > 0)
  64.         suppress_blanklines--;
  65.     else {
  66.         ps.bl_line = true;
  67.         n_real_blanklines++;
  68.     }
  69.     }
  70.     else if (!inhibit_formatting) {
  71.     suppress_blanklines = 0;
  72.     ps.bl_line = false;
  73.     if (prefix_blankline_requested && not_first_line)
  74.         if (swallow_optional_blanklines) {
  75.         if (n_real_blanklines == 1)
  76.             n_real_blanklines = 0;
  77.         }
  78.         else {
  79.         if (n_real_blanklines == 0)
  80.             n_real_blanklines = 1;
  81.         }
  82.     while (--n_real_blanklines >= 0)
  83.         putc('\n', output);
  84.     n_real_blanklines = 0;
  85.     if (ps.ind_level == 0) {
  86.         if (!btype_3)
  87.         ps.ind_stmt = 0;    /* this is a class A kludge. dont do
  88.                      * additional statement indentation
  89.                      * if we are at bracket level 0 */
  90.         else
  91.         if (*s_code != '{')
  92.             ps.ind_stmt = 0;    /* this one is a class AA kludge:
  93.                      * defeat the class A kludge if
  94.                      * the statement is '{' */
  95.     }
  96.  
  97.     if (e_lab != s_lab || e_code != s_code)
  98.         ++code_lines;    /* keep count of lines with code */
  99.  
  100.  
  101.     if (e_lab != s_lab) {    /* print lab, if any */
  102.         if (comment_open) {
  103.         comment_open = 0;
  104.         fprintf(output, ".*/\n");
  105.         }
  106.         while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
  107.         e_lab--;
  108.         cur_col = pad_output(1, compute_label_target());
  109.         fprintf(output, "%.*s", e_lab - s_lab, s_lab);
  110.         cur_col = count_spaces(cur_col, s_lab);
  111.     }
  112.     else
  113.         cur_col = 1;    /* there is no label section */
  114.  
  115.     ps.pcase = false;
  116.  
  117.     if (s_code != e_code) {    /* print code section, if any */
  118.         register char *p;
  119.  
  120.         if (comment_open) {
  121.         comment_open = 0;
  122.         fprintf(output, ".*/\n");
  123.         }
  124.         target_col = compute_code_target();
  125.         {
  126.         register    i;
  127.  
  128.         for (i = 0; i < ps.p_l_follow; i++)
  129.             if (ps.paren_indents[i] >= 0)
  130.             ps.paren_indents[i] = -(ps.paren_indents[i] + target_col);
  131.         }
  132.         cur_col = pad_output(cur_col, target_col);
  133.         for (p = s_code; p < e_code; p++)
  134.         if (*p == (char) 0200)
  135.             fprintf(output, "%d", target_col * 7);
  136.         else
  137.             putc(*p, output);
  138.         cur_col = count_spaces(cur_col, s_code);
  139.     }
  140.     if (s_com != e_com)
  141.         if (troff) {
  142.         int         all_here = 0;
  143.         register char *p;
  144.  
  145.         if (ps.cc_comment)
  146.             all_here++;
  147.         else if (e_com[-1] == '/' && e_com[-2] == '*')
  148.             e_com -= 2, all_here++;
  149.         while (e_com > s_com && e_com[-1] == ' ')
  150.             e_com--;
  151.         *e_com = 0;
  152.         p = s_com;
  153.         while (*p == ' ')
  154.             p++;
  155.         if (p[0] == '/' && (p[1] == '*' || p[1] == '/'))
  156.             p += 2, all_here++;
  157.         else if (p[0] == '*')
  158.             p += p[1] == '/' ? 2 : 1;
  159.         while (*p == ' ')
  160.             p++;
  161.         if (*p == 0)
  162.             goto inhibit_newline;
  163.         if (comment_open < 2 && ps.box_com) {
  164.             comment_open = 0;
  165.             fprintf(output, ".*/\n");
  166.         }
  167.         if (comment_open == 0) {
  168.             if ('a' <= *p && *p <= 'z')
  169.             *p = *p + 'A' - 'a';
  170.             if (e_com - p < 50 && all_here == 2) {
  171.             register char *follow = p;
  172.             fprintf(output, "\n.nr C! \\w\1");
  173.             while (follow < e_com) {
  174.                 switch (*follow) {
  175.                 case '\n':
  176.                 putc(' ', output);
  177.                 case 1:
  178.                 break;
  179.                 case '\\':
  180.                 putc('\\', output);
  181.                 default:
  182.                 putc(*follow, output);
  183.                 }
  184.                 follow++;
  185.             }
  186.             putc(1, output);
  187.             }
  188.             fprintf(output, "\n./* %dp %d %dp\n",
  189.                 ps.com_col * 7,
  190.                 (s_code != e_code || s_lab != e_lab) - ps.box_com,
  191.                 target_col * 7);
  192.         }
  193.         comment_open = 1 + ps.box_com;
  194.         while (*p) {
  195.             if (*p == BACKSLASH)
  196.             putc(BACKSLASH, output);
  197.             putc(*p++, output);
  198.         }
  199.         }
  200.         else {        /* print comment, if any */
  201.         register    target = ps.com_col;
  202.         register char *com_st = s_com;
  203.  
  204.         target += ps.comment_delta;
  205.         while (*com_st == '\t')
  206.             com_st++, target += 8;    /* ? */
  207.         while (target <= 0)
  208.             if (*com_st == ' ')
  209.             target++, com_st++;
  210.             else if (*com_st == '\t')
  211.             target = ((target - 1) & ~7) + 9, com_st++;
  212.             else
  213.             target = 1;
  214.         if (cur_col > target) {    /* if comment cant fit on this line,
  215.                      * put it on next line */
  216.             putc('\n', output);
  217.             cur_col = 1;
  218.             ++ps.out_lines;
  219.         }
  220.         while (e_com > com_st && isspace(e_com[-1]))
  221.             e_com--;
  222.         cur_col = pad_output(cur_col, target);
  223.         if (!ps.box_com && !ps.cc_comment) {
  224.             if (star_comment_cont && (com_st[1] != '*' || e_com <= com_st + 1))
  225.             if (com_st[1] == ' ' && com_st[0] == ' ' && e_com > com_st + 1)
  226.                 com_st[1] = '*';
  227.             else
  228.                 fwrite(" * ", com_st[0] == '\t' ? 2 : com_st[0] == '*' ? 1 : 3, 1, output);
  229.         }
  230.         fwrite(com_st, e_com - com_st, 1, output);
  231.         ps.comment_delta = ps.n_comment_delta;
  232.         cur_col = count_spaces(cur_col, com_st);
  233.         ++ps.com_lines;    /* count lines with comments */
  234.         }
  235.     if (ps.use_ff)
  236.         putc('\014', output);
  237.     else
  238.         putc('\n', output);
  239. inhibit_newline:
  240.     ++ps.out_lines;
  241.     if (ps.just_saw_decl == 1 && blanklines_after_declarations) {
  242.         prefix_blankline_requested = 1;
  243.         ps.just_saw_decl = 0;
  244.     }
  245.     else
  246.         prefix_blankline_requested = postfix_blankline_requested;
  247.     postfix_blankline_requested = 0;
  248.     }
  249.     ps.decl_on_line = ps.in_decl;    /* if we are in the middle of a
  250.                      * declaration, remember that fact for
  251.                      * proper comment indentation */
  252.     ps.ind_stmt = ps.in_stmt & ~ps.in_decl;    /* next line should be
  253.                          * indented if we have not
  254.                          * completed this stmt and if
  255.                          * we are not in the middle of
  256.                          * a declaration */
  257.     ps.use_ff = false;
  258.     ps.dumped_decl_indent = 0;
  259.     *(e_lab = s_lab) = '\0';    /* reset buffers */
  260.     *(e_code = s_code) = '\0';
  261.     *(e_com = s_com) = '\0';
  262.     ps.ind_level = ps.i_l_follow;
  263.     ps.paren_level = ps.p_l_follow;
  264.     paren_target = -ps.paren_indents[ps.paren_level - 1];
  265.     not_first_line = 1;
  266.     return;
  267. };
  268.  
  269. compute_code_target()
  270. {
  271.     register    target_col = ps.ind_size * ps.ind_level + 1;
  272.  
  273.     if (ps.paren_level)
  274.     if (!lineup_to_parens)
  275.         target_col += continuation_indent * ps.paren_level;
  276.     else {
  277.         register    w;
  278.         register    t = paren_target;
  279.  
  280.         if ((w = count_spaces(t, s_code) - max_col) > 0
  281.             && count_spaces(target_col, s_code) <= max_col) {
  282.         t -= w + 1;
  283.         if (t > target_col)
  284.             target_col = t;
  285.         }
  286.         else
  287.         target_col = t;
  288.     }
  289.     else if (ps.ind_stmt)
  290.     target_col += continuation_indent;
  291.     return target_col;
  292. }
  293.  
  294. compute_label_target()
  295. {
  296.     return
  297.     ps.pcase ?
  298.         (cplus && ps.in_decl) ? cplus_ppp_indent
  299.     : (int) (case_ind * ps.ind_size) + 1
  300.     : *s_lab == '#' ? 1
  301.     : ps.ind_size * (ps.ind_level - label_offset) + 1;
  302. }
  303.  
  304.  
  305. /*
  306.  * Copyright (C) 1976 by the Board of Trustees of the University of Illinois
  307.  *
  308.  * All rights reserved
  309.  *
  310.  *
  311.  * NAME: fill_buffer
  312.  *
  313.  * FUNCTION: Reads one block of input into input_buffer
  314.  *
  315.  * HISTORY: initial coding     November 1976    D A Willcox of CAC 1/7/77 A
  316.  * Willcox of CAC    Added check for switch back to partly full input
  317.  * buffer from temporary buffer
  318.  *
  319.  */
  320. int
  321. fill_buffer()
  322. {                /* this routine reads stuff from the input */
  323.     register char *p;
  324.     register int i;
  325.     register FILE *f = input;
  326.  
  327.     if (bp_save != 0) {        /* there is a partly filled input buffer left */
  328.     buf_ptr = bp_save;    /* dont read anything, just switch buffers */
  329.     buf_end = be_save;
  330.     bp_save = be_save = 0;
  331.     if (buf_ptr < buf_end)
  332.         return;        /* only return if there is really something in
  333.                  * this buffer */
  334.     }
  335.     for (p = buf_ptr = in_buffer;;) {
  336.     if ((i = getc(f)) == EOF) {
  337.         *p++ = ' ';
  338.         *p++ = '\n';
  339.         had_eof = true;
  340.         break;
  341.     }
  342.     *p++ = i;
  343.     if (i == '\n')
  344.         break;
  345.     }
  346.     buf_end = p;
  347.     if (p[-2] == '/' && p[-3] == '*') {
  348.     if (in_buffer[3] == 'I' && strncmp(in_buffer, "/**INDENT**", 11) == 0)
  349.         fill_buffer();    /* flush indent error message */
  350.     else {
  351.         int         com = 0;
  352.  
  353.         p = in_buffer;
  354.         while (*p == ' ' || *p == '\t')
  355.         p++;
  356.         if (*p == '/' && p[1] == '*') {
  357.         p += 2;
  358.         while (*p == ' ' || *p == '\t')
  359.             p++;
  360.         if (p[0] == 'I' && p[1] == 'N' && p[2] == 'D' && p[3] == 'E'
  361.             && p[4] == 'N' && p[5] == 'T') {
  362.             p += 6;
  363.             if(*p == ':') {
  364. #define MAX_SOURCE_ARG 100
  365.             char argbuf[MAX_SOURCE_ARG]; /* how big can they get ...  */
  366.             char * a;
  367.             p++;    /* skip the : */
  368.             /* since set_option changes flags, process pending stuff now */
  369.             if (s_com != e_com || s_lab != e_lab || s_code != e_code)
  370.                 dump_line();
  371.             while (1) {
  372.                 a = argbuf;    /* accumulate an option */
  373.                 while (*p <= ' ') /* skip whitespace */
  374.                 p++;
  375.                 if(*p == '*') break;
  376.                 while (*p > ' ')
  377.                 *a++ = *p++;
  378.                 *a++ = '\0';
  379.                 set_option(argbuf);
  380.             }
  381.             goto End_Magic_Comment;
  382.             }
  383.             while (*p == ' ' || *p == '\t')
  384.             p++;
  385.             if (*p == '*')
  386.             com = 1;
  387.             else if (*p == 'O')
  388.             if (*++p == 'N')
  389.                 p++, com = 1;
  390.             else if (*p == 'F' && *++p == 'F')
  391.                 p++, com = 2;
  392.             while (*p == ' ' || *p == '\t')
  393.             p++;
  394.             if (p[0] == '*' && p[1] == '/' && p[2] == '\n' && com) {
  395.             if (s_com != e_com || s_lab != e_lab || s_code != e_code)
  396.                 dump_line();
  397.             if (!(inhibit_formatting = com - 1)) {
  398.                 n_real_blanklines = 0;
  399.                 postfix_blankline_requested = 0;
  400.                 prefix_blankline_requested = 0;
  401.                 suppress_blanklines = 1;
  402.             }
  403.             }
  404.         }
  405.         }
  406.     }
  407.     }
  408. End_Magic_Comment:
  409.     if (inhibit_formatting) {
  410.     p = in_buffer;
  411.     do
  412.         putc(*p, output);
  413.     while (*p++ != '\n');
  414.     }
  415.     return;
  416. };
  417.  
  418. /*
  419.  * Copyright (C) 1976 by the Board of Trustees of the University of Illinois
  420.  *
  421.  * All rights reserved
  422.  *
  423.  *
  424.  * NAME: pad_output
  425.  *
  426.  * FUNCTION: Writes tabs and spaces to move the current column up to the desired
  427.  * position.
  428.  *
  429.  * ALGORITHM: Put tabs and/or blanks into pobuf, then write pobuf.
  430.  *
  431.  * PARAMETERS: current        integer        The current column target
  432.  * nteger        The desired column
  433.  *
  434.  * RETURNS: Integer value of the new column.  (If current >= target, no action is
  435.  * taken, and current is returned.
  436.  *
  437.  * GLOBALS: None
  438.  *
  439.  * CALLS: write (sys)
  440.  *
  441.  * CALLED BY: dump_line
  442.  *
  443.  * HISTORY: initial coding     November 1976    D A Willcox of CAC
  444.  *
  445.  */
  446. pad_output(current, target)    /* writes tabs and blanks (if necessary) to
  447.                  * get the current output position up to the
  448.                  * target column */
  449.     int         current;    /* the current column value */
  450.     int         target;        /* position we want it at */
  451. {
  452.     register int curr;        /* internal column pointer */
  453.     register int tcur;
  454.  
  455.     if (troff)
  456.     fprintf(output, "\\h'|%dp'", (target - 1) * 7);
  457.     else {
  458.     if (current >= target)
  459.         return (current);    /* line is already long enough */
  460.     curr = current;
  461.     while ((tcur = ((curr - 1) & tabmask) + tabsize + 1) <= target) {
  462.         putc('\t', output);
  463.         curr = tcur;
  464.     }
  465.     while (curr++ < target)
  466.         putc(' ', output);    /* pad with final blanks */
  467.     }
  468.     return (target);
  469. };
  470.  
  471. /*
  472.  * Copyright (C) 1976 by the Board of Trustees of the University of Illinois
  473.  *
  474.  * All rights reserved
  475.  *
  476.  *
  477.  * NAME: count_spaces
  478.  *
  479.  * FUNCTION: Find out where printing of a given string will leave the current
  480.  * character position on output.
  481.  *
  482.  * ALGORITHM: Run thru input string and add appropriate values to current
  483.  * position.
  484.  *
  485.  * RETURNS: Integer value of position after printing "buffer" starting in column
  486.  * "current".
  487.  *
  488.  * HISTORY: initial coding     November 1976    D A Willcox of CAC
  489.  *
  490.  */
  491. int
  492. count_spaces(current, buffer)
  493. /*
  494.  * this routine figures out where the character position will be after
  495.  * printing the text in buffer starting at column "current"
  496.  */
  497.     int         current;
  498.     char       *buffer;
  499. {
  500.     register char *buf;        /* used to look thru buffer */
  501.     register int cur;        /* current character counter */
  502.  
  503.     cur = current;
  504.  
  505.     for (buf = buffer; *buf != '\0'; ++buf) {
  506.     switch (*buf) {
  507.  
  508.     case '\n':
  509.     case 014:        /* form feed */
  510.         cur = 1;
  511.         break;
  512.  
  513.     case '\t':
  514.         cur = ((cur - 1) & tabmask) + tabsize + 1;
  515.         break;
  516.  
  517.     case '\b':        /* this is a backspace */
  518.         --cur;
  519.         break;
  520.  
  521.     default:
  522.         ++cur;
  523.         break;
  524.     }            /* end of switch */
  525.     }                /* end of for loop */
  526.     return (cur);
  527. };
  528.  
  529. int    found_err;
  530. diag(level, msg, a, b)
  531. {
  532.     if (level)
  533.     found_err = 1;
  534.     if (output == stdout) {
  535.     fprintf(stdout, "/**INDENT** %s@%d: ", level == 0 ? "Warning" : "Error", line_no);
  536.     fprintf(stdout, msg, a, b);
  537.     fprintf(stdout, " */\n");
  538.     }
  539.     else {
  540.     fprintf(stderr, "%s@%d: ", level == 0 ? "Warning" : "Error", line_no);
  541.     fprintf(stderr, msg, a, b);
  542.     fprintf(stderr, "\n");
  543.     }
  544. }
  545.  
  546. writefdef(f, nm)
  547.     register struct fstate *f;
  548. {
  549.     fprintf(output, ".ds f%c %s\n.nr s%c %d\n",
  550.         nm, f->font, nm, f->size);
  551. }
  552.  
  553. char       *
  554. chfont(of, nf, s)
  555.     register struct fstate *of,
  556.                *nf;
  557.     char       *s;
  558. {
  559.     if (of->font[0] != nf->font[0]
  560.         || of->font[1] != nf->font[1]) {
  561.     *s++ = '\\';
  562.     *s++ = 'f';
  563.     if (nf->font[1]) {
  564.         *s++ = '(';
  565.         *s++ = nf->font[0];
  566.         *s++ = nf->font[1];
  567.     }
  568.     else
  569.         *s++ = nf->font[0];
  570.     }
  571.     if (nf->size != of->size) {
  572.     *s++ = '\\';
  573.     *s++ = 's';
  574.     if (nf->size < of->size) {
  575.         *s++ = '-';
  576.         *s++ = '0' + of->size - nf->size;
  577.     }
  578.     else {
  579.         *s++ = '+';
  580.         *s++ = '0' + nf->size - of->size;
  581.     }
  582.     }
  583.     return s;
  584. }
  585.  
  586.  
  587. parsefont(f, s0)
  588.     register struct fstate *f;
  589.     char       *s0;
  590. {
  591.     register char *s = s0;
  592.     int         sizedelta = 0;
  593.     bzero(f, sizeof *f);
  594.     while (*s) {
  595.     if (isdigit(*s))
  596.         f->size = f->size * 10 + *s - '0';
  597.     else if (isupper(*s))
  598.         if (f->font[0])
  599.         f->font[1] = *s;
  600.         else
  601.         f->font[0] = *s;
  602.     else if (*s == 'c')
  603.         f->allcaps = 1;
  604.     else if (*s == '+')
  605.         sizedelta++;
  606.     else if (*s == '-')
  607.         sizedelta--;
  608.     else {
  609.         fprintf(stderr, "indent: bad font specification: %s\n", s0);
  610.         exit(1);
  611.     }
  612.     s++;
  613.     }
  614.     if (f->font[0] == 0)
  615.     f->font[0] = 'R';
  616.     if (bodyf.size == 0)
  617.     bodyf.size = 11;
  618.     if (f->size == 0)
  619.     f->size = bodyf.size + sizedelta;
  620.     else if (sizedelta > 0)
  621.     f->size += bodyf.size;
  622.     else
  623.     f->size = bodyf.size - f->size;
  624. }
  625.