home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / prgramer / pascal2c / comment.c < prev    next >
C/C++ Source or Header  |  1992-08-03  |  10KB  |  467 lines

  1. /* "p2c", a Pascal to C translator.
  2.    Copyright (C) 1989, 1990, 1991 Free Software Foundation.
  3.    Author's address: daveg@csvax.caltech.edu; 256-80 Caltech/Pasadena CA 91125.
  4.  
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation (any version).
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program; see the file COPYING.  If not, write to
  16. the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
  17.  
  18.  
  19.  
  20. #define PROTO_COMMENT_C
  21. #include "trans.h"
  22.  
  23.  
  24.  
  25. Static int cmttablesize;
  26. Static uchar *cmttable;
  27.  
  28. Static int grabbed_comment;
  29.  
  30.  
  31.  
  32.  
  33. /* Special comment forms:
  34.  
  35.    \001\001\001...      Blank line(s), one \001 char per blank line
  36.    \002text...          Additional line for previous comment
  37.    \003text...          Additional comment line, absolutely indented
  38.    \004text...        Note or warning line, unindented
  39.  
  40. */
  41.  
  42.  
  43.  
  44.  
  45. void setup_comment()
  46. {
  47.     curcomments = NULL;
  48.     cmttablesize = 200;
  49.     cmttable = ALLOC(cmttablesize, uchar, misc);
  50.     grabbed_comment = 0;
  51. }
  52.  
  53.  
  54.  
  55.  
  56.  
  57. int commentlen(cmt)
  58. Strlist *cmt;
  59. {
  60.     if (cmt)
  61.     if (*(cmt->s))
  62.         return strlen(cmt->s) + 4;
  63.     else
  64.         return 5;
  65.     else
  66.     return 0;
  67. }
  68.  
  69.  
  70. int commentvisible(cmt)
  71. Strlist *cmt;
  72. {
  73.     return (cmt &&
  74.         getcommentkind(cmt) != CMT_DONE &&
  75.         ((eatcomments != 1 && eatcomments != 2) ||
  76.          isembedcomment(cmt)));
  77. }
  78.  
  79.  
  80.  
  81.  
  82.  
  83.  
  84. /* If preceding statement's POST comments include blank lines,
  85.    steal all comments after longest stretch of blank lines as
  86.    PRE comments for the next statement. */
  87.  
  88. void steal_comments(olds, news, always)
  89. long olds, news;
  90. int always;
  91. {
  92.     Strlist *cmt, *cmtfirst = NULL, *cmtblank = NULL;
  93.     int len, longest;
  94.  
  95.     for (cmt = curcomments; cmt; cmt = cmt->next) {
  96.     if ((cmt->value & CMT_MASK) == olds &&
  97.         getcommentkind(cmt) == CMT_POST) {
  98.         if (!cmtfirst)
  99.         cmtfirst = cmt;
  100.     } else {
  101.         cmtfirst = NULL;
  102.     }
  103.     }
  104.     if (cmtfirst) {
  105.     if (!always) {
  106.         longest = 0;
  107.         for (cmt = cmtfirst; cmt; cmt = cmt->next) {
  108.         if (cmt->s[0] == '\001') {   /* blank line(s) */
  109.             len = strlen(cmt->s);
  110.             if (len > longest) {
  111.             longest = len;
  112.             cmtblank = cmt;
  113.             }
  114.         }
  115.         }
  116.         if (longest > 0) {
  117.         if (blankafter)
  118.             cmtfirst = cmtblank->next;
  119.         else
  120.             cmtfirst = cmtblank;
  121.         } else if (commentafter == 1)
  122.         cmtfirst = NULL;
  123.     }
  124.     changecomments(cmtfirst, CMT_POST, olds, CMT_PRE, news);
  125.     }
  126. }
  127.  
  128.  
  129.  
  130. Strlist *fixbeginendcomment(cmt)
  131. Strlist *cmt;
  132. {
  133.     char *cp, *cp2;
  134.  
  135.     if (!cmt)
  136.     return NULL;
  137.     cp = cmt->s;
  138.     while (isspace(*cp))
  139.     cp++;
  140.     if (!strcincmp(cp, "procedure ", 10)) {    /* remove "PROCEDURE" keyword */
  141.     strcpy(cp, cp+10);
  142.     } else if (!strcincmp(cp, "function ", 9)) {
  143.     strcpy(cp, cp+9);
  144.     }
  145.     while (isspace(*cp))
  146.     cp++;
  147.     if (!*cp)
  148.     return NULL;
  149.     if (getcommentkind(cmt) == CMT_ONBEGIN) {
  150.     cp2 = curctx->sym->name;
  151.     while (*cp2) {
  152.         if (toupper(*cp2++) != toupper(*cp++))
  153.         break;
  154.     }
  155.     while (isspace(*cp))
  156.         cp++;
  157.     if (!*cp2 && !*cp)
  158.         return NULL;     /* eliminate function-begin comment */
  159.     }
  160.     return cmt;
  161. }
  162.  
  163.  
  164.  
  165.  
  166. Static void attach_mark(sp)
  167. Stmt *sp;
  168. {
  169.     long serial;
  170.  
  171.     while (sp) {
  172.     serial = sp->serial;
  173.     if (serial >= 0 && serial < cmttablesize) {
  174.         cmttable[serial]++;
  175.         if (sp->kind == SK_IF && serial+1 < cmttablesize)
  176.         cmttable[serial+1]++;   /* the "else" branch */
  177.     }
  178.     attach_mark(sp->stm1);
  179.     attach_mark(sp->stm2);
  180.     sp = sp->next;
  181.     }
  182. }
  183.  
  184.  
  185.  
  186. void attach_comments(sbase)
  187. Stmt *sbase;
  188. {
  189.     Strlist *cmt;
  190.     long serial, i, j;
  191.     int kind;
  192.  
  193.     if (spitorphancomments)
  194.     return;
  195.     if (serialcount >= cmttablesize) {
  196.     cmttablesize = serialcount + 100;
  197.     cmttable = REALLOC(cmttable, cmttablesize, uchar);
  198.     }
  199.     for (i = 0; i < cmttablesize; i++)
  200.     cmttable[i] = 0;
  201.     attach_mark(sbase);
  202.     for (cmt = curcomments; cmt; cmt = cmt->next) {
  203.     serial = cmt->value & CMT_MASK;
  204.     kind = getcommentkind(cmt);
  205.     if (serial < 0 || serial >= cmttablesize || cmttable[serial])
  206.         continue;
  207.     i = 0;
  208.     j = 0;
  209.     do {
  210.         if (commentafter == 1) {
  211.         j++;
  212.         if (j % 3 == 0)
  213.             i++;
  214.         } else if (commentafter == 0) {
  215.         i++;
  216.         if (i % 3 == 0)
  217.             j++;
  218.         } else {
  219.         i++;
  220.         j++;
  221.         }
  222.         if (serial+i < cmttablesize && cmttable[serial+i]) {
  223.         setcommentkind(cmt, CMT_PRE);
  224.         cmt->value += i;
  225.         break;
  226.         }
  227.         if (serial-j > 0 && cmttable[serial-j]) {
  228.         setcommentkind(cmt, CMT_POST);
  229.         cmt->value -= j;
  230.         break;
  231.         }
  232.     } while (serial+i < cmttablesize || serial-j > 0);
  233.     }
  234. }
  235.  
  236.  
  237.  
  238.  
  239. void setcommentkind(cmt, kind)
  240. Strlist *cmt;
  241. int kind;
  242. {
  243.     cmt->value = (cmt->value & CMT_MASK) | (kind << CMT_SHIFT);
  244. }
  245.  
  246.  
  247.  
  248. void commentline(kind)
  249. int kind;
  250. {
  251.     char *cp;
  252.     Strlist *sl;
  253.  
  254.     if (grabbed_comment) {
  255.     grabbed_comment = 0;
  256.     return;
  257.     }
  258.     if (blockkind == TOK_IMPORT || skipping_module)
  259.     return;
  260.     if (eatcomments == 1)
  261.     return;
  262.     for (cp = curtokbuf; (cp = my_strchr(cp, '*')) != NULL; ) {
  263.     if (*++cp == '/') {
  264.         cp[-1] = '%';
  265.         note("Changed \"* /\" to \"% /\" in comment [140]");
  266.     }
  267.     }
  268.     sl = strlist_append(&curcomments, curtokbuf);
  269.     sl->value = curserial;
  270.     setcommentkind(sl, kind);
  271. }
  272.  
  273.  
  274.  
  275. void addnote(msg, serial)
  276. char *msg;
  277. long serial;
  278. {
  279.     int len1, len2, xextra, extra;
  280.     int defer = (notephase > 0 && spitcomments == 0);
  281.     Strlist *sl, *base = NULL, **pbase = (defer) ? &curcomments : &base;
  282.     char *prefix;
  283.  
  284.     if (defer && (outf != stdout || !quietmode))
  285.     printf("%s, line %d: %s\n", infname, inf_lnum, msg);
  286.     else if (outf != stdout)
  287.     printf("%s, line %d/%d: %s\n", infname, inf_lnum, outf_lnum, msg);
  288.     if (verbose)
  289.     fprintf(logf, "%s, %d/%d: %s\n", infname, inf_lnum, outf_lnum, msg);
  290.     if (notephase == 2 || regression)
  291.     prefix = format_s("\004 p2c: %s:", infname);
  292.     else
  293.     prefix = format_sd("\004 p2c: %s, line %d:", infname, inf_lnum);
  294.     len1 = strlen(prefix);
  295.     len2 = strlen(msg) + 2;
  296.     if (len1 + len2 < linewidth-4) {
  297.     msg = format_ss("%s %s ", prefix, msg);
  298.     } else {
  299.     extra = xextra = 0;
  300.     while (len2 - extra > linewidth-6) {
  301.         while (extra < len2 && !isspace(msg[extra]))
  302.         extra++;
  303.         xextra = extra;
  304.         while (extra < len2 && isspace(msg[extra]))
  305.         extra++;
  306.     }
  307.     prefix = format_sds("%s %.*s", prefix, xextra, msg);
  308.     msg += extra;
  309.     sl = strlist_append(pbase, prefix);
  310.     sl->value = serial;
  311.     setcommentkind(sl, CMT_POST);
  312.     msg = format_s("\003 * %s ", msg);
  313.     }
  314.     sl = strlist_append(pbase, msg);
  315.     sl->value = serial;
  316.     setcommentkind(sl, CMT_POST);
  317.     outputmode++;
  318.     outcomments(base);
  319.     outputmode--;
  320. }
  321.  
  322.  
  323.  
  324.  
  325.  
  326. /* Grab a comment off the end of the current line */
  327. Strlist *grabcomment(kind)
  328. int kind;
  329. {
  330.     char *cp, *cp2;
  331.     Strlist *cmt, *savecmt;
  332.  
  333.     if (grabbed_comment || spitcomments == 1)
  334.     return NULL;
  335.     cp = inbufptr;
  336.     while (isspace(*cp))
  337.     cp++;
  338.     if (*cp == ';' || *cp == ',' || *cp == '.')
  339.     cp++;
  340.     while (isspace(*cp))
  341.     cp++;
  342.     cp2 = curtokbuf;
  343.     if (*cp == '{') {
  344.     cp++;
  345.     while (*cp && *cp != '}')
  346.         *cp2++ = *cp++;
  347.     if (!*cp)
  348.         return NULL;
  349.     cp++;
  350.     } else if (*cp == '(' && cp[1] == '*') {
  351.     cp += 2;
  352.     while (*cp && (*cp != '*' || cp[1] != ')'))
  353.         *cp2++ = *cp++;
  354.     if (!*cp)
  355.         return NULL;
  356.     cp += 2;
  357.     } else
  358.     return NULL;
  359.     while (isspace(*cp))
  360.     cp++;
  361.     if (*cp)
  362.     return NULL;
  363.     *cp2 = 0;
  364.     savecmt = curcomments;
  365.     curcomments = NULL;
  366.     commentline(kind);
  367.     cmt = curcomments;
  368.     curcomments = savecmt;
  369.     grabbed_comment = 1;
  370.     if (cmtdebug > 1)
  371.     fprintf(outf, "Grabbed comment [%d] \"%s\"\n", cmt->value & CMT_MASK, cmt->s);
  372.     return cmt;
  373. }
  374.  
  375.  
  376.  
  377. int matchcomment(cmt, kind, stamp)
  378. Strlist *cmt;
  379. int kind, stamp;
  380. {
  381.     if (spitcomments == 1 && (cmt->value & CMT_MASK) != 10000 &&
  382.     *cmt->s != '\001' && (kind >= 0 || stamp >= 0))
  383.     return 0;
  384.     if (!cmt || getcommentkind(cmt) == CMT_DONE)
  385.     return 0;
  386.     if (stamp >= 0 && (cmt->value & CMT_MASK) != stamp)
  387.     return 0;
  388.     if (kind >= 0) {
  389.     if (kind & CMT_NOT) {
  390.         if (getcommentkind(cmt) == kind - CMT_NOT)
  391.         return 0;
  392.     } else {
  393.         if (getcommentkind(cmt) != kind)
  394.         return 0;
  395.     }
  396.     }
  397.     return 1;
  398. }
  399.  
  400.  
  401.  
  402. Strlist *findcomment(cmt, kind, stamp)
  403. Strlist *cmt;
  404. int kind, stamp;
  405. {
  406.     while (cmt && !matchcomment(cmt, kind, stamp))
  407.     cmt = cmt->next;
  408.     if (cmt && cmtdebug > 1)
  409.     fprintf(outf, "Found comment [%d] \"%s\"\n", cmt->value & CMT_MASK, cmt->s);
  410.     return cmt;
  411. }
  412.  
  413.  
  414.  
  415. Strlist *extractcomment(cmt, kind, stamp)
  416. Strlist **cmt;
  417. int kind, stamp;
  418. {
  419.     Strlist *base, **last, *sl;
  420.  
  421.     last = &base;
  422.     while ((sl = *cmt)) {
  423.     if (matchcomment(sl, kind, stamp)) {
  424.         if (cmtdebug > 1)
  425.         fprintf(outf, "Extracted comment [%d] \"%s\"\n",
  426.                 sl->value & CMT_MASK, sl->s);
  427.         *cmt = sl->next;
  428.         *last = sl;
  429.         last = &sl->next;
  430.     } else
  431.         cmt = &sl->next;
  432.     }
  433.     *last = NULL;
  434.     return base;
  435. }
  436.  
  437.  
  438. void changecomments(cmt, okind, ostamp, kind, stamp)
  439. Strlist *cmt;
  440. int okind, ostamp, kind, stamp;
  441. {
  442.     while (cmt) {
  443.     if (matchcomment(cmt, okind, ostamp)) {
  444.         if (cmtdebug > 1)
  445.         fprintf(outf, "Changed comment [%s:%d] \"%s\" ",
  446.             CMT_NAMES[getcommentkind(cmt)],
  447.             cmt->value & CMT_MASK, cmt->s);
  448.         if (kind >= 0)
  449.         setcommentkind(cmt, kind);
  450.         if (stamp >= 0)
  451.         cmt->value = (cmt->value & ~CMT_MASK) | stamp;
  452.         if (cmtdebug > 1)
  453.         fprintf(outf, " to [%s:%d]\n",
  454.             CMT_NAMES[getcommentkind(cmt)], cmt->value & CMT_MASK);
  455.     }
  456.     cmt = cmt->next;
  457.     }
  458. }
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465. /* End. */
  466.  
  467.