+ /*
+ * The function isn't an internal one. Determine the name and
+ * amount of arguments the function accepts by searching for
+ * the `#` (pound sign).
+ */
+ int args = 0;
+ int size = 0;
+ char *find = strchr(name, '#');
+ char *peek = find;
+
+ /*
+ * Code structures for filling after determining the correct
+ * information to add to the code write system.
+ */
+ prog_section_function function;
+ prog_section_def def;
+ memset(&function, 0, sizeof(prog_section_function));
+ memset(&def, 0, sizeof(prog_section_def));
+ if (find) {
+ find ++;
+
+ /* skip whitespace */
+ if (*find == ' ' || *find == '\t')
+ find++;
+
+ /*
+ * If the input is larger than eight, it's considered
+ * invalid and shouldn't be allowed. The QuakeC VM only
+ * allows a maximum of eight arguments.
+ */
+ if (*find == '9') {
+ printf("invalid number of arguments, must be a valid number from 0-8\n");
+ mem_d(copy);
+ mem_d(name);
+ return false;
+ }
+
+ if (*find != '0') {
+ /*
+ * if we made it this far we have a valid number for the
+ * argument count, so fall through a switch statement and
+ * do it.
+ */
+ switch (*find) {
+ case '8': args++; case '7': args++;
+ case '6': args++; case '5': args++;
+ case '4': args++; case '3': args++;
+ case '2': args++; case '1': args++;
+ }
+ }
+ /*
+ * We need to parse the argument size now by determining
+ * the argument identifer list used after the amount of
+ * arguments.
+ */
+ memset(function.argsize, 0, sizeof(function.argsize));
+ find ++; /* skip the number */
+ while (*find == ' ' || *find == '\t') find++;
+ while (size < args) {
+ switch (*find) {
+ case 'V': case 'v': function.argsize[size]=3; break;
+ case 'S': case 's':
+ case 'F': case 'f':
+ case 'E': case 'e': function.argsize[size]=1; break;
+ case '\0':
+ printf("missing argument identifer, expected %d\n", args);
+ return false;
+ default:
+ printf("error invalid function argument identifier\n");
+ return false;
+ }
+ size++,find++;
+ }
+ while (*find == ' ' || *find == '\t') find++;
+ if (*find != '\0') {
+ printf("too many function argument identifers expected %d\n", args);
+ return false;
+ }
+ } else {
+ printf("missing number of argument count in function %s\n", name);
+ return false;
+ }
+
+ /*
+ * Now we need to strip the name apart into it's exact size
+ * by working in the peek buffer till we hit the name again.
+ */
+ if (*peek == '#') {
+ peek --; /* '#' */
+ peek --; /* number */
+ }
+ while (*peek == ' ' || *peek == '\t') peek--;
+
+ /*
+ * We're guranteed to be exactly where we need to be in the
+ * peek buffer to null terminate and get our name from name
+ * without any garbage before or after it.
+ */
+ *++peek='\0';
+
+ /*
+ * We got valid function structure information now. Lets add
+ * the function to the code writer function table.
+ */
+ function.entry = code_statements_elements;
+ function.firstlocal = 0;
+ function.locals = 0;
+ function.profile = 0;
+ function.name = code_chars_elements;
+ function.file = 0;
+ function.nargs = args;
+ def.type = TYPE_FUNCTION;
+ def.offset = code_globals_elements;
+ def.name = code_chars_elements;
+ code_functions_add(function);
+ code_globals_add (code_statements_elements);
+ code_chars_put (name, strlen(name));
+ code_chars_add ('\0');
+ sym.type = TYPE_FUNCTION;
+ sym.name = util_strdup(name);
+ sym.offset = function.entry;
+ asm_symbols_add(sym);
+
+ /* update assembly state */
+
+ *state = ASM_FUNCTION;
+ util_debug("ASM", "added context function %s to function table\n", name);