/* scanner.H
 * John Viega
 *
 * Jan 28-29 2000
 */

#ifndef __SCANNER_H__
#define __SCANNER_H__
#include "lex.H"
#include "vulndb.H"
#include "handlers.H"

struct LineIgnoreList
{
  int line_start;
  int line_end;
  char **ignore; 
  LineIgnoreList *next;
  int scope_ends_at_token;
  int scope_starts_at_token;
  int token_number;

  LineIgnoreList(int l1, int l2, int tn)
    {
      line_start            = l1;
      line_end              = l2;
      token_number          = tn;
      ignore                = 0;
      next                  = 0;
      scope_ends_at_token   = 0;
      scope_starts_at_token = 0;      
    }

  ~LineIgnoreList()
    {
      int i=0;
      if(!ignore) return;
      while(ignore[i] != 0)
	{
	  delete[] ignore[i++];
	}
      delete[] ignore;
    }
};

class Scanner{
public:
  Scanner(Lex *l) { lexer = l; ignore_data_end = ignore_data_start = 0;  
                    ignore_ptr = &ignore_data_start; }
  void RunScan();
  ~Scanner()
  {
    while(ignore_data_start)
      {
	LineIgnoreList *n = ignore_data_start->next;
	delete ignore_data_start;
	ignore_data_start = n;
      }
  }

private:
  Lex            *lexer;
  LineIgnoreList *ignore_data_end;
  LineIgnoreList *ignore_data_start;
  LineIgnoreList **ignore_ptr;
  void AddToBigIgnoreList(LineIgnoreList *p);
  void CheckName(char *name, TokenContainer *tc, int i, int startline, int endline);
  void ProcessIgnores();
  void CheckOneContainer(TokenContainer *tc, CommentTok *tok);
  void FigureOutCommand(TokenContainer *tc, CommentTok *tok);
  void CalculateEffectiveLineNumber(CommentTok *tok, int& l1, int& l2);
  int  IgnoreItOrNo(char *id, int start_line, int end_line, int token_index);
};  
#endif
