// File: /workspace/github_c_makefile_star2_O0/lucvoo[P]sparse-dev/pre-process.c
// Function: substitute
static struct token **substitute(struct token **list, struct token *body, struct arg *args)
{
	struct position *base_pos = &(*list)->pos;
	int *count;
	enum {Normal, Placeholder, Concat} state = Normal;

	for (; !eof_token(body); body = body->next) {
		struct token *added, *arg;
		struct token **tail;
		struct token *t;

		switch (token_type(body)) {
		case TOKEN_GNU_KLUDGE:
			/*
			 * GNU kludge: if we had <comma>##<vararg>, behaviour
			 * depends on whether we had enough arguments to have
			 * a vararg.  If we did, ## is just ignored.  Otherwise
			 * both , and ## are ignored.  Worse, there can be
			 * an arbitrary number of ##<arg> in between; if all of
			 * those are empty, we act as if they hadn't been there,
			 * otherwise we act as if the kludge didn't exist.
			 */
			t = body;
			if (handle_kludge(&body, args)) {
				if (state == Concat)
					state = Normal;
				else
					state = Placeholder;
				continue;
			}
			added = dup_token(t, base_pos);
			token_type(added) = TOKEN_SPECIAL;
			tail = &added->next;
			break;

		case TOKEN_STR_ARGUMENT:
			arg = args[body->argnum].str;
			count = &args[body->argnum].n_str;
			goto copy_arg;

		case TOKEN_QUOTED_ARGUMENT:
			arg = args[body->argnum].arg;
			count = &args[body->argnum].n_quoted;
			if (!arg || eof_token(arg)) {
				if (state == Concat)
					state = Normal;
				else
					state = Placeholder;
				continue;
			}
			goto copy_arg;

		case TOKEN_MACRO_ARGUMENT:
			arg = args[body->argnum].expanded;
			count = &args[body->argnum].n_normal;
			if (eof_token(arg)) {
				state = Normal;
				continue;
			}
		copy_arg:
			tail = copy(&added, arg, count);
			added->pos.newline = body->pos.newline;
			added->pos.whitespace = body->pos.whitespace;
			break;

		case TOKEN_CONCAT:
			if (state == Placeholder)
				state = Normal;
			else
				state = Concat;
			continue;

		case TOKEN_IDENT:
			added = dup_token(body, base_pos);
			if (added->ident->tainted)
				added->pos.noexpand = 1;
			tail = &added->next;
			break;

		default:
			added = dup_token(body, base_pos);
			tail = &added->next;
			break;
		}

		/*
		 * if we got to doing real concatenation, we already have
		 * added something into the list, so containing_token() is OK.
		 */
		if (state == Concat && merge(containing_token(list), added)) {
			*list = added->next;
			if (tail != &added->next)
				list = tail;
		} else {
			*list = added;
			list = tail;
		}
		state = Normal;
	}
	*list = &eof_token_entry;
	return list;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x20(%rbp)
movl $0x0, -0x2c(%rbp)
leaq 0x7d5e3(%rip), %rax     # 0xac9c0
cmpq %rax, -0x10(%rbp)
sete %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x2f3ef
jmp 0x2f6f3
movq -0x10(%rbp), %rax
movl (%rax), %eax
andl $0x3f, %eax
addl $-0x3, %eax
movl %eax, %ecx
movq %rcx, -0x58(%rbp)
subl $0x16, %eax
ja 0x2f661
movq -0x58(%rbp), %rax
leaq 0x382eb(%rip), %rcx     # 0x67700
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x10(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x18(%rbp), %rsi
leaq -0x10(%rbp), %rdi
callq 0x2fdd0
cmpl $0x0, %eax
je 0x2f453
cmpl $0x2, -0x2c(%rbp)
jne 0x2f447
movl $0x0, -0x2c(%rbp)
jmp 0x2f44e
movl $0x1, -0x2c(%rbp)
jmp 0x2f6e2
movq -0x50(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x2fe90
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq (%rax), %rcx
andq $-0x40, %rcx
orq $0x12, %rcx
movq %rcx, (%rax)
movq -0x38(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x48(%rbp)
jmp 0x2f67e
movq -0x18(%rbp), %rax
movq -0x10(%rbp), %rcx
movslq 0x10(%rcx), %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x18(%rbp), %rax
movq -0x10(%rbp), %rcx
movslq 0x10(%rcx), %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
addq $0x20, %rax
movq %rax, -0x28(%rbp)
jmp 0x2f579
movq -0x18(%rbp), %rax
movq -0x10(%rbp), %rcx
movslq 0x10(%rcx), %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movq (%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x18(%rbp), %rax
movq -0x10(%rbp), %rcx
movslq 0x10(%rcx), %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
addq $0x1c, %rax
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x40(%rbp)
je 0x2f50b
leaq 0x7d4bb(%rip), %rax     # 0xac9c0
cmpq %rax, -0x40(%rbp)
jne 0x2f526
cmpl $0x2, -0x2c(%rbp)
jne 0x2f51a
movl $0x0, -0x2c(%rbp)
jmp 0x2f521
movl $0x1, -0x2c(%rbp)
jmp 0x2f6e2
jmp 0x2f579
movq -0x18(%rbp), %rax
movq -0x10(%rbp), %rcx
movslq 0x10(%rcx), %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x18(%rbp), %rax
movq -0x10(%rbp), %rcx
movslq 0x10(%rcx), %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
addq $0x18, %rax
movq %rax, -0x28(%rbp)
leaq 0x7d45b(%rip), %rax     # 0xac9c0
cmpq %rax, -0x40(%rbp)
jne 0x2f577
movl $0x0, -0x2c(%rbp)
jmp 0x2f6e2
jmp 0x2f579
movq -0x40(%rbp), %rsi
movq -0x28(%rbp), %rdx
leaq -0x38(%rbp), %rdi
callq 0x2ff90
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
shrq $0x14, %rax
andq $0x1, %rax
movl %eax, %ecx
movq -0x38(%rbp), %rax
movl %ecx, %ecx
movl %ecx, %edx
movq (%rax), %rcx
andq $0x1, %rdx
shlq $0x14, %rdx
andq $-0x100001, %rcx        # imm = 0xFFEFFFFF
orq %rdx, %rcx
movq %rcx, (%rax)
movq -0x10(%rbp), %rax
movq (%rax), %rax
shrq $0x15, %rax
andq $0x1, %rax
movl %eax, %ecx
movq -0x38(%rbp), %rax
movl %ecx, %ecx
movl %ecx, %edx
movq (%rax), %rcx
andq $0x1, %rdx
shlq $0x15, %rdx
andq $-0x200001, %rcx        # imm = 0xFFDFFFFF
orq %rdx, %rcx
movq %rcx, (%rax)
jmp 0x2f67e
cmpl $0x1, -0x2c(%rbp)
jne 0x2f604
movl $0x0, -0x2c(%rbp)
jmp 0x2f60b
movl $0x2, -0x2c(%rbp)
jmp 0x2f6e2
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x2fe90
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
movb 0x11(%rax), %al
andb $0x1, %al
cmpb $0x0, %al
je 0x2f653
movq -0x38(%rbp), %rax
movabsq $0x7fffffffffffffff, %rcx # imm = 0x7FFFFFFFFFFFFFFF
andq (%rax), %rcx
movabsq $-0x8000000000000000, %rdx # imm = 0x8000000000000000
orq %rdx, %rcx
movq %rcx, (%rax)
movq -0x38(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x48(%rbp)
jmp 0x2f67e
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x2fe90
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x48(%rbp)
cmpl $0x2, -0x2c(%rbp)
jne 0x2f6c8
movq -0x8(%rbp), %rdi
callq 0x30290
movq %rax, %rdi
movq -0x38(%rbp), %rsi
callq 0x30080
cmpl $0x0, %eax
je 0x2f6c8
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rcx
movq -0x8(%rbp), %rax
movq %rcx, (%rax)
movq -0x48(%rbp), %rax
movq -0x38(%rbp), %rcx
addq $0x8, %rcx
cmpq %rcx, %rax
je 0x2f6c6
movq -0x48(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x2f6db
movq -0x38(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, (%rax)
movq -0x48(%rbp), %rax
movq %rax, -0x8(%rbp)
movl $0x0, -0x2c(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x10(%rbp)
jmp 0x2f3d6
movq -0x8(%rbp), %rax
leaq 0x7d2c2(%rip), %rcx     # 0xac9c0
movq %rcx, (%rax)
movq -0x8(%rbp), %rax
addq $0x60, %rsp
popq %rbp
retq
nopl (%rax,%rax)