// File: /workspace/github_c_makefile_star2_O1/mmayer[P]pcal/src/readfile.c
// Function: read_datefile
void read_datefile (FILE *fp, char *filename)
{
   static int file_level = 0;
   int if_level = 0;
   int line = 0;
   int extra = 0;
   int pptype, ntokens, save_year, expr, (*pfcn) (char *) = NULL;
   char *ptok = NULL;
   char **pword;
   char msg[STRSIZ], incpath[STRSIZ], save_font;

   /* stack for processing nested "if{n}defs" - required for "elif" */
   struct {
      int state;   /* PROCESSING, AWAITING_TRUE, SKIP_TO_ENDIF */
      int else_ok;   /* is "elif" or "else" legal at this point? */
   } if_state[MAX_IF_NESTING+1];
   
   if (fp == NULL) return;   /* whoops, no date file */
      
   /* Note that there is no functional limit on file nesting.  This is mostly
      to catch infinite loops (e.g., a includes b, b includes a).
   */
   if (++file_level > MAX_FILE_NESTING) {
      ERR(E_FILE_NESTING);
      exit(EXIT_FAILURE);
   }
   
   save_year = curr_year;   /* save current year... */
   save_font = fontstyle[0];   /* ... and font style */
   
   if_state[0].state = PROCESSING;   /* set up initial state */
   if_state[0].else_ok = FALSE;
   
   /* read lines until EOF */
   
   while (get_pcal_line(fp, lbuf, &line)) {
      char suffix;
      
      if (DEBUG(DEBUG_PP)) {
         fprintf(stderr, "%s (%d)", filename, line);
         if (if_state[if_level].state == PROCESSING) fprintf(stderr, ": '%s'", lbuf);
         fprintf(stderr, "\n");
      }
      
      ntokens = loadwords(words, lbuf); /* split line into tokens */
      pword = words;   /* point to the first */
      
      /* get token type and pointers to function and name */
      
      suffix = words[0][strlen(words[0])-1];
      if ((pptype = get_token(*pword++)) != PP_OTHER) {
         pfcn = pp_info[pptype].pfcn;
         ptok = pp_info[pptype].name;
         pptype = pp_info[pptype].code;   /* use type code */
      }
      
      /* Perform symbol value substitution, but bypass it for any 'undef'
        preprocessor commands, otherwise there's no way to 'undef' a symbol
        which also had a value defined with it.
      */
      if (pptype != PP_UNDEF) {
         char **ap, *nap;
         for (ap=words; *ap; ap++) {
            if ((nap = find_sym_val(*ap))) *ap=nap;
         }
      }
      
      switch (pptype) {

      case PP_DEFINE:
         if (if_state[if_level].state == PROCESSING) (void) (*pfcn)(*pword);
         if (ntokens == 3) do_define_sym_val(*pword,pword[1]);
         extra = ntokens > 3;
         break;
         
      case PP_UNDEF:
         if (if_state[if_level].state == PROCESSING) (void) (*pfcn)(*pword);
         extra = ntokens > 2;
         break;
         
      case PP_ELIF:
         if (!if_state[if_level].else_ok) {
            ERR(E_ELIF_ERR);
            break;
         }
         
         /* if a true expression has just been processed, disable processing
            and skip to endif; if no true expression has been found yet and
            the current expression is true, enable processing
         */
         switch (if_state[if_level].state) {
         case PROCESSING:
            if_state[if_level].state = SKIP_TO_ENDIF;
            break;
         case AWAITING_TRUE:
            copy_text(lbuf, pword);   /* reconstruct string */
            if ((expr = (*pfcn)(lbuf)) == EXPR_ERR) {
               ERR(E_EXPR_SYNTAX);
               expr = FALSE;
            }
            if (expr) if_state[if_level].state = PROCESSING;
            break;
         }
         
         extra = FALSE;
         break;
         
      case PP_ELSE:
         if (!if_state[if_level].else_ok) {
            ERR(E_ELSE_ERR);
            break;
         }
         
         /* if a true condition has just been processed, disable processing
            and skip to endif; if no true condition has been found yet, enable
            processing
         */
         switch (if_state[if_level].state) {
         case PROCESSING:
            if_state[if_level].state = SKIP_TO_ENDIF;
            break;
         case AWAITING_TRUE:
            if_state[if_level].state = PROCESSING;
            break;
         }
         
         /* subsequent "elif" or "else" forbidden */
         if_state[if_level].else_ok = FALSE;
         extra = ntokens > 1;
         break;
         
      case PP_ENDIF:
         if (if_level < 1) {
            ERR(E_END_ERR);
            break;
         }
         if_level--;
         extra = ntokens > 1;
         break;
         
      case PP_IFDEF:
      case PP_IFNDEF:
         /* "if{n}def"s nested too deeply? */
         if (++if_level > MAX_IF_NESTING) {
            ERR(E_IF_NESTING);
            exit(EXIT_FAILURE);
            break;
         }
         
         /* if processing enabled at outer level, evaluate expression and
            enable/disable processing for following clause; if not, skip to
            matching endif
         */
         if (if_state[if_level-1].state == PROCESSING) {
            copy_text(lbuf, pword);   /* reconstruct string */
            if ((expr = (*pfcn)(lbuf)) == EXPR_ERR) {
               ERR(E_EXPR_SYNTAX);
               expr = FALSE;
            }
            if_state[if_level].state = expr ? PROCESSING : AWAITING_TRUE;
         } 
         else if_state[if_level].state = SKIP_TO_ENDIF;
         
         if_state[if_level].else_ok = TRUE;
         extra = FALSE;
         break;
         
      case PP_INCLUDE:
         if (if_state[if_level].state == PROCESSING) {
            do_include(mk_path(incpath, filename), *pword, suffix == '?');
         }
         extra = ntokens > 2;
         break;
         
      case PP_OTHER:   
         /* None of the above... Parse this configuration file line as a
            non-preprocessor directive.  This could be an event specification,
            an event deletion specification, a 'year' specification, an 'input
            language' specification, an option specification, or a 'note box'
            text specification.
         */
         if (if_state[if_level].state == PROCESSING) {

            switch (parse_as_non_preproc(words, filename)) {

            case PARSE_INVDATE:
               ERR(E_INV_DATE);
               break;
               
            case PARSE_INVLINE:
               ERR(E_INV_LINE);
               break;
               
            case PARSE_NOMATCH:
               ERR(E_NO_MATCH);
               break;
            }
         }
         extra = FALSE;
         break;
         
      } /* end switch */
      
      if (extra) {   /* extraneous data? */
         sprintf(msg, E_GARBAGE, ptok);
         ERR(msg);
      }
      
   } /* end while */
   
   if (if_level > 0) fprintf(stderr, E_UNT_IFDEF, progname, filename);
   
   file_level--;
   curr_year = save_year;   /* restore saved year and font style */
   fontstyle[0] = save_font;

   return;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x288, %rsp            # imm = 0x288
movq %rsi, 0x10(%rsp)
movl $0x0, 0xc(%rsp)
movq %rdi, 0x38(%rsp)
testq %rdi, %rdi
je 0xba86
movl 0x22372(%rip), %eax     # 0x2d820
leal 0x1(%rax), %ecx
movl %ecx, 0x22369(%rip)     # 0x2d820
cmpl $0xa, %eax
jge 0xbacd
leaq 0x22119(%rip), %rbx     # 0x2d5e0
movl (%rbx), %ebp
leaq 0x1d7c6(%rip), %r14     # 0x28c96
movb (%r14), %r15b
movq $0x0, 0x40(%rsp)
leaq 0x2144d(%rip), %rsi     # 0x2c930
leaq 0xc(%rsp), %rdx
movq 0x38(%rsp), %rdi
callq 0xb0c4
testl %eax, %eax
je 0xba7b
movb %r15b, 0x1a(%rsp)
movl %ebp, 0x2c(%rsp)
leaq 0x211d2(%rip), %rbp     # 0x2c6dc
leaq 0x2141f(%rip), %r12     # 0x2c930
leaq 0xc(%rsp), %r14
xorl %r15d, %r15d
xorl %r13d, %r13d
movq $0x0, 0x30(%rsp)
movq $0x0, 0x20(%rsp)
testb $0x20, (%rbp)
jne 0xb6d2
leaq 0x215f1(%rip), %rbx     # 0x2cb30
movq %rbx, %rdi
movq %r12, %rsi
callq 0xa985
movl %eax, 0x1c(%rsp)
movq (%rbx), %rbx
movq %rbx, %rdi
callq 0x5100
movb -0x1(%rbx,%rax), %al
movb %al, 0x1b(%rsp)
movq %rbx, %rdi
callq 0xbad7
cmpl $-0x1, %eax
je 0xb594
cltq
leaq (%rax,%rax,2), %rax
leaq 0x1d285(%rip), %rcx     # 0x28800
movq 0x10(%rcx,%rax,8), %rdx
movq %rdx, 0x20(%rsp)
movq (%rcx,%rax,8), %rdx
movq %rdx, 0x30(%rsp)
movl 0x8(%rcx,%rax,8), %ebx
jmp 0xb599
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
cmpl $0x7, %ebx
jne 0xb5e9
movslq %r15d, %rax
cmpl $0x0, 0x40(%rsp,%rax,8)
jne 0xb5b7
leaq 0x21581(%rip), %rax     # 0x2cb30
movq 0x8(%rax), %rdi
callq *0x20(%rsp)
xorl %r13d, %r13d
cmpl $0x3, 0x1c(%rsp)
setge %r13b
testl %r13d, %r13d
jne 0xb6ec
movq 0x38(%rsp), %rdi
movq %r12, %rsi
movq %r14, %rdx
callq 0xb0c4
testl %eax, %eax
jne 0xb52e
jmp 0xba5f
movl %r13d, 0x28(%rsp)
movl %r15d, %r13d
movq %r14, %r15
movq %r12, %r14
movq %rbp, %r12
leaq 0x2152f(%rip), %rax     # 0x2cb30
movq (%rax), %rdi
testq %rdi, %rdi
je 0xb645
leaq 0x21520(%rip), %rax     # 0x2cb30
leaq 0x8(%rax), %rbp
callq 0xc1a1
cmpl $-0x1, %eax
je 0xb62d
cltq
leaq 0x22529(%rip), %rcx     # 0x2db50
movq (%rcx,%rax,8), %rax
jmp 0xb62f
xorl %eax, %eax
testq %rax, %rax
je 0xb638
movq %rax, -0x8(%rbp)
movq (%rbp), %rdi
addq $0x8, %rbp
testq %rdi, %rdi
jne 0xb614
incl %ebx
cmpl $0x8, %ebx
ja 0xb8a1
leaq 0x13599(%rip), %rcx     # 0x1ebf0
movslq (%rcx,%rbx,4), %rax
addq %rcx, %rax
movq %r12, %rbp
movq %r14, %r12
movq %r15, %r14
movl %r13d, %r15d
movl 0x28(%rsp), %r13d
jmpq *%rax
cmpl $0x14, %r15d
jge 0xbabe
movslq %r15d, %rcx
movl $0x2, %eax
cmpl $0x0, 0x40(%rsp,%rcx,8)
jne 0xb6b8
leaq 0x2149f(%rip), %rax     # 0x2cb30
leaq 0x8(%rax), %rsi
movq %r12, %rdi
callq 0xaadb
movq %r12, %rdi
callq *0x20(%rsp)
movl %eax, %r13d
cmpl $-0x1, %eax
je 0xb98e
xorl %eax, %eax
testl %r13d, %r13d
sete %al
incl %r15d
movslq %r15d, %rcx
movl %eax, 0x40(%rsp,%rcx,8)
movl $0x1, 0x44(%rsp,%rcx,8)
xorl %r13d, %r13d
jmp 0xb5c3
movq %r14, %rdi
movq 0x10(%rsp), %rsi
movl %r15d, %edx
leaq 0x40(%rsp), %rcx
callq 0x542b
jmp 0xb538
leaq 0x1c0(%rsp), %rbx
movq %rbx, %rdi
leaq 0x136af(%rip), %rsi     # 0x1edad
movq 0x30(%rsp), %rdx
xorl %eax, %eax
callq 0x52f0
movq 0x1c8df(%rip), %rax     # 0x27ff0
movq (%rax), %rdi
movl 0xc(%rsp), %r9d
leaq 0x13590(%rip), %rsi     # 0x1ecb0
leaq 0x21109(%rip), %rdx     # 0x2c830
movq %rbx, %rcx
movq 0x10(%rsp), %r8
xorl %eax, %eax
callq 0x5210
jmp 0xb5cc
movslq %r15d, %rax
cmpl $0x0, 0x44(%rsp,%rax,8)
je 0xb913
movl 0x40(%rsp,%rax,8), %ecx
testl %ecx, %ecx
je 0xb8b7
cmpl $0x1, %ecx
movl 0x1c(%rsp), %edx
jne 0xb8c4
xorl %ecx, %ecx
jmp 0xb8c0
movslq %r15d, %rax
cmpl $0x0, 0x40(%rsp,%rax,8)
jne 0xb782
leaq 0x213b6(%rip), %rax     # 0x2cb30
movq 0x8(%rax), %rdi
callq *0x20(%rsp)
movl 0x1c(%rsp), %ebx
cmpl $0x3, %ebx
jne 0xb79f
leaq 0x2139e(%rip), %rax     # 0x2cb30
movq 0x8(%rax), %rdi
movq 0x10(%rax), %rsi
callq 0xbb51
xorl %r13d, %r13d
cmpl $0x4, %ebx
jmp 0xb5bf
movslq %r15d, %rbx
cmpl $0x0, 0x44(%rsp,%rbx,8)
je 0xb93c
movl 0x40(%rsp,%rbx,8), %eax
xorl %r13d, %r13d
cmpl $0x1, %eax
je 0xb8d7
testl %eax, %eax
jne 0xb5c3
movl $0x2, 0x40(%rsp,%rbx,8)
jmp 0xb5c3
movslq %r15d, %rax
xorl %r13d, %r13d
cmpl $0x0, 0x40(%rsp,%rax,8)
jne 0xb5c3
leaq 0x2133b(%rip), %rdi     # 0x2cb30
movq 0x10(%rsp), %rsi
callq 0xbdcb
cmpl $0x3, %eax
je 0xb9ef
cmpl $0x2, %eax
je 0xb9c6
cmpl $0x1, %eax
jne 0xb5c3
movq 0x1c7cf(%rip), %rax     # 0x27ff0
movq (%rax), %rdi
movl 0xc(%rsp), %r9d
xorl %r13d, %r13d
leaq 0x1347d(%rip), %rsi     # 0x1ecb0
leaq 0x20ff6(%rip), %rdx     # 0x2c830
leaq 0x13537(%rip), %rcx     # 0x1ed78
jmp 0xba16
testl %r15d, %r15d
jle 0xb965
decl %r15d
xorl %r13d, %r13d
cmpl $0x2, 0x1c(%rsp)
jmp 0xb5bf
movslq %r15d, %rax
cmpl $0x0, 0x40(%rsp,%rax,8)
jne 0xb5b7
leaq 0xf0(%rsp), %rdi
movq 0x10(%rsp), %rsi
callq 0xb1df
leaq 0x212aa(%rip), %rcx     # 0x2cb30
movq 0x8(%rcx), %rsi
xorl %edx, %edx
cmpb $0x3f, 0x1b(%rsp)
sete %dl
movq %rax, %rdi
callq 0xbbc0
jmp 0xb5b7
movq %r12, %rbp
movq %r14, %r12
movq %r15, %r14
movl %r13d, %r15d
movl 0x28(%rsp), %r13d
jmp 0xb5c3
movl $0x2, %ecx
movl 0x1c(%rsp), %edx
movl %ecx, 0x40(%rsp,%rax,8)
movl $0x0, 0x44(%rsp,%rax,8)
xorl %r13d, %r13d
cmpl $0x2, %edx
jmp 0xb5bf
leaq 0x21252(%rip), %rax     # 0x2cb30
leaq 0x8(%rax), %rsi
movq %r12, %rdi
callq 0xaadb
movq %r12, %rdi
callq *0x20(%rsp)
movl %eax, %r13d
cmpl $-0x1, %eax
je 0xba27
testl %r13d, %r13d
je 0xb6ca
movl $0x0, 0x40(%rsp,%rbx,8)
jmp 0xb6ca
movq 0x1c6d6(%rip), %rax     # 0x27ff0
movq (%rax), %rdi
movl 0xc(%rsp), %r9d
leaq 0x13387(%rip), %rsi     # 0x1ecb0
leaq 0x20f00(%rip), %rdx     # 0x2c830
leaq 0x133f4(%rip), %rcx     # 0x1ed2b
jmp 0xba16
movq 0x1c6ad(%rip), %rax     # 0x27ff0
movq (%rax), %rdi
movl 0xc(%rsp), %r9d
leaq 0x1335e(%rip), %rsi     # 0x1ecb0
leaq 0x20ed7(%rip), %rdx     # 0x2c830
leaq 0x1339f(%rip), %rcx     # 0x1ecff
jmp 0xba16
movq 0x1c684(%rip), %rax     # 0x27ff0
movq (%rax), %rdi
movl 0xc(%rsp), %r9d
leaq 0x13335(%rip), %rsi     # 0x1ecb0
leaq 0x20eae(%rip), %rdx     # 0x2c830
leaq 0x133b3(%rip), %rcx     # 0x1ed3c
jmp 0xba16
movq 0x1c65b(%rip), %rax     # 0x27ff0
movq (%rax), %rdi
movl 0xc(%rsp), %r9d
xorl %r13d, %r13d
leaq 0x13309(%rip), %rsi     # 0x1ecb0
leaq 0x20e82(%rip), %rdx     # 0x2c830
leaq 0x1335b(%rip), %rcx     # 0x1ed10
movq 0x10(%rsp), %r8
xorl %eax, %eax
callq 0x5210
jmp 0xb6b0
movq 0x1c623(%rip), %rax     # 0x27ff0
movq (%rax), %rdi
movl 0xc(%rsp), %r9d
xorl %r13d, %r13d
leaq 0x132d1(%rip), %rsi     # 0x1ecb0
leaq 0x20e4a(%rip), %rdx     # 0x2c830
leaq 0x13398(%rip), %rcx     # 0x1ed85
jmp 0xba16
movq 0x1c5fa(%rip), %rax     # 0x27ff0
movq (%rax), %rdi
movl 0xc(%rsp), %r9d
xorl %r13d, %r13d
leaq 0x132a8(%rip), %rsi     # 0x1ecb0
leaq 0x20e21(%rip), %rdx     # 0x2c830
leaq 0x13381(%rip), %rcx     # 0x1ed97
movq 0x10(%rsp), %r8
xorl %eax, %eax
callq 0x5210
jmp 0xb5c3
movq 0x1c5c2(%rip), %rax     # 0x27ff0
movq (%rax), %rdi
movl 0xc(%rsp), %r9d
xorl %r13d, %r13d
leaq 0x13270(%rip), %rsi     # 0x1ecb0
leaq 0x20de9(%rip), %rdx     # 0x2c830
leaq 0x132c2(%rip), %rcx     # 0x1ed10
movq 0x10(%rsp), %r8
xorl %eax, %eax
callq 0x5210
jmp 0xb8fd
testl %r15d, %r15d
leaq 0x21b77(%rip), %rbx     # 0x2d5e0
movl 0x2c(%rsp), %ebp
leaq 0x1d222(%rip), %r14     # 0x28c96
movb 0x1a(%rsp), %r15b
jg 0xba98
decl 0x21d9f(%rip)           # 0x2d820
movl %ebp, (%rbx)
movb %r15b, (%r14)
addq $0x288, %rsp            # imm = 0x288
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x1c551(%rip), %rax     # 0x27ff0
movq (%rax), %rdi
leaq 0x13321(%rip), %rsi     # 0x1edca
leaq 0x20d80(%rip), %rdx     # 0x2c830
movq 0x10(%rsp), %rcx
xorl %eax, %eax
callq 0x5210
jmp 0xba7b
leaq 0xc(%rsp), %rdi
movq 0x10(%rsp), %rsi
callq 0x5487
movq 0x10(%rsp), %rdi
callq 0x54bf