summaryrefslogtreecommitdiff
path: root/data/odcctools/ifnc.diff
diff options
context:
space:
mode:
Diffstat (limited to 'data/odcctools/ifnc.diff')
-rw-r--r--data/odcctools/ifnc.diff225
1 files changed, 225 insertions, 0 deletions
diff --git a/data/odcctools/ifnc.diff b/data/odcctools/ifnc.diff
new file mode 100644
index 000000000..5d77c5981
--- /dev/null
+++ b/data/odcctools/ifnc.diff
@@ -0,0 +1,225 @@
+Index: as/read.c
+===================================================================
+--- odcctools/as/read.c (revision 206)
++++ odcctools+iPhone/as/read.c (working copy)
+@@ -524,6 +525,7 @@
+ { "rept", s_rept, 0 },
+ { "endr", s_endr, 0 },
+ { "ifc", s_ifc, 0 },
++ { "ifnc", s_ifnc, 0 },
+ { NULL } /* end sentinel */
+ };
+
+@@ -3826,6 +3836,15 @@
+ return(s);
+ }
+
++static int is_identifier_char(char c) {
++ return
++ (c >= 'a' && c <= 'z') ||
++ (c >= 'A' && c <= 'Z') ||
++ (c >= '0' && c <= '9') ||
++ (c == '_' || c == '.') ||
++ (c == '=' || c == '$');
++}
++
+ /*
+ * demand_copy_string()
+ *
+@@ -3855,19 +3874,20 @@
+ obstack_1grow(&notes, c);
+ len++;
+ }
+- /*
+- * This next line is so demand_copy_C_string will return a null
+- * termanated string.
+- */
+- obstack_1grow(&notes, '\0');
+- retval = obstack_finish(&notes);
+ }
+ else{
+- as_bad("Missing string");
+- retval = NULL;
+- ignore_rest_of_line();
++ while (is_identifier_char(*input_line_pointer)) {
++ obstack_1grow(&notes, *input_line_pointer++);
++ len++;
++ }
+ }
++ /*
++ * This next line is so demand_copy_C_string will return a null
++ * termanated string.
++ */
++ obstack_1grow(&notes, '\0');
+ *lenP = len;
++ retval = obstack_finish(&notes);
+ return(retval);
+ }
+
+@@ -3964,6 +3984,36 @@
+ }
+
+ /* iPhone binutils extension: .ifc assembles if the two strings are the same */
++void s_ifnc(int value)
++{
++ char *ptr1, *ptr2;
++ int len1, len2;
++
++ if (if_depth >= MAX_IF_DEPTH)
++ as_fatal("Maximum if nesting level reached");
++ last_states[if_depth++] = the_cond_state;
++ the_cond_state.the_cond = if_cond;
++
++ if (the_cond_state.ignore)
++ totally_ignore_line();
++ else {
++ ptr1 = demand_copy_string(&len1);
++
++ SKIP_WHITESPACE();
++ if (*input_line_pointer != ',')
++ as_bad(".ifnc needs two strings separated by a comma (',')");
++ else
++ input_line_pointer++;
++
++ ptr2 = demand_copy_string(&len2);
++
++ the_cond_state.cond_met = (len1 != len2 || strncmp(ptr1, ptr2, len1));
++ the_cond_state.ignore = !the_cond_state.cond_met;
++ demand_empty_rest_of_line();
++ }
++}
++
++/* iPhone binutils extension: .ifc assembles if the two strings are the same */
+ void s_ifc(int value)
+ {
+ char *ptr1, *ptr2;
+@@ -4381,7 +4431,7 @@
+ * determine which it is. */
+ named_invocation = 0;
+ ptr = input_line_pointer;
+- while (!is_end_of_line(*ptr)) {
++ while (is_identifier_char(*ptr)) {
+ if (*ptr == '=') {
+ named_invocation = 1;
+ break;
+@@ -4391,66 +4441,58 @@
+
+ index = 0;
+
+- while (is_ignorable_ws(*input_line_pointer))
+- input_line_pointer++;
+- ptr = input_line_pointer;
++ SKIP_WHITESPACE();
+
+ /* Ok, now parse each argument. */
+ while (1) {
+- if (is_end_of_line(*input_line_pointer) || *input_line_pointer ==
+- ',' || is_ignorable_ws(*input_line_pointer)) {
+- len = input_line_pointer - ptr;
+- arg_buf = malloc(len + 1);
+- if (len)
+- strncpy(arg_buf, ptr, len);
+- arg_buf[len] = '\0';
++ int length;
++ char *value = demand_copy_string(&length);
+
+-#if 0
+- printf("arg is '%s'\n", arg_buf);
+-#endif
++ if (named_invocation) {
++ if (*input_line_pointer++ != '=') {
++ as_bad("In a named-argument-style macro invocation, "
++ "all of the arguments must be specified in the "
++ "named-argument style, but one or more weren't");
++ break;
++ }
+
+- if (named_invocation) {
+- arg_val_ptr = arg_buf;
+- strsep(&arg_val_ptr, "=");
+- if (arg_val_ptr == NULL) {
+- as_bad("In a named-argument-style macro invocation, "
+- "all of the arguments must be specified in the "
+- "named-argument style, but one or more weren't");
++ /* We've parsed it fine, now just find which argument the
++ * user meant. */
++ which_arg = -1;
++ for (i = 0; i < info->arg_count; i++) {
++ if (!strcmp(value, info->args[i]->name)) {
++ which_arg = i;
+ break;
+ }
++ }
+
+- /* We've parsed it fine, now just find which argument the
+- * user meant. */
+- which_arg = -1;
+- for (i = 0; i < info->arg_count; i++) {
+- if (!strcmp(arg_buf, info->args[i]->name)) {
+- which_arg = i;
+- break;
+- }
+- }
++ if (which_arg == -1) {
++ as_bad("'%s' doesn't name an argument of the macro "
++ "'%s'", arg_buf, info->name);
++ break;
++ }
+
+- if (which_arg == -1) {
+- as_bad("'%s' doesn't name an argument of the macro "
+- "'%s'", arg_buf, info->name);
+- break;
+- }
++ arguments[which_arg] = demand_copy_string(&length);
++ } else {
++ /* If not a named invocation, it's simple. */
++ arguments[index++] = value;
++ }
+
+- arguments[which_arg] = arg_val_ptr;
+- } else {
+- /* If not a named invocation, it's simple. */
+- arguments[index++] = arg_buf;
+- }
++ if (*input_line_pointer == ',') {
++ ++input_line_pointer;
++ SKIP_WHITESPACE();
++ continue;
++ } else if (
++ !is_end_of_line(*input_line_pointer) &&
++ !is_ignorable_ws(*input_line_pointer)
++ ) {
++ as_bad("invalid macro expansion argument character (%c)", *input_line_pointer);
++ }
+
+- if (*input_line_pointer == ',' || is_ignorable_ws(
+- *input_line_pointer)) {
+- input_line_pointer++;
+- while (is_ignorable_ws(*input_line_pointer))
+- input_line_pointer++;
+- ptr = input_line_pointer;
+- } else /* must be end of line */
+- break;
+- } else
+- input_line_pointer++;
++ SKIP_WHITESPACE();
++
++ if (is_end_of_line(*input_line_pointer))
++ break;
+ }
+
+ nargs = info->arg_count;
+Index: as/read.h
+===================================================================
+--- odcctools/as/read.h (revision 206)
++++ odcctools+iPhone/as/read.h (working copy)
+@@ -110,6 +110,8 @@
+ int value);
+ extern void s_endr(
+ int value);
++extern void s_ifnc(
++ int value);
+ extern void s_ifc(
+ int value);
+ extern void big_cons(