home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpm / cpm68k / utils.lbr / IO.CQ / IO.C
Encoding:
Text File  |  1986-05-22  |  11.8 KB  |  567 lines

  1. #
  2. /*
  3.  
  4.               Copyright (C) 1976
  5.                 by the
  6.               Board of Trustees
  7.                 of the
  8.             University of Illinois
  9.  
  10.              All rights reserved
  11.  
  12.  
  13. FILE NAME:
  14.     io.c
  15.  
  16. PURPOSE:
  17.     Contains routines to handle i/o related stuff for indent.
  18.  
  19. GLOBALS:
  20.     None
  21.  
  22. FUNCTIONS:
  23.     dump_line
  24.     fill_buffer
  25.     pad_output
  26.     count_spaces
  27.     eqin
  28.     cmp
  29.  
  30. */
  31. /*
  32.  
  33.               Copyright (C) 1976
  34.                 by the
  35.               Board of Trustees
  36.                 of the
  37.             University of Illinois
  38.  
  39.              All rights reserved
  40.  
  41.  
  42. NAME:
  43.     dump_line
  44.  
  45. FUNCTION:
  46.     Does the actual printing of the stored up line
  47.  
  48. ALGORITHM:
  49.     For each of the label, code, and comment sections which are used on 
  50.     this line:
  51.  
  52.     1) Use pad_output to get the section aligned properly.
  53.     2) write the section
  54.  
  55.     The indentation level used for the code is set by ind_level.  After
  56.     printing, ind_level is set to i_l_follow.
  57.  
  58.     An extra level of indentation is added if ind_stmt is 1.  After 
  59.     printing, ind_stmt is set to 1 iff the line just printed has an
  60.     unterminated, non-declaration statement.
  61.  
  62. PARAMETERS:
  63.     None
  64.  
  65. RETURNS:
  66.     Nothing
  67.  
  68. GLOBALS:
  69.     labbuf
  70.     s_lab
  71.     e_lab =        Reset to s_lab
  72.  
  73.     codebuf
  74.     s_code
  75.     e_code =    Reset to s_code
  76.  
  77.     combuf
  78.     s_com
  79.     e_com =        Reset to s_com
  80.  
  81.     bl_line =    Set to true iff the line was blank
  82.     case_ind
  83.     code_lines =    Count lines with code
  84.     com_col
  85.     com_lines =    Keep track of lines with comments
  86.     decl_on_line =    Set to in_decl after line is printed
  87.     i_l_follow
  88.     in_decl
  89.     in_stmt
  90.     ind_level =    Set to i_l_follow at completion
  91.     ind_size
  92.     ind_stmt =    Set to in_stmt at completion if not in declaration
  93.     out_lines =    Count output lines
  94.     p_l_follow
  95.     paren_level =    Set to p_l_follow at completion
  96.     pcase
  97.     use_ff =    Reset to false
  98.  
  99. CALLS:
  100.     pad_output
  101.     printf (lib)
  102.     write (lib)
  103.  
  104. CALLED BY:
  105.     main
  106.     pr_comment
  107.  
  108. HISTORY:
  109.     initial coding     November 1976    D A Willcox of CAC
  110.  
  111. */
  112. #include "indntglo.h";
  113.  
  114.  
  115.  
  116. int     ff = 014;           /* used to write a form feed */
  117.  
  118.  
  119. dump_line () {               /* dump_line is the routine that actually
  120.                       effects the printing of the new source.
  121.                       It prints the label section, followed by
  122.                       the code section with the appropriate
  123.                       nesting level, followed by any comments 
  124.                    */
  125.     register int    cur_col,
  126.                     temp_col,
  127.                     target_col;
  128.  
  129.     bl_line = true;           /* if we don't find otherwise, assume a
  130.                       blank line */
  131.  
  132.     if (ind_level == 0)
  133.     ind_stmt = 0;           /* this is a class A kludge. don't do
  134.                       additional statement indentation if we
  135.                       are at bracket level 0 */
  136.  
  137.     if (e_lab != s_lab || e_code != s_code)
  138.     ++code_lines;           /* keep count of lines with code */
  139.  
  140.     if (e_lab != s_lab) {      /* print lab, if any */
  141.     if (pcase)           /* if the label is really a case, we must
  142.                       indent */
  143.         cur_col = pad_output (1, case_ind * ind_size + 1);
  144.     else {
  145.         if (*s_lab == '#') /* check for #define, etc */
  146.         cur_col = 1;
  147.         else
  148.         cur_col = pad_output (1, ind_size * (ind_level - label_offset) + 1);
  149.     }
  150.  
  151.     write (output, s_lab, (short int) (e_lab - s_lab));
  152.     cur_col = count_spaces (cur_col, s_lab);
  153.     /* count_spaces gives number of characters, considering tabs */
  154.     bl_line = false;       /* line not blank after all */
  155.     }
  156.     else
  157.     cur_col = 1;           /* there is no label section */
  158.  
  159.     pcase = false;
  160.  
  161.     if (s_code != e_code) {    /* print code section, if any */
  162.     target_col = ind_size * (ind_level + paren_level + ind_stmt) + 1;
  163.  
  164.     cur_col = pad_output (cur_col, target_col);
  165.     /* pad_output writes enough tabs and spaces to get the current char
  166.        position up to target_col */
  167.     write (output, s_code, (short int) (e_code - s_code));
  168.     cur_col = count_spaces (cur_col, s_code);
  169.     bl_line = false;       /* line not blank */
  170.     }
  171.  
  172.     if ((cur_col - 1) > max_col && output!=1)/* check for line too long */
  173.     printf ("%d: Code has %d chars, max is %d\n", line_no, (cur_col - 1), max_col);
  174.  
  175.     if (s_com != e_com) {      /* print comment, if any */
  176.     if (cur_col > com_col && count_spaces (cur_col, s_com) >= max_col) {
  177.     /* if comment can't fit on this line, put it on next line */
  178.         write (output, "\n", 1);
  179.         cur_col = 1;
  180.         ++out_lines;
  181.     }
  182.     cur_col = pad_output (cur_col, com_col);
  183.     write (output, s_com, (short int) (e_com - s_com));
  184.  
  185.     cur_col = count_spaces (cur_col, s_com);
  186.     if ((cur_col - 1) > max_col && output!=1)/* check for too long comment */
  187.         printf ("%d: Comment goes to column %d.  Max is %d\n",
  188.         line_no, (cur_col - 1), max_col);
  189.  
  190.     bl_line = false;
  191.     ++com_lines;           /* count lines with comments */
  192.     }
  193.  
  194.     if (use_ff)
  195.     write (output, &ff, 1);/* end the output with a ff */
  196.     else
  197.     write (output, "\n", 1); /* or a newline */
  198.     use_ff = false;
  199.     *(e_lab = s_lab) = '\0';   /* reset buffers */
  200.     *(e_code = s_code) = '\0';
  201.     *(e_com = s_com) = '\0';
  202.  
  203.     ind_level = i_l_follow;
  204.     paren_level = p_l_follow;
  205.     ++out_lines;
  206.     decl_on_line = in_decl;    /* if we are in the middle of a
  207.                       declaration, remember that fact for
  208.                       proper comment indentation */
  209.     ind_stmt = in_stmt & ~in_decl;
  210.  /* next line should be indented if we have not completed this stmt and if
  211.     we are not in the middle of a declaration */
  212.  
  213.     return;
  214. };
  215. /*
  216.  
  217.               Copyright (C) 1976
  218.                 by the
  219.               Board of Trustees
  220.                 of the
  221.             University of Illinois
  222.  
  223.              All rights reserved
  224.  
  225.  
  226. NAME:
  227.     fill_buffer
  228.  
  229. FUNCTION:
  230.     Reads one block of input into input_buffer
  231.  
  232. ALGORITHM:
  233.     Trivial
  234.  
  235. PARAMETERS:
  236.     None
  237.  
  238. RETURNS:
  239.     Nothing
  240.  
  241. GLOBALS:
  242.     in_buffer =
  243.     buf_end =    Set to 1 past last character read in
  244.     buf_ptr =    Set to start of buffer
  245.     be_save =    Set to zero if it was non-zero
  246.     bp_save =    Set to zero
  247.  
  248. CALLS:
  249.     read (lib)
  250.  
  251. CALLED BY:
  252.     lexi
  253.     main
  254.     pr_comment
  255.  
  256. HISTORY:
  257.     initial coding     November 1976    D A Willcox of CAC
  258.     1/7/77        D A Willcox of CAC    Added check for switch back to
  259.                         partly full input buffer from
  260.                         temporary buffer 
  261.  
  262. */
  263. int     fill_buffer () { /* this routine reads stuff from the input */
  264.     int     count;
  265.     register int    i;
  266.  
  267.     if (bp_save != 0) {           /* there is a partly filled input buffer
  268.                       left */
  269.     buf_ptr = bp_save;     /* don't read anything, just switch buffers 
  270.                    */
  271.     buf_end = be_save;
  272.     bp_save = be_save = 0;
  273.     if (buf_ptr < buf_end)
  274.         return;           /* only return if there is really something
  275.                       in this buffer */
  276.     }
  277.  
  278.     count = read (input, in_buffer, inp_bufs);
  279.  
  280.     buf_end = in_buffer + count;
  281.     buf_ptr = in_buffer;
  282.  
  283.     if (count == 0) {           /* count of zero means eof */
  284.     had_eof = true;
  285.     *buf_end++ = ' ';
  286.     *buf_end++ = '\n';     /* insert extra newline.  it will
  287.                       eventually get indent to stop */
  288.     }
  289.  
  290.     return;
  291. };
  292. /*
  293.  
  294.               Copyright (C) 1976
  295.                 by the
  296.               Board of Trustees
  297.                 of the
  298.             University of Illinois
  299.  
  300.              All rights reserved
  301.  
  302.  
  303. NAME:
  304.     pad_output
  305.  
  306. FUNCTION:
  307.     Writes tabs and spaces to move the current column up to the
  308.     desired position.
  309.  
  310. ALGORITHM:
  311.     Put tabs and/or blanks into pobuf, then write pobuf.
  312.  
  313. PARAMETERS:
  314.     current        integer        The current column
  315.     target        integer        The desired column
  316.  
  317. RETURNS:
  318.     Integer value of the new column.  (If current >= target,
  319.     no action is taken, and current is returned.
  320.  
  321. GLOBALS:
  322.     None
  323.  
  324. CALLS:
  325.     write (sys)
  326.  
  327. CALLED BY:
  328.     dump_line
  329.  
  330. HISTORY:
  331.     initial coding     November 1976    D A Willcox of CAC
  332.  
  333. */
  334. int     pad_output (current, target)/* writes tabs and blanks (if necessary) to
  335.                       get the current output position up to
  336.                       the target column */
  337. int     current;           /* the current column value */
  338. int     target;               /* position we want it at */
  339. {
  340.     register int    curr; /* internal column pointer */
  341.     register char  *p; /* pointer into buffer of characters to be written */
  342.     char    pobuf[256]; /* pad characters are stored here before writing */
  343.     register int tcur;
  344.  
  345.     if (current >= target)
  346.     return (current);      /* line is already long enough */
  347.  
  348.     curr = current;
  349.     p = pobuf;
  350.     while (curr < target) {
  351.     if ((tcur = ((curr - 1) & tabmask) + tabsize + 1) <= target){
  352.         *p++ = '\t';       /* put a tab into buffer */
  353.         curr = tcur;
  354.     }
  355.     else {
  356.         while (curr++ < target)
  357.         *p++ = ' ';    /* pad with final blanks */
  358.     }
  359.     }
  360.  
  361.     write (output, pobuf, (short int) (p - pobuf)); /* write the characters we saved */
  362.     return (target);
  363. };
  364. /*
  365.  
  366.               Copyright (C) 1976
  367.                 by the
  368.               Board of Trustees
  369.                 of the
  370.             University of Illinois
  371.  
  372.              All rights reserved
  373.  
  374.  
  375. NAME:
  376.     count_spaces
  377.  
  378. FUNCTION:
  379.     Find out where printing of a given string will leave the current
  380.     character position on output.
  381.  
  382. ALGORITHM:
  383.     Run thru input string and add appropriate values to current position.
  384.  
  385. PARAMETERS:
  386.     current        integer          The current line character position
  387.     buffer        ptr to character  Pointer to input string
  388.  
  389. RETURNS:
  390.     Integer value of position after printing "buffer" starting in
  391.     column "current".
  392.  
  393. GLOBALS:
  394.     None
  395.  
  396. CALLS:
  397.     None
  398.  
  399. CALLED BY:
  400.     pr_comment
  401.  
  402. HISTORY:
  403.     initial coding     November 1976    D A Willcox of CAC
  404.  
  405. */
  406. int     count_spaces (current, buffer)
  407.                    /* this routine figures out where the
  408.                       character position will be after
  409.                       printing the text in buffer starting at
  410.                       column "current" */
  411. int     current;
  412. char   *buffer;
  413. {
  414.     register char  *buf; /* used to look thru buffer */
  415.     register int    cur; /* current character counter */
  416.  
  417.     cur = current;
  418.  
  419.     for (buf = buffer; *buf != '\0'; ++buf) {
  420.     switch (*buf) {
  421.  
  422.         case '\n': 
  423.         case 014:            /* form feed */
  424.         cur = 1;
  425.         break;
  426.  
  427.         case '\t': 
  428.         cur = ((cur - 1) & tabmask) + tabsize + 1;
  429.         break;
  430.  
  431.         case '':            /* this is a backspace */
  432.         --cur;
  433.         break;
  434.  
  435.         default: 
  436.         ++cur;
  437.         break;
  438.     }               /* end of switch */
  439.     }                   /* end of for loop */
  440.  
  441.     return (cur);
  442. };
  443. /*
  444.  
  445.               Copyright (C) 1976
  446.                 by the
  447.               Board of Trustees
  448.                 of the
  449.             University of Illinois
  450.  
  451.              All rights reserved
  452.  
  453.  
  454. NAME:
  455.     eqin
  456.  
  457. FUNCTION:
  458.     Returns true if the first arg matches the beginning of the second arg.
  459.  
  460. ALGORITHM:
  461.     Trivial
  462.  
  463. PARAMETERS:
  464.     str1    pointer to character
  465.     str2    pointer to character
  466.  
  467. RETURNS:
  468.     1 if first string matches start of second string
  469.     0 otherwise
  470.  
  471. GLOBALS:
  472.     None
  473.  
  474. CALLS:
  475.     None
  476.  
  477. CALLED BY:
  478.     lexi
  479.     main
  480.  
  481. HISTORY:
  482.     initial coding November 1976 by D A Willcox of CAC
  483.  
  484. */
  485. eqin (str1, str2)
  486. char   *str1;
  487. char   *str2;
  488. {
  489.     register char  *s1; /* local pointer into first string */
  490.     register char  *s2; /* local pointer into second string */
  491.  
  492.     s1 = str1;
  493.     s2 = str2;
  494.     while (*s1) {           /* compare no further than end of first
  495.                       string */
  496.     if (*s2 == 0)           /* check that second string isn't too short 
  497.                    */
  498.         return (false);
  499.     if (*s1++ != *s2++)
  500.         return (false);
  501.     }
  502.  
  503.     return (true);
  504. }
  505. /*
  506.               Copyright (C) 1976
  507.                 by the
  508.               Board of Trustees
  509.                 of the
  510.             University of Illinois
  511.  
  512.              All rights reserved
  513.  
  514. NAME:
  515.     cmp
  516.  
  517. FUNCTION:
  518.     Compares two strings
  519.  
  520. ALGORITHM:
  521.     Trivial
  522.  
  523. PARAMETERS:
  524.     a    Pointer to char        First string to compare
  525.     b    Pointer to char        Second string to compare
  526.  
  527. RETURNS:
  528.     -1 if a < b
  529.      0 if a = b
  530.      1 if a > b
  531.  
  532. GLOBALS:
  533.     None
  534.  
  535. CALLS:
  536.     None
  537.  
  538. CALLED BY:
  539.     main
  540.  
  541. HISTORY:
  542.     1/7/77        D A Willcox of CAC    Initial Coding
  543. */
  544. int     cmp (a, b)
  545. char   *a;
  546. char   *b;
  547. {
  548.     register char  *ta,
  549.                    *tb;
  550.  
  551.     ta = a;
  552.     tb = b;
  553.  
  554.     while (*ta) {
  555.     if (*ta > *tb)
  556.         return (1);
  557.     if (*ta < *tb)
  558.         return (-1);
  559.     ++ta;
  560.     ++tb;
  561.     }
  562.     if (*tb)
  563.     return (1);
  564.     else
  565.     return (0);
  566. }
  567.