// File: arnoldrobbins[P]mcilroy-regex/re2.cpp
// Function: special(regex_t*, Cenv*)
static int
special(regex_t *preg, Cenv *env)
{
	Rex* kmp;
	Rex* rex = preg->rex;
	String *string;
	if(rex == ERROR)
		return 0;
	switch(rex->type) {
	case SUBEXP:
		for(;;) {
			rex = ((Subexp*)rex)->rex;
			switch(rex->type) {
			case SUBEXP:
				continue;
			case DOT:
				goto dot;
			case ANCHOR:
				goto anchor;
			default:
				return 0;
			}
		}
	dot:
	case DOT:			// .*
		if(((Dot*)rex)->lo==0 && ((Dot*)rex)->hi==RE_DUP_INF)
			return ONCE;
		return 0;
	case OK:			// empty regexp
		if(env->flags & REG_NULL)
			return ONCE;
		regfree(preg);
		return 0;
	case STRING:
		if(env->flags & (REG_ANCH | REG_LITERAL))
			return 0;
		string = (String*)rex;
		kmp = NEW(Kmp(string->seg, &env->flags));
		if(kmp==ERROR || env->flags&SPACE) 
			return 0;
		kmp->next = rex->next;
		preg->rex = kmp;
		string->seg = Seg(0,0);
		string->next = 0;
		delete string;
		return ONCE;
	anchor:
	case ANCHOR: 
		if(!(env->flags & REG_NEWLINE))
			return ONCE;
	}
	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpq 0xa486(%rip), %rax      # 0x18510
jne 0xe098
movl $0x0, -0x4(%rbp)
jmp 0xe2a6
movq -0x28(%rbp), %rax
movzbl 0x8(%rax), %eax
movq %rax, -0x68(%rbp)
subq $0x9, %rax
ja 0xe29f
movq -0x68(%rbp), %rax
leaq 0x35db(%rip), %rcx      # 0x11694
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
jmp 0xe0c4
movq -0x28(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movzbl 0x8(%rax), %eax
movl %eax, -0x6c(%rbp)
subl $0x1, %eax
je 0xe0fa
jmp 0xe0e2
movl -0x6c(%rbp), %eax
subl $0x3, %eax
je 0xe0f8
jmp 0xe0ec
movl -0x6c(%rbp), %eax
subl $0x9, %eax
jne 0xe0ff
jmp 0xe0f6
jmp 0xe0c4
jmp 0xe10b
jmp 0xe284
movl $0x0, -0x4(%rbp)
jmp 0xe2a6
jmp 0xe10d
movq -0x28(%rbp), %rax
cmpl $0x0, 0x18(%rax)
jne 0xe130
movq -0x28(%rbp), %rax
cmpl $0x40000000, 0x1c(%rax) # imm = 0x40000000
jne 0xe130
movl $0x1000, -0x4(%rbp)     # imm = 0x1000
jmp 0xe2a6
movl $0x0, -0x4(%rbp)
jmp 0xe2a6
movq -0x18(%rbp), %rax
movl (%rax), %eax
andl $0x40, %eax
cmpl $0x0, %eax
je 0xe156
movl $0x1000, -0x4(%rbp)     # imm = 0x1000
jmp 0xe2a6
movq -0x10(%rbp), %rdi
callq 0xe2c0
movl $0x0, -0x4(%rbp)
jmp 0xe2a6
movq -0x18(%rbp), %rax
movl (%rax), %eax
andl $0x180, %eax            # imm = 0x180
cmpl $0x0, %eax
je 0xe187
movl $0x0, -0x4(%rbp)
jmp 0xe2a6
movq -0x28(%rbp), %rax
movq %rax, -0x30(%rbp)
movl $0x88, %edi
callq 0x51a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x78(%rbp)
movq -0x30(%rbp), %rax
movups 0x18(%rax), %xmm0
movaps %xmm0, -0x40(%rbp)
movq -0x18(%rbp), %rcx
movq -0x40(%rbp), %rsi
movl -0x38(%rbp), %edx
callq 0x9d10
jmp 0xe1c1
movq -0x78(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0xd030
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpq 0xa333(%rip), %rax      # 0x18510
je 0xe1ef
movq -0x18(%rbp), %rax
movl (%rax), %eax
andl $0x400, %eax            # imm = 0x400
cmpl $0x0, %eax
je 0xe21a
movl $0x0, -0x4(%rbp)
jmp 0xe2a6
movq -0x78(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
movl $0x88, %esi
callq 0x51b0
jmp 0xe2b2
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x20(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x8(%rax)
leaq -0x60(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0xbd40
movq -0x30(%rbp), %rax
movq -0x60(%rbp), %rcx
movq %rcx, 0x18(%rax)
movl -0x58(%rbp), %ecx
movl %ecx, 0x20(%rax)
movq -0x30(%rbp), %rax
movq $0x0, 0x10(%rax)
movq -0x30(%rbp), %rax
movq %rax, -0x80(%rbp)
cmpq $0x0, %rax
je 0xe27b
movq -0x80(%rbp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movl $0x1000, -0x4(%rbp)     # imm = 0x1000
jmp 0xe2a6
jmp 0xe286
movq -0x18(%rbp), %rax
movl (%rax), %eax
andl $0x8, %eax
cmpl $0x0, %eax
jne 0xe29d
movl $0x1000, -0x4(%rbp)     # imm = 0x1000
jmp 0xe2a6
jmp 0xe29f
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x80, %rsp
popq %rbp
retq
movq -0x48(%rbp), %rdi
callq 0x52d0
nopl (%rax,%rax)