// File: /workspace/github_c_makefile_star2_O2/ohkimur[P]the-c-programming-language-2nd-edition-solutions/chapter_1/exercise_1_24/check_syntax.c
// Function: check_syntax
void check_syntax(char str[])
{
  int parentheses = 0;
  int brackets = 0;
  int braces = 0;

  int single_quotes = FALSE;
  int double_quotes = FALSE;

  int block_comment = FALSE;
  int line_comment = FALSE;

  int i = 0;
  while (str[i] != '\0' && parentheses >= 0 && brackets >= 0 && braces >= 0)
  {
    if (!line_comment && !block_comment && !single_quotes && !double_quotes)
    {
      if (str[i] == '(')
      {
        ++parentheses;
      }
      else if (str[i] == ')')
      {
        --parentheses;
      }

      if (str[i] == '[')
      {
        ++brackets;
      }
      else if (str[i] == ']')
      {
        --brackets;
      }

      if (str[i] == '{')
      {
        ++braces;
      }
      else if (str[i] == '}')
      {
        --braces;
      }
    }

    if (!line_comment && !block_comment)
    {
      if (str[i] == '\'' && !single_quotes && !double_quotes)
      {
        single_quotes = TRUE;
      }
      else if (single_quotes && str[i] == '\'' && (str[i - 1] != '\\' || str[i - 2] == '\\'))
      {
        single_quotes = FALSE;
      }

      if (str[i] == '"' && !single_quotes && !double_quotes)
      {
        double_quotes = TRUE;
      }
      else if (double_quotes && str[i] == '"' && (str[i - 1] != '\\' || str[i - 2] == '\\'))
      {
        double_quotes = FALSE;
      }
    }

    if (!single_quotes && !double_quotes)
    {
      if (str[i] == '/' && str[i + 1] == '*' && !line_comment)
      {
        block_comment = TRUE;
      }
      else if (str[i] == '*' && str[i + 1] == '/')
      {
        block_comment = FALSE;
      }

      if (str[i] == '/' && str[i + 1] == '/' && !block_comment)
      {
        line_comment = TRUE;
      }
      else if (str[i] == '\n')
      {
        line_comment = FALSE;
      }
    }

    ++i;
  }

  if (parentheses)
  {
    printf("Error: unbalanced parentheses.\n");
  }

  if (brackets)
  {
    printf("Error: unbalanced brackets.\n");
  }

  if (braces)
  {
    printf("Error: unbalanced braces.\n");
  }

  if (single_quotes)
  {
    printf("Error: unbalanced single quotes.\n");
  }

  if (double_quotes)
  {
    printf("Error: unbalanced double quotes.\n");
  }

  if (block_comment)
  {
    printf("Error: block comment not closed.\n");
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
xorl %eax, %eax
pushq $0x1
popq %rcx
xorl %edx, %edx
xorl %ebp, %ebp
xorl %ebx, %ebx
xorl %r15d, %r15d
xorl %r12d, %r12d
xorl %r14d, %r14d
xorl %esi, %esi
movzbl (%rdi), %r8d
testl %r8d, %r8d
je 0x1381
testl %edx, %edx
js 0x1381
testl %ebp, %ebp
js 0x1381
testl %ebx, %ebx
js 0x1381
movl %esi, %r9d
orl %r14d, %r9d
setne %r9b
testl %r15d, %r15d
jne 0x1254
testb %r9b, %r9b
jne 0x1254
testl %r12d, %r12d
jne 0x1254
cmpl $0x7d, %r8d
je 0x1252
cmpl $0x29, %r8d
je 0x124e
cmpl $0x5b, %r8d
je 0x1242
cmpl $0x5d, %r8d
je 0x124a
cmpl $0x7b, %r8d
je 0x1246
cmpl $0x28, %r8d
jne 0x1254
incl %edx
jmp 0x1254
incl %ebp
jmp 0x1254
incl %ebx
jmp 0x1254
decl %ebp
jmp 0x1254
decl %edx
jmp 0x1254
decl %ebx
testb %r9b, %r9b
jne 0x12ff
testl %r12d, %r12d
sete %r10b
testl %r15d, %r15d
sete %r9b
cmpl $0x27, %r8d
sete %r11b
testl %r15d, %r15d
je 0x1298
movb $0x1, %r9b
cmpl $0x27, %r8d
jne 0x12a4
cmpb $0x5c, -0x1(%rdi)
jne 0x1290
cmpb $0x5c, -0x2(%rdi)
movl %ecx, %r15d
jne 0x12a7
xorl %r9d, %r9d
xorl %r15d, %r15d
jmp 0x12a7
andb %r10b, %r9b
andb %r11b, %r9b
movzbl %r9b, %r15d
jmp 0x12a7
movl %ecx, %r15d
testl %r12d, %r12d
setne %r11b
cmpl $0x22, %r8d
setne %r10b
orb %r11b, %r10b
orb %r9b, %r10b
movl $0x0, %r9d
cmovnel %r15d, %r9d
testl %r12d, %r12d
je 0x12f4
cmpl $0x22, %r8d
jne 0x1349
xorl %r12d, %r12d
cmpb $0x5c, -0x1(%rdi)
jne 0x12ff
xorl %r12d, %r12d
cmpb $0x5c, -0x2(%rdi)
movl %ecx, %r10d
movl $0x0, %r9d
movl $0x0, %r11d
je 0x12ff
jmp 0x1370
xorb $0x1, %r10b
movzbl %r10b, %r12d
movl %r9d, %r15d
movl %r15d, %r9d
orl %r12d, %r9d
je 0x130f
movl %r12d, %r10d
movl %r14d, %r9d
jmp 0x136d
cmpl $0x2a, %r8d
je 0x1354
cmpl $0x2f, %r8d
jne 0x135c
movb 0x1(%rdi), %r10b
cmpb $0x2a, %r10b
movl %ecx, %r9d
cmovnel %r14d, %r9d
testl %esi, %esi
cmovnel %r14d, %r9d
cmpb $0x2f, %r10b
jne 0x135f
testl %r9d, %r9d
jne 0x135f
xorl %r10d, %r10d
xorl %r15d, %r15d
xorl %r9d, %r9d
movl %ecx, %r11d
jmp 0x1370
xorl %r9d, %r9d
movl %ecx, %r10d
xorl %r11d, %r11d
jmp 0x1370
cmpb $0x2f, 0x1(%rdi)
cmovel %eax, %r14d
movl %r14d, %r9d
xorl %r10d, %r10d
cmpl $0xa, %r8d
cmovel %r10d, %esi
xorl %r15d, %r15d
movl %esi, %r11d
incq %rdi
movl %r10d, %r12d
movl %r9d, %r14d
movl %r11d, %esi
jmp 0x11dc
testl %edx, %edx
je 0x1391
leaq 0xc78(%rip), %rdi       # 0x2004
callq 0x1030
testl %ebp, %ebp
je 0x13a1
leaq 0xc87(%rip), %rdi       # 0x2023
callq 0x1030
testl %ebx, %ebx
je 0x13b1
leaq 0xc93(%rip), %rdi       # 0x203f
callq 0x1030
testl %r15d, %r15d
je 0x13c2
leaq 0xc9c(%rip), %rdi       # 0x2059
callq 0x1030
testl %r12d, %r12d
je 0x13d3
leaq 0xcac(%rip), %rdi       # 0x207a
callq 0x1030
testl %r14d, %r14d
je 0x13ec
leaq 0xcbc(%rip), %rdi       # 0x209b
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x1030
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq