// File: /workspace/github_c_makefile_star2_O0/mmayer[P]pcal/src/readfile.c
// Function: parse_rel
int parse_rel (int val, int wkd, char **pword, int *ptype, char ***pptext)
{
   int prep, n, rtn, base_wkd, incr = 1, (*pfcn) (int, int, int);
   date_str *pd;
   
   /* we have the weekday - now look for the preposition */
   if ((prep = get_prep(*pword++)) == PR_OTHER) return PARSE_INVLINE;

   /* get the base date */
   if ((rtn = parse_date(pword, ptype, pptext)) != PARSE_OK) return rtn;

   /* transform 'candidate_dates' array in place - note that the relative date may not
      be in the same month or even year */
   
   if (IS_WILD(wkd)) {   /* wildcard for weekday name? */
      pfcn = pdatefcn[wkd - WILD_FIRST];
      
      for (pd = candidate_dates; pd->mm; pd++) {
         
         /* search for nearest matching date */
         
         switch (prep) {
         case PR_BEFORE:
            pd->dd -= 1;   /* start with previous date */
            normalize(pd);
            /* fall through */
         case PR_ON_BEFORE:
            incr = -1;   /* search backwards */
            break;
            
         case PR_AFTER:
            pd->dd += 1;   /* start with following date */
            normalize(pd);
            /* fall through */
         case PR_ON_AFTER:
            incr = 1;   /* search forward */
            break;
            
         case PR_NEAREST:
            /* If NEAREST_INCR (cf. pcaldefs.h) is 1, pcal will disambiguate
               "nearest" in favor of the later date; if -1, in favor of the
               earlier.  "incr" will take the values 1, -2, 3, -4, ... or -1,
               2, -3, 4 ...  respectively during the search loop below.
              
               ("nearest_before" and "nearest_after" were added to v4.6 to
               allow the user to specify disambiguation of two equally near
               dates.)
            */
            incr = NEAREST_INCR;
            val = 1;   /* ordinals meaningless here */
            break;
            
         case PR_NEAREST_BEFORE:
            incr = -1;   /* start searching backward */
            val = 1;   /* ordinals meaningless here */
            break;

         case PR_NEAREST_AFTER:
            incr = 1;   /* start searching forward */
            val = 1;   /* ordinals meaningless here */
            break;
         }
         
         n = val;
         while (!((*pfcn)(pd->mm, pd->dd, pd->yy) && --n == 0)) {
            pd->dd += incr;
            normalize(pd);
            /* if searching for "nearest" date, invert sign and bump magnitude
               of 'incr' on each pass
            */
            if (prep == PR_NEAREST || prep == PR_NEAREST_BEFORE || prep == PR_NEAREST_AFTER) {
               incr -= (incr > 0) ? (2 * incr + 1) : (2 * incr - 1);
            }
         }
      }

   }
   else  {   /* explicit weekday name */
      for (pd = candidate_dates; pd->mm; pd++) {
         
         /* calculate nearest matching weekday - note that "nearest_before"
           and "nearest_after" are synonyms for "before" and "after"
         */

         base_wkd = calc_weekday(pd->mm, pd->dd, pd->yy);
         switch (prep) {
         case PR_BEFORE:
         case PR_NEAREST_BEFORE:
         case PR_ON_BEFORE:
            if (prep != PR_ON_BEFORE || wkd != base_wkd) pd->dd -= 7 - (wkd - base_wkd + 7) % 7;
            pd->dd -= 7 * (val - 1);
            break;
            
         case PR_AFTER:
         case PR_NEAREST_AFTER:
         case PR_ON_AFTER:
            if (prep != PR_ON_AFTER || wkd != base_wkd) pd->dd += (wkd - base_wkd + 6) % 7 + 1;
            pd->dd += 7 * (val - 1);
            break;
            
         case PR_NEAREST:
            /* use closer of previous and next */
            val = wkd - base_wkd;
            pd->dd += (val > 3) ? (val - 7) : (val < -3) ? (val + 7) : val;
            break;

         case PR_ON:
            /*
              The 'on' preposition is a special case.  When the conditions it
              specifies are not matched, we really need to actually _remove_
              this entry from the 'candidate dates' array.
              
              However, for now, it's easier to just set the 'year' ('yy')
              field in the 'candidate dates' array to -1, as a flag to ignore
              this date entry entirely when later adding events to the big
              linked list based on entries from this 'candidate dates' array.
            */
            if (wkd != base_wkd) {
               pd->yy = -1;  /* invalidate this 'candidate date' entry... */
            }
            break;

         default:
            return PARSE_INVLINE;
            break;
         }
         
         normalize(pd);   /* adjust for month/year crossing */
      }
   }
   
   return PARSE_OK;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movl %edi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movl $0x1, -0x3c(%rbp)
movq -0x18(%rbp), %rax
movq %rax, %rcx
addq $0x8, %rcx
movq %rcx, -0x18(%rbp)
movq (%rax), %rdi
callq 0xff30
movl %eax, -0x2c(%rbp)
cmpl $-0x1, %eax
jne 0x11acc
movl $0x2, -0x4(%rbp)
jmp 0x11de5
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0x10d30
movl %eax, -0x34(%rbp)
cmpl $0x0, %eax
je 0x11af0
movl -0x34(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x11de5
cmpl $0x7, -0xc(%rbp)
jl 0x11c7c
cmpl $0x11, -0xc(%rbp)
jg 0x11c7c
movl -0xc(%rbp), %eax
subl $0x7, %eax
movslq %eax, %rcx
leaq 0x1c6ac(%rip), %rax     # 0x2e1c0
movq (%rax,%rcx,8), %rax
movq %rax, -0x48(%rbp)
leaq 0x223dd(%rip), %rax     # 0x33f00
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
cmpl $0x0, (%rax)
je 0x11c77
movl -0x2c(%rbp), %eax
movq %rax, -0x58(%rbp)
subq $0x6, %rax
ja 0x11bc5
movq -0x58(%rbp), %rax
leaq 0x13294(%rip), %rcx     # 0x24de4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x50(%rbp), %rax
movl 0x4(%rax), %ecx
subl $0x1, %ecx
movl %ecx, 0x4(%rax)
movq -0x50(%rbp), %rdi
callq 0xbb80
movl $0xffffffff, -0x3c(%rbp) # imm = 0xFFFFFFFF
jmp 0x11bc5
movq -0x50(%rbp), %rax
movl 0x4(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x4(%rax)
movq -0x50(%rbp), %rdi
callq 0xbb80
movl $0x1, -0x3c(%rbp)
jmp 0x11bc5
movl $0x1, -0x3c(%rbp)
movl $0x1, -0x8(%rbp)
jmp 0x11bc5
movl $0xffffffff, -0x3c(%rbp) # imm = 0xFFFFFFFF
movl $0x1, -0x8(%rbp)
jmp 0x11bc5
movl $0x1, -0x3c(%rbp)
movl $0x1, -0x8(%rbp)
movl -0x8(%rbp), %eax
movl %eax, -0x30(%rbp)
movq -0x48(%rbp), %rax
movq -0x50(%rbp), %rcx
movl (%rcx), %edi
movq -0x50(%rbp), %rcx
movl 0x4(%rcx), %esi
movq -0x50(%rbp), %rcx
movl 0x8(%rcx), %edx
callq *%rax
movl %eax, %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
movb %al, -0x59(%rbp)
je 0x11c03
movl -0x30(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x30(%rbp)
cmpl $0x0, %eax
sete %al
movb %al, -0x59(%rbp)
movb -0x59(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x11c0e
jmp 0x11c64
movl -0x3c(%rbp), %ecx
movq -0x50(%rbp), %rax
addl 0x4(%rax), %ecx
movl %ecx, 0x4(%rax)
movq -0x50(%rbp), %rdi
callq 0xbb80
cmpl $0x4, -0x2c(%rbp)
je 0x11c36
cmpl $0x5, -0x2c(%rbp)
je 0x11c36
cmpl $0x6, -0x2c(%rbp)
jne 0x11c5f
cmpl $0x0, -0x3c(%rbp)
jle 0x11c49
movl -0x3c(%rbp), %eax
shll %eax
addl $0x1, %eax
movl %eax, -0x60(%rbp)
jmp 0x11c54
movl -0x3c(%rbp), %eax
shll %eax
subl $0x1, %eax
movl %eax, -0x60(%rbp)
movl -0x60(%rbp), %ecx
movl -0x3c(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x3c(%rbp)
jmp 0x11bcb
jmp 0x11c66
movq -0x50(%rbp), %rax
addq $0xc, %rax
movq %rax, -0x50(%rbp)
jmp 0x11b27
jmp 0x11dde
leaq 0x2227d(%rip), %rax     # 0x33f00
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
cmpl $0x0, (%rax)
je 0x11ddc
movq -0x50(%rbp), %rax
movl (%rax), %edi
movl 0x4(%rax), %esi
movl 0x8(%rax), %edx
callq 0xc110
movl %eax, -0x38(%rbp)
movl -0x2c(%rbp), %eax
movq %rax, -0x68(%rbp)
subq $0x7, %rax
ja 0x11db9
movq -0x68(%rbp), %rax
leaq 0x13100(%rip), %rcx     # 0x24dc4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
cmpl $0x1, -0x2c(%rbp)
jne 0x11cdb
movl -0xc(%rbp), %eax
cmpl -0x38(%rbp), %eax
je 0x11d01
movl -0xc(%rbp), %eax
subl -0x38(%rbp), %eax
addl $0x7, %eax
movl $0x7, %ecx
cltd
idivl %ecx
movl %edx, %eax
movl $0x7, %edx
subl %eax, %edx
movq -0x50(%rbp), %rax
movl 0x4(%rax), %ecx
subl %edx, %ecx
movl %ecx, 0x4(%rax)
movl -0x8(%rbp), %eax
subl $0x1, %eax
imull $0x7, %eax, %edx
movq -0x50(%rbp), %rax
movl 0x4(%rax), %ecx
subl %edx, %ecx
movl %ecx, 0x4(%rax)
jmp 0x11dc2
cmpl $0x3, -0x2c(%rbp)
jne 0x11d29
movl -0xc(%rbp), %eax
cmpl -0x38(%rbp), %eax
je 0x11d49
movl -0xc(%rbp), %eax
subl -0x38(%rbp), %eax
addl $0x6, %eax
movl $0x7, %ecx
cltd
idivl %ecx
movl %edx, %ecx
addl $0x1, %ecx
movq -0x50(%rbp), %rax
addl 0x4(%rax), %ecx
movl %ecx, 0x4(%rax)
movl -0x8(%rbp), %eax
subl $0x1, %eax
imull $0x7, %eax, %ecx
movq -0x50(%rbp), %rax
addl 0x4(%rax), %ecx
movl %ecx, 0x4(%rax)
jmp 0x11dc2
movl -0xc(%rbp), %eax
subl -0x38(%rbp), %eax
movl %eax, -0x8(%rbp)
cmpl $0x3, -0x8(%rbp)
jle 0x11d78
movl -0x8(%rbp), %eax
subl $0x7, %eax
movl %eax, -0x6c(%rbp)
jmp 0x11d95
cmpl $-0x3, -0x8(%rbp)
jge 0x11d89
movl -0x8(%rbp), %eax
addl $0x7, %eax
movl %eax, -0x70(%rbp)
jmp 0x11d8f
movl -0x8(%rbp), %eax
movl %eax, -0x70(%rbp)
movl -0x70(%rbp), %eax
movl %eax, -0x6c(%rbp)
movl -0x6c(%rbp), %ecx
movq -0x50(%rbp), %rax
addl 0x4(%rax), %ecx
movl %ecx, 0x4(%rax)
jmp 0x11dc2
movl -0xc(%rbp), %eax
cmpl -0x38(%rbp), %eax
je 0x11db7
movq -0x50(%rbp), %rax
movl $0xffffffff, 0x8(%rax)  # imm = 0xFFFFFFFF
jmp 0x11dc2
movl $0x2, -0x4(%rbp)
jmp 0x11de5
movq -0x50(%rbp), %rdi
callq 0xbb80
movq -0x50(%rbp), %rax
addq $0xc, %rax
movq %rax, -0x50(%rbp)
jmp 0x11c87
jmp 0x11dde
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x70, %rsp
popq %rbp
retq
nop