title: splint debugging parse error
body: <p>This is my first time using splint (from Ubuntu repositories) and I immediately got hit by a WTF. The error message:</p>
  
  <pre><code>nightcracker@nightcracker-pc:~/c/brainfuck$ splint brainfuck.c
  Splint 3.1.2 --- 03 May 2009
  
  brainfuck.c:17:6: Parse Error. (For help on parse errors, see splint -help
                 parseerrors.)
  *** Cannot continue.
  </code></pre>
  
  <p>Now, apparently it sees something wrong on line 16, column 6. Let's check that out (posting full code):</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  
  enum {
      CELL_CHUNK_SIZE = 1024,
  };
  
  typedef unsigned char cell;
  
  int main(int argc, char *argv[]) {
      if (argc &lt; 1) {
          fprintf(stderr, "ERROR: Not enough arguments\n");
          return 1;
      }
  
      FILE  *srcfile; // source file &lt;&lt; THIS LINE APPARENTLY IS WRONG
      long srclen; // source file size
      char *bf; // brainfuck code file in memory
  
      char *ip; // instruction pointer
      cell *cells; // brainfuck cells
      cell *newcells; // used for creating a new chunk of cells
      cell *cp; // cell pointer
      unsigned long numcells = CELL_CHUNK_SIZE; // amount of current cells
      unsigned nest; // current nesting
      int buf; // i/o buffer
  
      srcfile = fopen(argv[1], "rb");
      if (srcfile == NULL) {
          fprintf(stderr, "ERROR: Couldn't open source file\n");
          return 2;
      }
  
      // get source file length
      fseek(srcfile, 0, SEEK_END);
      srclen = ftell(srcfile);
      fseek(srcfile, 0, SEEK_SET);
  
      // allocate memory for source file
      bf = malloc(srclen);
      if (bf == NULL) {
          fprintf(stderr, "ERROR: Couldn't allocate memory for source file\n");
          return 3;
      }
  
      // read source file in memory
      if (srclen != fread(bf, sizeof(char), srclen, srcfile)) {
          fprintf(stderr, "ERROR: Error while reading source file\n");
          free(bf);
          return 4;
      }
  
      fclose(srcfile);
  
      cells = malloc(CELL_CHUNK_SIZE * sizeof(cell));
      memset(cells, 0, CELL_CHUNK_SIZE);
  
      if (cells == NULL) {
          fprintf(stderr, "ERROR: Memory allocation failed\n");
          free(bf);
          free(cells);
          return 5;
      }
  
      cp = cells; // cell pointer initialized to most-left cell
      ip = bf; // instruction pointer initialized to first character
      nest = 0;
  
      while (ip &gt;= bf &amp;&amp; ip &lt;= (bf + srclen)) {
          switch (*ip) {
              case '+':
                  (*cp)++;
                  break;
              case '-':
                  (*cp)--;
                  break;
              case '&gt;':
                  cp++;
                  if ((cp - cells) == numcells) {
                      newcells = realloc(cells, (numcells + CELL_CHUNK_SIZE) * sizeof(cell)); // allocate memory for new chunk
  
                      if (newcells == NULL) {
                          fprintf(stderr, "ERROR: Memory allocation failed\n");
                          free(bf);
                          free(cells);
                          return 5;
                      }
  
                      cp = newcells + (cp - cells); // point cell pointer to cell in new chunk
                      cells = newcells; // point cells to new memory location (if altered)
                      memset(cp, 0, CELL_CHUNK_SIZE); // initialize new chunk
                      numcells += CELL_CHUNK_SIZE;
                  }
                  break;
              case '&lt;':
                  cp--;
                  break;
              case '.':
                  putchar(*cp);
                  break;
              case ',':
                  if ((buf = getchar()) != EOF) {
                      *cp = (unsigned char) buf;
                  } else *cp = 0;
                  break;
              case '[':
                  if (!(*cp)) {
                      ip++; // move past the opening bracket
                      while (nest &gt; 0 || *ip != ']') { // skip to matching ]
                          if (*ip == '[') nest++; // enter nest
                          if (*ip == ']') nest--; // leave nest (or main loop, in which nesting &gt; 0 fails)
  
                          ip++; // move right
                      }
  
                  }
                  break;
              case ']':
                  if (*cp) {
                      ip--; // move before the closing bracket
                      while (nest &gt; 0 || *ip != '[') { // rewind to matching [
                          if (*ip == '[') nest--; // leave nest (or main loop, in which nesting &gt; 0 fails)
                          if (*ip == ']') nest++; // enter nest
  
                          ip--; // move left
                      }
                      ip--; // move before the opening bracket
                  }
                  break;
          }
  
          ip++; // move to next instruction
      }
  
  
      free(cells);
      free(bf);
      return 0;
  }
  </code></pre>
  
  <p>Note that this program compiles without errors (<code>gcc -Wall -std=c99 brainfuck.c</code>) and runtime behaves normal.</p>
  
  <p>Note: if you are offended by the name brainfuck, live with it. It's a programming language that is named that way by the author and I respect and use that name.</p>