home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / v / vim_src.zip / QUICKFIX.C < prev    next >
C/C++ Source or Header  |  1993-01-12  |  6KB  |  276 lines

  1. /* vi:ts=4:sw=4
  2.  *
  3.  * VIM - Vi IMitation
  4.  *
  5.  * Code Contributions By:    Bram Moolenaar            mool@oce.nl
  6.  *                            Tim Thompson            twitch!tjt
  7.  *                            Tony Andrews            onecom!wldrdg!tony 
  8.  *                            G. R. (Fred) Walter        watmath!watcgl!grwalter 
  9.  */
  10.  
  11. /*
  12.  * quickfix.c: functions for quickfix mode, using the Manx errorfile
  13.  */
  14.  
  15. #include "vim.h"
  16. #include "globals.h"
  17. #include "proto.h"
  18.  
  19. static void qf_free __ARGS((void));
  20.  
  21. /*
  22.  * for each error the next struct is allocated and linked in a list
  23.  */
  24. struct qf_line
  25. {
  26.     struct qf_line    *qf_next;    /* pointer to next error in the list */
  27.     struct qf_line    *qf_prev;    /* pointer to previous error in the list */
  28.     linenr_t         qf_lnum;    /* line number where the error occurred */
  29.     char            *qf_mark;    /* pointer to that line (if != NULL) */
  30.     int                 qf_col;    /* column where the error occurred */
  31.     char             qf_cleared;/* set to TRUE if qf_mark has been cleared */
  32.     char             qf_type;    /* type of the error (mostly 'E') */
  33.     int                 qf_nr;        /* error number */
  34.     char            *qf_fname;    /* file name where the error occurred */
  35.     char            *qf_text;    /* description of the error */
  36. };
  37.  
  38. static struct qf_line *qf_start;        /* pointer to the first error */
  39. static struct qf_line *qf_ptr;            /* pointer to the current error */
  40.  
  41. static int    qf_count = 0;        /* number of errors (0 means no error list) */
  42.        int    qf_index;            /* current index in the error list */
  43. static int    qf_marksset;        /* set to 1 when qf_mark-s have been set */
  44.  
  45. /*
  46.  * Read the errorfile into memory, line by line, building the error list.
  47.  * Return 1 for error, 0 for success.
  48.  */
  49.     int
  50. qf_init(fname)
  51.     char *fname;
  52. {
  53.     char             namebuf[CMDBUFFSIZE];
  54.     char            errmsg[CMDBUFFSIZE];
  55.     FILE            *fd;
  56.     struct qf_line    *qfp = NULL;
  57.  
  58.     if (fname == NULL)
  59.     {
  60.         emsg(e_errorf);
  61.         return 1;
  62.     }
  63.     if ((fd = fopen(fname, "r")) == NULL)
  64.     {
  65.         emsg(e_openerrf);
  66.         return 1;
  67.     }
  68.     qf_free();
  69.  
  70.     while (fgets(IObuff, IOSIZE, fd) != NULL)
  71.     {
  72.         if ((qfp = (struct qf_line *)alloc((unsigned)sizeof(struct qf_line))) == NULL)
  73.             goto error2;
  74.  
  75.     /* parse the line: "filename>linenr:colnr:type:number:text" */
  76.         if (sscanf(IObuff, "%[^>]>%ld:%d:%c:%d:%[^\n]", namebuf,
  77.                 &qfp->qf_lnum, &qfp->qf_col, &qfp->qf_type,
  78.                                 &qfp->qf_nr, errmsg) != 6)
  79.             goto error;
  80.         if ((qfp->qf_fname = strsave(namebuf)) == NULL)
  81.             goto error1;
  82.         if ((qfp->qf_text = strsave(errmsg)) == NULL)
  83.         {
  84.             free(qfp->qf_fname);
  85.             goto error1;
  86.         }
  87.         if (qf_count == 0)        /* first element in the list */
  88.         {
  89.             qf_start = qfp;
  90.             qfp->qf_prev = qfp;    /* first element points to itself */
  91.         }
  92.         else
  93.         {
  94.             qfp->qf_prev = qf_ptr;
  95.             qf_ptr->qf_next = qfp;
  96.         }
  97.         qfp->qf_next = qfp;        /* last element points to itself */
  98.         qfp->qf_mark = NULL;
  99.         qfp->qf_cleared = FALSE;
  100.         qf_ptr = qfp;
  101.         ++qf_count;
  102.     }
  103.     if (!ferror(fd))
  104.     {
  105.         qf_ptr = qf_start;
  106.         qf_index = 1;
  107.         fclose(fd);
  108.         return 0;
  109.     }
  110. error:
  111.     emsg(e_readerrf);
  112. error1:
  113.     free(qfp);
  114. error2:
  115.     fclose(fd);
  116.     qf_free();
  117.     return 1;
  118. }
  119.  
  120. /*
  121.  * jump to quickfix line "errornr"; if "errornr" is zero, redisplay the same line
  122.  */
  123.     void
  124. qf_jump(errornr)
  125.     int errornr;
  126. {
  127.     struct qf_line *qfp;
  128.     linenr_t        i;
  129.     char            *msgp;
  130.  
  131.     if (qf_count == 0)
  132.     {
  133.         emsg(e_quickfix);
  134.         return;
  135.     }
  136.     if (errornr == 0)
  137.         errornr = qf_index;
  138.     while (errornr < qf_index && qf_index > 1)
  139.     {
  140.         --qf_index;
  141.         qf_ptr = qf_ptr->qf_prev;
  142.     }
  143.     while (errornr > qf_index && qf_index < qf_count)
  144.     {
  145.         ++qf_index;
  146.         qf_ptr = qf_ptr->qf_next;
  147.     }
  148.  
  149.     /*
  150.      * read the wanted file if needed, and check autowrite etc.
  151.      */
  152.     if (getfile(qf_ptr->qf_fname, TRUE) <= 0)
  153.     {
  154.         /*
  155.          * use mark if possible, because the line number may be invalid
  156.          * after line inserts / deletes
  157.          */
  158.         i = 0;
  159.         msgp = "";
  160.         if ((qf_ptr->qf_mark != NULL && (i = ptr2nr(qf_ptr->qf_mark, (linenr_t)0)) == 0) || qf_ptr->qf_cleared)
  161.             msgp = "(line changed) ";
  162.         if (i == 0)
  163.             i = qf_ptr->qf_lnum;
  164.         if (i > line_count)
  165.             i = line_count;
  166.         Curpos.lnum = i;
  167.         Curpos.col = qf_ptr->qf_col;
  168.         adjustCurpos();
  169.         cursupdate();
  170.         smsg("(%d of %d) %s%s %d: %s", qf_index, qf_count, msgp, qf_ptr->qf_type == 'E' ? "Error" : "Warning", qf_ptr->qf_nr, qf_ptr->qf_text);
  171.  
  172.         if (!qf_marksset)        /* marks not set yet: try to find them for
  173.                                     the errors in the curren file */
  174.         {
  175.             for (i = 0, qfp = qf_start; i < qf_count; ++i, qfp = qfp->qf_next)
  176.                 if (strcmp(qfp->qf_fname, qf_ptr->qf_fname) == 0 && qfp->qf_lnum <= line_count)
  177.                     qfp->qf_mark = nr2ptr(qfp->qf_lnum);
  178.             qf_marksset = 1;
  179.         }
  180.     }
  181. }
  182.  
  183. /*
  184.  * list all errors
  185.  */
  186.     void
  187. qf_list()
  188. {
  189.     struct qf_line *qfp;
  190.     int i;
  191.  
  192.     if (qf_count == 0)
  193.     {
  194.         emsg(e_quickfix);
  195.         return;
  196.     }
  197.     qfp = qf_start;
  198.     gotocmdline(TRUE, NUL);
  199.     settmode(0);
  200.     for (i = 1; i <= qf_count; ++i)
  201.     {
  202.         sprintf(IObuff, "%2d line %ld col %2d %s %3d: %s",
  203.             i,
  204.             (long)qfp->qf_lnum,
  205.             qfp->qf_col,
  206.             qfp->qf_type == 'E' ? "Error" : "Warning",
  207.             qfp->qf_nr,
  208.             qfp->qf_text);
  209.         outstr(IObuff);
  210.         outchar('\n');
  211.         qfp = qfp->qf_next;
  212.         flushbuf();
  213.     }
  214.     settmode(1);
  215.     wait_return(TRUE);
  216. }
  217.  
  218. /*
  219.  * free the error list
  220.  */
  221.     static void
  222. qf_free()
  223. {
  224.     struct qf_line *qfp;
  225.  
  226.     while (qf_count)
  227.     {
  228.         qfp = qf_start->qf_next;
  229.         free(qf_start->qf_fname);
  230.         free(qf_start->qf_text);
  231.         free(qf_start);
  232.         qf_start = qfp;
  233.         --qf_count;
  234.     }
  235.     qf_marksset = 0;
  236. }
  237.  
  238. /*
  239.  * qf_clrallmarks() - clear all marks
  240.  *
  241.  * Used mainly when trashing the entire buffer during ":e" type commands
  242.  */
  243.     void
  244. qf_clrallmarks()
  245. {
  246.     int             i;
  247.     struct qf_line *qfp;
  248.  
  249.     if (qf_count)
  250.         for (i = 0, qfp = qf_start; i < qf_count; i++, qfp = qfp->qf_next)
  251.             qfp->qf_mark = NULL;
  252.     qf_marksset = 0;
  253. }
  254.  
  255. /*
  256.  * qf_adjustmark: set new ptr for a mark
  257.  */
  258.    void
  259. qf_adjustmark(old, new)
  260.     char        *old, *new;
  261. {
  262.     register int i;
  263.     struct qf_line *qfp;
  264.  
  265.     if (qf_count)
  266.     {
  267.         for (i = 0, qfp = qf_start; i < qf_count; ++i, qfp = qfp->qf_next)
  268.             if (qfp->qf_mark == old)
  269.             {
  270.                 qfp->qf_mark = new;
  271.                 if (new == NULL)
  272.                     qfp->qf_cleared = TRUE;
  273.             }
  274.     }
  275. }
  276.