                          /* comments.c, 25 May 11 */

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "global.h"
#include "errors.h"
#include "comments.h"


#define UNLIKELY_COMMENT 1000
#define MAX_LINE_LEN 1024
#define MAX_SUFF_LEN 7

BOOL do_fortran_comments = FALSE,
     do_eol_comments = FALSE,
     do_trace_lang_info;
int first_comment_char = UNLIKELY_COMMENT,
    second_comment_char;

struct suf_comment_rec {
	char suffix_str[MAX_SUFF_LEN+1];
	int first_comment_char;
	int second_comment_char;
	struct suf_comment_rec *next;
	} *comment_list;

static FILE *comment_file;
static CHAR line_buf[MAX_LINE_LEN]; // Current input line
static int cur_line_len;


void read_li_line(void)
{
cur_line_len=0;
// Read a line
if (fgets(line_buf, MAX_LINE_LEN, comment_file) == NULL)
   return;

for (; cur_line_len < MAX_LINE_LEN; cur_line_len++)
   if (line_buf[cur_line_len] == NULL_CHAR)
      {
      cur_line_len--; // Assume newline is one character long
      line_buf[cur_line_len]=NULL_CHAR;
      break;
      }

// printf("%d:%s\n", cur_line_len, line_buf);
}


static int skip_space(int ch_offset)
{
while (isspace(line_buf[ch_offset]) && (ch_offset < cur_line_len))
   ch_offset++;
return ch_offset;
}


static char * get_file_ext(char *filename)
{
size_t ch_offset = strlen(filename);

while (ch_offset > 0)
   {
   if (filename[ch_offset] == '.')
      return filename+ch_offset+1;
   ch_offset--;
   }
return NULL;
}


void get_lang_comment_info(char *filename)
{
char * file_ext = get_file_ext(filename);
struct suf_comment_rec *temp_comment_ptr;

do_eol_comments=FALSE;
do_fortran_comments=FALSE;
if (file_ext == NULL)
   {
   first_comment_char=UNLIKELY_COMMENT;
   return;
   }
temp_comment_ptr=comment_list;
while (temp_comment_ptr)
   {
   if (strcmp(temp_comment_ptr->suffix_str, file_ext) == 0)
      {
      first_comment_char=temp_comment_ptr->first_comment_char;
      second_comment_char=temp_comment_ptr->second_comment_char;
      if (first_comment_char == '*')
	 do_fortran_comments=TRUE;
      else
	 do_eol_comments=TRUE;
      return;
      }
   temp_comment_ptr=temp_comment_ptr->next;
   }
first_comment_char=UNLIKELY_COMMENT;
second_comment_char=0;
}


void init_comment_handling(char *li_name)
{
first_comment_char='#';
second_comment_char=0;
comment_file = fopen(li_name, "r");

if (comment_file == NULL)
   {
   print_warning("Could not open language information file: %s\n", li_name);
   return;
   }

if (do_trace_lang_info)
   printf("Opened %s\n", li_name);

while (!feof(comment_file))
   {
   read_li_line();
   if (cur_line_len > 0)
      {
      int lang_start=skip_space(0),
          lang_end,
	  comment_offset;
      struct suf_comment_rec *comment_ptr;

      if (lang_start == cur_line_len)
	 continue;
      if (line_buf[lang_start] == '#') // A comment line
	 continue;
      // Get language name
      lang_end=lang_start;
      while ((!isspace(line_buf[lang_end])) && (lang_end < cur_line_len))
	 lang_end++;
      comment_ptr=malloc(sizeof(struct suf_comment_rec));
      if (lang_end-lang_start < MAX_SUFF_LEN)
	 {
	 memcpy(comment_ptr->suffix_str, line_buf+lang_start,
						lang_end-lang_start);
	 comment_ptr->suffix_str[lang_end-lang_start]='\0';
	 }
      else
	 {
	 print_warning("Language suffix too long: %s\n", line_buf+lang_start);
	 continue;
	 }
      // Get first comment character
      comment_offset=skip_space(lang_end);
      if (comment_offset == cur_line_len)
	 {
	 print_warning("Missing comment characters: %s\n", line_buf+lang_start);
	 continue;
	 }
      comment_ptr->first_comment_char=line_buf[comment_offset];
      // Get second comment character or nothing
      if (comment_offset+1 <= cur_line_len)
	 comment_ptr->second_comment_char=line_buf[comment_offset+1];
      else
	 comment_ptr->second_comment_char=0;
      comment_ptr->next=comment_list;
      comment_list=comment_ptr;
      }
   }

fclose(comment_file);
}

