// File: /workspace/github_c_makefile_star2_O0/mati75[P]evilwm/bind.c
// Function: bind_control
void bind_control(const char *ctlname, const char *func) {
	// Parse control string
	char *ctldup = xstrdup(ctlname);
	if (!ctldup)
		return;
	struct bind *newbind = xmalloc(sizeof(*newbind));
	*newbind = (struct bind){0};

	for (char *tmp = strtok(ctldup, ",+"); tmp; tmp = strtok(NULL, ",+")) {
		// is this a modifier?
		struct name_to_modifier *m = modifier_by_name(tmp);
		if (m) {
			newbind->state |= m->value;
			continue;
		}

		// only consider first key or button listed
		if (newbind->type)
			continue;

		// maybe it's a button?
		unsigned b = button_by_name(tmp);
		if (b) {
			newbind->type = ButtonPress;
			newbind->control.button = b;
			continue;
		}

		// ok, see if it's recognised as a key name
		KeySym k = XStringToKeysym(tmp);
		if (k != NoSymbol) {
			newbind->type = KeyPress;
			newbind->control.key = k;
			continue;
		}
	}
	free(ctldup);

	// No known control type?  Abort.
	if (!newbind->type) {
		free(newbind);
		return;
	}

	// always unbind any existing matching control
	for (struct list *l = controls; l; l = l->next) {
		struct bind *b = l->data;
		if (newbind->type == KeyPress && b->state == newbind->state && b->control.key == newbind->control.key) {
			controls = list_delete(controls, b);
			free(b);
			break;
		}
		if (newbind->type == ButtonPress && b->state == newbind->state && b->control.button == newbind->control.button) {
			controls = list_delete(controls, b);
			free(b);
			break;
		}
	}

	// empty function definition implies unbind.  already done, so return.
	if (!func || *func == 0) {
		free(newbind);
		return;
	}

	// parse the second string for function & flags

	char *funcdup = xstrdup(func);
	if (!funcdup)
		return;

	for (char *tmp = strtok(funcdup, ",+"); tmp; tmp = strtok(NULL, ",+")) {
		// function name?
		struct function_def *fn = func_by_name(tmp);
		if (fn) {
			newbind->func = fn->func;
			newbind->flags = fn->flags;
			continue;
		}

		// a simple number?
		if (*tmp >= '0' && *tmp <= '9') {
			newbind->flags &= ~FL_VALUEMASK;
			newbind->flags |= strtol(tmp, NULL, 0) & FL_VALUEMASK;
			continue;
		}

		// treat it as a flag name then
		newbind->flags |= flags_by_name(tmp);
	}

	if (newbind->func) {
		controls = list_prepend(controls, newbind);
	} else {
		free(newbind);
	}

	free(funcdup);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
callq 0xd9c0
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0x497c
jmp 0x4ccb
movl $0x28, %edi
callq 0xd890
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x98(%rbp)
leaq -0x48(%rbp), %rdi
xorl %esi, %esi
movl $0x28, %edx
callq 0x4080
movq -0x98(%rbp), %rdi
leaq -0x48(%rbp), %rsi
movl $0x28, %edx
callq 0x4750
movq -0x18(%rbp), %rdi
leaq 0x9683(%rip), %rsi      # 0xe048
callq 0x4590
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x50(%rbp)
je 0x4a7a
movq -0x50(%rbp), %rdi
callq 0x4dc0
movq %rax, -0x58(%rbp)
cmpq $0x0, -0x58(%rbp)
je 0x4a00
movq -0x58(%rbp), %rax
movl 0x8(%rax), %ecx
movq -0x20(%rbp), %rax
orl 0x10(%rax), %ecx
movl %ecx, 0x10(%rax)
jmp 0x4a61
movq -0x20(%rbp), %rax
cmpl $0x0, (%rax)
je 0x4a0b
jmp 0x4a61
movq -0x50(%rbp), %rdi
callq 0x4e40
movl %eax, -0x5c(%rbp)
cmpl $0x0, -0x5c(%rbp)
je 0x4a33
movq -0x20(%rbp), %rax
movl $0x4, (%rax)
movl -0x5c(%rbp), %ecx
movq -0x20(%rbp), %rax
movl %ecx, 0x8(%rax)
jmp 0x4a61
movq -0x50(%rbp), %rdi
callq 0x40c0
movq %rax, -0x68(%rbp)
cmpq $0x0, -0x68(%rbp)
je 0x4a5f
movq -0x20(%rbp), %rax
movl $0x2, (%rax)
movq -0x68(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x8(%rax)
jmp 0x4a61
jmp 0x4a61
xorl %eax, %eax
movl %eax, %edi
leaq 0x95dc(%rip), %rsi      # 0xe048
callq 0x4590
movq %rax, -0x50(%rbp)
jmp 0x49ce
movq -0x18(%rbp), %rdi
callq 0x42e0
movq -0x20(%rbp), %rax
cmpl $0x0, (%rax)
jne 0x4a9a
movq -0x20(%rbp), %rdi
callq 0x42e0
jmp 0x4ccb
movq 0xe2b7(%rip), %rax      # 0x12d58
movq %rax, -0x70(%rbp)
cmpq $0x0, -0x70(%rbp)
je 0x4b66
movq -0x70(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x78(%rbp)
movq -0x20(%rbp), %rax
cmpl $0x2, (%rax)
jne 0x4b09
movq -0x78(%rbp), %rax
movl 0x10(%rax), %eax
movq -0x20(%rbp), %rcx
cmpl 0x10(%rcx), %eax
jne 0x4b09
movq -0x78(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x20(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jne 0x4b09
movq 0xe26a(%rip), %rdi      # 0x12d58
movq -0x78(%rbp), %rsi
callq 0xaf90
movq %rax, 0xe25a(%rip)      # 0x12d58
movq -0x78(%rbp), %rdi
callq 0x42e0
jmp 0x4b66
movq -0x20(%rbp), %rax
cmpl $0x4, (%rax)
jne 0x4b54
movq -0x78(%rbp), %rax
movl 0x10(%rax), %eax
movq -0x20(%rbp), %rcx
cmpl 0x10(%rcx), %eax
jne 0x4b54
movq -0x78(%rbp), %rax
movl 0x8(%rax), %eax
movq -0x20(%rbp), %rcx
cmpl 0x8(%rcx), %eax
jne 0x4b54
movq 0xe21f(%rip), %rdi      # 0x12d58
movq -0x78(%rbp), %rsi
callq 0xaf90
movq %rax, 0xe20f(%rip)      # 0x12d58
movq -0x78(%rbp), %rdi
callq 0x42e0
jmp 0x4b66
jmp 0x4b56
movq -0x70(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x70(%rbp)
jmp 0x4aa5
cmpq $0x0, -0x10(%rbp)
je 0x4b79
movq -0x10(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x0, %eax
jne 0x4b87
movq -0x20(%rbp), %rdi
callq 0x42e0
jmp 0x4ccb
movq -0x10(%rbp), %rdi
callq 0xd9c0
movq %rax, -0x80(%rbp)
cmpq $0x0, -0x80(%rbp)
jne 0x4ba0
jmp 0x4ccb
movq -0x80(%rbp), %rdi
leaq 0x949d(%rip), %rsi      # 0xe048
callq 0x4590
movq %rax, -0x88(%rbp)
cmpq $0x0, -0x88(%rbp)
je 0x4c95
movq -0x88(%rbp), %rdi
callq 0x4ec0
movq %rax, -0x90(%rbp)
cmpq $0x0, -0x90(%rbp)
je 0x4c08
movq -0x90(%rbp), %rax
movq 0x8(%rax), %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x90(%rbp), %rax
movl 0x10(%rax), %ecx
movq -0x20(%rbp), %rax
movl %ecx, 0x20(%rax)
jmp 0x4c79
movq -0x88(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x30, %eax
jl 0x4c61
movq -0x88(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x39, %eax
jg 0x4c61
movq -0x20(%rbp), %rax
movl 0x20(%rax), %ecx
andl $0xffffff00, %ecx       # imm = 0xFFFFFF00
movl %ecx, 0x20(%rax)
movq -0x88(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x4430
movq %rax, %rdx
andq $0xff, %rdx
movq -0x20(%rbp), %rax
movl 0x20(%rax), %ecx
orq %rdx, %rcx
movl %ecx, 0x20(%rax)
jmp 0x4c79
movq -0x88(%rbp), %rdi
callq 0x4f40
movl %eax, %ecx
movq -0x20(%rbp), %rax
orl 0x20(%rax), %ecx
movl %ecx, 0x20(%rax)
xorl %eax, %eax
movl %eax, %edi
leaq 0x93c4(%rip), %rsi      # 0xe048
callq 0x4590
movq %rax, -0x88(%rbp)
jmp 0x4bb7
movq -0x20(%rbp), %rax
cmpq $0x0, 0x18(%rax)
je 0x4cb9
movq 0xe0b1(%rip), %rdi      # 0x12d58
movq -0x20(%rbp), %rsi
callq 0xaf30
movq %rax, 0xe0a1(%rip)      # 0x12d58
jmp 0x4cc2
movq -0x20(%rbp), %rdi
callq 0x42e0
movq -0x80(%rbp), %rdi
callq 0x42e0
addq $0xa0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)