Mercurial > ~dholland > hg > tradcpp > index.cgi
comparison macro.c @ 184:d359d9b86327
Don't rely on anonymous unions.
They break on... dun dun dun... Solaris. Such a shock.
author | David A. Holland |
---|---|
date | Fri, 12 Jun 2015 03:35:01 -0400 (2015-06-12) |
parents | 6119608a9817 |
children | c8d4ab9aeff0 |
comparison
equal
deleted
inserted
replaced
183:4c3375895c6e | 184:d359d9b86327 |
---|---|
30 #include <stdint.h> | 30 #include <stdint.h> |
31 #include <stdio.h> | 31 #include <stdio.h> |
32 #include <stdlib.h> | 32 #include <stdlib.h> |
33 #include <string.h> | 33 #include <string.h> |
34 | 34 |
35 #include "union.h" | |
35 #include "array.h" | 36 #include "array.h" |
36 #include "mode.h" | 37 #include "mode.h" |
37 #include "place.h" | 38 #include "place.h" |
38 #include "macro.h" | 39 #include "macro.h" |
39 #include "output.h" | 40 #include "output.h" |
40 | 41 |
41 struct expansionitem { | 42 struct expansionitem { |
42 enum { EI_STRING, EI_PARAM, EI_FILE, EI_LINE } itemtype; | 43 enum { EI_STRING, EI_PARAM, EI_FILE, EI_LINE } itemtype; |
43 union { | 44 union { |
44 char *string; /* EI_STRING */ | 45 char *ei_string; /* for EI_STRING */ |
45 unsigned param; /* EI_PARAM */ | 46 unsigned ei_param; /* for EI_PARAM */ |
46 }; | 47 } UN; |
47 }; | 48 }; |
48 DECLARRAY(expansionitem, static UNUSED); | 49 DECLARRAY(expansionitem, static UNUSED); |
49 DEFARRAY(expansionitem, static); | 50 DEFARRAY(expansionitem, static); |
51 | |
52 #ifdef NEED_UNION_ACCESSORS | |
53 #define ei_string un.ei_string | |
54 #define ei_param un.ei_param | |
55 #endif | |
56 | |
50 | 57 |
51 struct macro { | 58 struct macro { |
52 struct place defplace; | 59 struct place defplace; |
53 struct place expansionplace; | 60 struct place expansionplace; |
54 unsigned hash; | 61 unsigned hash; |
76 { | 83 { |
77 struct expansionitem *ei; | 84 struct expansionitem *ei; |
78 | 85 |
79 ei = domalloc(sizeof(*ei)); | 86 ei = domalloc(sizeof(*ei)); |
80 ei->itemtype = EI_STRING; | 87 ei->itemtype = EI_STRING; |
81 ei->string = dostrdup(string); | 88 ei->ei_string = dostrdup(string); |
82 return ei; | 89 return ei; |
83 } | 90 } |
84 | 91 |
85 static | 92 static |
86 struct expansionitem * | 93 struct expansionitem * |
88 { | 95 { |
89 struct expansionitem *ei; | 96 struct expansionitem *ei; |
90 | 97 |
91 ei = domalloc(sizeof(*ei)); | 98 ei = domalloc(sizeof(*ei)); |
92 ei->itemtype = EI_STRING; | 99 ei->itemtype = EI_STRING; |
93 ei->string = dostrndup(string, len); | 100 ei->ei_string = dostrndup(string, len); |
94 return ei; | 101 return ei; |
95 } | 102 } |
96 | 103 |
97 static | 104 static |
98 struct expansionitem * | 105 struct expansionitem * |
100 { | 107 { |
101 struct expansionitem *ei; | 108 struct expansionitem *ei; |
102 | 109 |
103 ei = domalloc(sizeof(*ei)); | 110 ei = domalloc(sizeof(*ei)); |
104 ei->itemtype = EI_PARAM; | 111 ei->itemtype = EI_PARAM; |
105 ei->param = param; | 112 ei->ei_param = param; |
106 return ei; | 113 return ei; |
107 } | 114 } |
108 | 115 |
109 static | 116 static |
110 struct expansionitem * | 117 struct expansionitem * |
132 void | 139 void |
133 expansionitem_destroy(struct expansionitem *ei) | 140 expansionitem_destroy(struct expansionitem *ei) |
134 { | 141 { |
135 switch (ei->itemtype) { | 142 switch (ei->itemtype) { |
136 case EI_STRING: | 143 case EI_STRING: |
137 dostrfree(ei->string); | 144 dostrfree(ei->ei_string); |
138 break; | 145 break; |
139 case EI_PARAM: | 146 case EI_PARAM: |
140 case EI_FILE: | 147 case EI_FILE: |
141 case EI_LINE: | 148 case EI_LINE: |
142 break; | 149 break; |
152 if (ei1->itemtype != ei2->itemtype) { | 159 if (ei1->itemtype != ei2->itemtype) { |
153 return false; | 160 return false; |
154 } | 161 } |
155 switch (ei1->itemtype) { | 162 switch (ei1->itemtype) { |
156 case EI_STRING: | 163 case EI_STRING: |
157 if (strcmp(ei1->string, ei2->string) != 0) { | 164 if (strcmp(ei1->ei_string, ei2->ei_string) != 0) { |
158 return false; | 165 return false; |
159 } | 166 } |
160 break; | 167 break; |
161 case EI_PARAM: | 168 case EI_PARAM: |
162 if (ei1->param != ei2->param) { | 169 if (ei1->ei_param != ei2->ei_param) { |
163 return false; | 170 return false; |
164 } | 171 } |
165 break; | 172 break; |
166 case EI_FILE: | 173 case EI_FILE: |
167 case EI_LINE: | 174 case EI_LINE: |
820 num = expansionitemarray_num(&es->curmacro->expansion); | 827 num = expansionitemarray_num(&es->curmacro->expansion); |
821 for (i=0; i<num; i++) { | 828 for (i=0; i<num; i++) { |
822 ei = expansionitemarray_get(&es->curmacro->expansion, i); | 829 ei = expansionitemarray_get(&es->curmacro->expansion, i); |
823 switch (ei->itemtype) { | 830 switch (ei->itemtype) { |
824 case EI_STRING: | 831 case EI_STRING: |
825 len += strlen(ei->string); | 832 len += strlen(ei->ei_string); |
826 break; | 833 break; |
827 case EI_PARAM: | 834 case EI_PARAM: |
828 arg = stringarray_get(&es->args, ei->param); | 835 arg = stringarray_get(&es->args, ei->ei_param); |
829 len += strlen(arg); | 836 len += strlen(arg); |
830 break; | 837 break; |
831 case EI_FILE: | 838 case EI_FILE: |
832 len += strlen(place_getname(p)) + 2; | 839 len += strlen(place_getname(p)) + 2; |
833 break; | 840 break; |
841 *ret = '\0'; | 848 *ret = '\0'; |
842 for (i=0; i<num; i++) { | 849 for (i=0; i<num; i++) { |
843 ei = expansionitemarray_get(&es->curmacro->expansion, i); | 850 ei = expansionitemarray_get(&es->curmacro->expansion, i); |
844 switch (ei->itemtype) { | 851 switch (ei->itemtype) { |
845 case EI_STRING: | 852 case EI_STRING: |
846 strcat(ret, ei->string); | 853 strcat(ret, ei->ei_string); |
847 break; | 854 break; |
848 case EI_PARAM: | 855 case EI_PARAM: |
849 arg = stringarray_get(&es->args, ei->param); | 856 arg = stringarray_get(&es->args, ei->ei_param); |
850 strcat(ret, arg); | 857 strcat(ret, arg); |
851 break; | 858 break; |
852 case EI_FILE: | 859 case EI_FILE: |
853 strcat(ret, "\""); | 860 strcat(ret, "\""); |
854 strcat(ret, place_getname(p)); | 861 strcat(ret, place_getname(p)); |