// File: /workspace/github_c_makefile_star2_O3/haxlang[P]hax/haxParse.c
// Function: HaxParseWords
int
HaxParseWords(
    Hax_Interp *interp,		/* Interpreter to use for nested command
				 * evaluations and error messages. */
    char *string,		/* First character of word. */
    int flags,			/* Flags to control parsing (same values as
				 * passed to Hax_Eval). */
    int maxWords,		/* Maximum number of words to parse. */
    char **termPtr,		/* Store address of terminating character
				 * here. */
    int *argcPtr,		/* Filled in with actual number of words
				 * parsed. */
    char **argv,		/* Store addresses of individual words here. */
    ParseValue *pvPtr		/* Information about where to place
				 * fully-substituted word. */)
{
    char *src, *dst;
    char c;
    int type, result, argc;
    char *oldBuffer;		/* Used to detect when pvPtr's buffer gets
				 * reallocated, so we can adjust all of the
				 * argv pointers. */

    src = string;
    oldBuffer = pvPtr->buffer;
    dst = pvPtr->next;
    for (argc = 0; argc < maxWords; argc++) {
	argv[argc] = dst;

	/*
	 * Skip leading space.
	 */

	skipSpace:
	c = *src;
	type = CHAR_TYPE(c);
	while (type == HAX_SPACE) {
	    src++;
	    c = *src;
	    type = CHAR_TYPE(c);
	}

	/*
	 * Handle the normal case (i.e. no leading double-quote or brace).
	 */

	if (type == HAX_NORMAL) {
	    normalArg:
	    while (1) {
		if (dst == pvPtr->end) {
		    /*
		     * Target buffer space is about to run out.  Make
		     * more space.
		     */

		    pvPtr->next = dst;
		    (*pvPtr->expandProc)(interp, pvPtr, 1);
		    dst = pvPtr->next;
		}

		if (type == HAX_NORMAL) {
		    copy:
		    *dst = c;
		    dst++;
		    src++;
		} else if (type == HAX_SPACE) {
		    goto wordEnd;
		} else if (type == HAX_DOLLAR) {
		    int length;
		    char *value;

		    value = Hax_ParseVar(interp, src, termPtr);
		    if (value == NULL) {
			return HAX_ERROR;
		    }
		    src = *termPtr;
		    length = strlen(value);
		    if ((pvPtr->end - dst) <= length) {
			pvPtr->next = dst;
			(*pvPtr->expandProc)(interp, pvPtr, length);
			dst = pvPtr->next;
		    }
		    strcpy(dst, value);
		    dst += length;
		} else if (type == HAX_COMMAND_END) {
		    if ((c == ']') && !(flags & HAX_BRACKET_TERM)) {
			goto copy;
		    }

		    /*
		     * End of command;  simulate a word-end first, so
		     * that the end-of-command can be processed as the
		     * first thing in a new word.
		     */

		    goto wordEnd;
		} else if (type == HAX_OPEN_BRACKET) {
		    pvPtr->next = dst;
		    result = HaxParseNestedCmd(interp, src+1, flags, termPtr,
			    pvPtr);
		    if (result != HAX_OK) {
			return result;
		    }
		    src = *termPtr;
		    dst = pvPtr->next;
		} else if (type == HAX_BACKSLASH) {
		    int numRead;

		    *dst = Hax_Backslash(src, &numRead);
		    if (*dst != 0) {
			dst++;
		    }
		    src += numRead;
		} else {
		    goto copy;
		}
		c = *src;
		type = CHAR_TYPE(c);
	    }
	} else {

	    /*
	     * Check for the end of the command.
	     */

	    if (type == HAX_COMMAND_END) {
		if (flags & HAX_BRACKET_TERM) {
		    if (c == '\0') {
			Hax_SetResult(interp, (char *) "missing close-bracket",
				HAX_STATIC);
			return HAX_ERROR;
		    }
		} else {
		    if (c == ']') {
			goto normalArg;
		    }
		}
		goto done;
	    }

	    /*
	     * Now handle the special cases: open braces, double-quotes,
	     * and backslash-newline.
	     */

	    pvPtr->next = dst;
	    if (type == HAX_QUOTE) {
		result = HaxParseQuotes(interp, src+1, '"', flags,
			termPtr, pvPtr);
	    } else if (type == HAX_OPEN_BRACE) {
		result = HaxParseBraces(interp, src+1, termPtr, pvPtr);
	    } else if ((type == HAX_BACKSLASH) && (src[1] == '\n')) {
		src += 2;
		goto skipSpace;
	    } else {
		goto normalArg;
	    }
	    if (result != HAX_OK) {
		return result;
	    }

	    /*
	     * Back from quotes or braces;  make sure that the terminating
	     * character was the end of the word.  Have to be careful here
	     * to handle continuation lines (i.e. lines ending in backslash).
	     */

	    c = **termPtr;
	    if ((c == '\\') && ((*termPtr)[1] == '\n')) {
		c = (*termPtr)[2];
	    }
	    type = CHAR_TYPE(c);
	    if ((type != HAX_SPACE) && (type != HAX_COMMAND_END)) {
		if (*src == '"') {
		    Hax_SetResult(interp,
			    (char *) "extra characters after close-quote",
			    HAX_STATIC);
		} else {
		    Hax_SetResult(interp,
			    (char *) "extra characters after close-brace",
			    HAX_STATIC);
		}
		return HAX_ERROR;
	    }
	    src = *termPtr;
	    dst = pvPtr->next;

	}

	/*
	 * We're at the end of a word, so add a null terminator.  Then
	 * see if the buffer was re-allocated during this word.  If so,
	 * update all of the argv pointers.
	 */

	wordEnd:
	*dst = '\0';
	dst++;
	if (oldBuffer != pvPtr->buffer) {
	    int i;

	    for (i = 0; i <= argc; i++) {
		argv[i] = pvPtr->buffer + (argv[i] - oldBuffer);
	    }
	    oldBuffer = pvPtr->buffer;
	}
    }

    done:
    pvPtr->next = dst;
    *termPtr = src;
    *argcPtr = argc;
    return HAX_OK;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %r8, 0x18(%rsp)
movl %edx, 0xc(%rsp)
movq %rdi, (%rsp)
movq 0x88(%rsp), %r12
movq 0x8(%r12), %rbp
xorl %edx, %edx
testl %ecx, %ecx
jle 0xfbaa
movq %r9, 0x20(%rsp)
movq 0x80(%rsp), %rdi
movq (%r12), %r8
movl %ecx, 0x28(%rsp)
movl %ecx, %eax
movq %rax, 0x30(%rsp)
movl $0x1, %r9d
xorl %edx, %edx
leaq 0x6523(%rip), %r14      # 0x15e44
movq %r9, 0x38(%rsp)
movq %r8, 0x40(%rsp)
movq %rdx, 0x10(%rsp)
movq %rbp, (%rdi,%rdx,8)
movq %rsi, %rbx
movsbq (%rbx), %r13
movq 0xb66e(%rip), %rax      # 0x1afb0
movzbl 0x80(%rax,%r13), %r15d
cmpl $0x1, %r15d
je 0xf973
testl %r15d, %r15d
je 0xf9c0
cmpl $0x2, %r15d
je 0xf9ab
movq %rbp, 0x8(%r12)
cmpl $0x7, %r15d
jne 0xf978
cmpb $0xa, 0x1(%rbx)
jne 0xf9c0
addq $0x2, %rbx
jmp 0xf937
incq %rbx
jmp 0xf937
cmpl $0x5, %r15d
je 0xfaf5
cmpl $0x3, %r15d
jne 0xf9c0
leaq 0x1(%rbx), %rsi
movq (%rsp), %rdi
movl $0x22, %edx
movl 0xc(%rsp), %ecx
movq 0x18(%rsp), %r8
movq %r12, %r9
callq 0x4480
jmp 0xfb0a
testb $0x1, 0xc(%rsp)
jne 0xfbcf
cmpb $0x5d, %r13b
jne 0xfbe7
cmpq 0x10(%r12), %rbp
jne 0xf9e2
movq %rbp, 0x8(%r12)
movq (%rsp), %rdi
movq %r12, %rsi
movl $0x1, %edx
callq *0x18(%r12)
movq 0x8(%r12), %rbp
movzbl %r15b, %eax
decl %eax
cmpl $0x7, %eax
ja 0xfa0b
movslq (%r14,%rax,4), %rax
addq %r14, %rax
jmpq *%rax
testb $0x1, 0xc(%rsp)
jne 0xfaeb
cmpb $0x5d, %r13b
jne 0xfaeb
movb %r13b, (%rbp)
incq %rbp
incq %rbx
jmp 0xfad3
movq %rbp, 0x8(%r12)
incq %rbx
movq (%rsp), %rdi
movq %rbx, %rsi
movl 0xc(%rsp), %edx
movq 0x18(%rsp), %rbx
movq %rbx, %rcx
movq %r12, %r8
callq 0x4630
testl %eax, %eax
jne 0xfc0a
movq (%rbx), %rbx
movq 0x8(%r12), %rbp
jmp 0xfad3
movq (%rsp), %rdi
movq %rbx, %rsi
movq 0x18(%rsp), %rbx
movq %rbx, %rdx
callq 0x4400
testq %rax, %rax
je 0xfc05
movq %rax, %r13
movq (%rbx), %rbx
movq %rax, %rdi
callq 0x41d0
movq 0x10(%r12), %rcx
subq %rbp, %rcx
movslq %eax, %r15
cmpq %r15, %rcx
jg 0xfaa5
movq %rbp, 0x8(%r12)
movq (%rsp), %rdi
movq %r12, %rsi
movl %eax, %edx
callq *0x18(%r12)
movq 0x8(%r12), %rbp
movq %rbp, %rdi
movq %r13, %rsi
callq 0x40f0
addq %r15, %rbp
jmp 0xfad3
movq %rbx, %rdi
leaq 0x2c(%rsp), %rsi
callq 0x42c0
movb %al, (%rbp)
cmpb $0x1, %al
sbbq $-0x1, %rbp
movslq 0x2c(%rsp), %rax
addq %rax, %rbx
movsbq (%rbx), %r13
movq 0xb4d2(%rip), %rax      # 0x1afb0
movb 0x80(%rax,%r13), %r15b
jmp 0xf9c0
movq %rbx, %rsi
movq 0x10(%rsp), %rdx
jmp 0xfb4d
leaq 0x1(%rbx), %rsi
movq (%rsp), %rdi
movq 0x18(%rsp), %rdx
movq %r12, %rcx
callq 0x45d0
testl %eax, %eax
movq 0x10(%rsp), %rdx
jne 0xfc0a
movq 0x18(%rsp), %rax
movq (%rax), %rsi
movb (%rsi), %al
cmpb $0x5c, %al
jne 0xfb30
movb $0x5c, %al
cmpb $0xa, 0x1(%rsi)
jne 0xfb30
movb 0x2(%rsi), %al
movsbq %al, %rax
movq 0xb475(%rip), %rcx      # 0x1afb0
movb 0x80(%rcx,%rax), %al
addb $-0x3, %al
cmpb $-0x3, %al
jbe 0xfbc1
movq 0x8(%r12), %rbp
movb $0x0, (%rbp)
movq 0x40(%rsp), %r8
cmpq (%r12), %r8
movq 0x80(%rsp), %rdi
movq 0x38(%rsp), %r9
je 0xfb86
xorl %eax, %eax
movq (%rdi,%rax,8), %rcx
subq %r8, %rcx
addq (%r12), %rcx
movq %rcx, (%rdi,%rax,8)
incq %rax
cmpq %rax, %r9
jne 0xfb6b
movq (%r12), %r8
incq %rbp
incq %rdx
incq %r9
cmpq 0x30(%rsp), %rdx
jne 0xf921
movl 0x28(%rsp), %eax
movl %eax, %edx
movq %rsi, %rbx
movq 0x20(%rsp), %r9
jmp 0xfbad
movq %rsi, %rbx
movq %rbp, 0x8(%r12)
movq 0x18(%rsp), %rax
movq %rbx, (%rax)
movl %edx, (%r9)
xorl %eax, %eax
jmp 0xfc0a
cmpb $0x22, (%rbx)
jne 0xfbf3
leaq 0x62d7(%rip), %rsi      # 0x15ea4
jmp 0xfbfa
testb %r13b, %r13b
movq 0x20(%rsp), %r9
movq 0x10(%rsp), %rdx
jne 0xfbad
leaq 0x62a9(%rip), %rsi      # 0x15e8e
jmp 0xfbfa
movq 0x20(%rsp), %r9
movq 0x10(%rsp), %rdx
jmp 0xfbad
leaq 0x62cd(%rip), %rsi      # 0x15ec7
movq (%rsp), %rdi
xorl %edx, %edx
callq 0x44f0
movl $0x1, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq