comparison macro.c @ 159:8cef6d7227a8

Expand __FILE__ and __LINE__.
author Joerg Sonnenberger <joerg@bec.de>
date Fri, 27 Feb 2015 00:41:46 +0100
parents 19278e2f885d
children 4a4b3d5c41fa
comparison
equal deleted inserted replaced
158:19278e2f885d 159:8cef6d7227a8
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE. 27 * POSSIBILITY OF SUCH DAMAGE.
28 */ 28 */
29 29
30 #include <stdint.h> 30 #include <stdint.h>
31 #include <stdio.h>
31 #include <stdlib.h> 32 #include <stdlib.h>
32 #include <string.h> 33 #include <string.h>
33 34
34 #include "array.h" 35 #include "array.h"
35 #include "mode.h" 36 #include "mode.h"
36 #include "place.h" 37 #include "place.h"
37 #include "macro.h" 38 #include "macro.h"
38 #include "output.h" 39 #include "output.h"
39 40
40 struct expansionitem { 41 struct expansionitem {
41 bool isstring; 42 enum { EI_PARAM, EI_STRING, EI_FILE, EI_LINE } itemtype;
42 union { 43 union {
43 char *string; 44 char *string;
44 unsigned param; 45 unsigned param;
45 }; 46 };
46 }; 47 };
53 struct stringarray params; 54 struct stringarray params;
54 struct expansionitemarray expansion; 55 struct expansionitemarray expansion;
55 char *name; 56 char *name;
56 unsigned hash; 57 unsigned hash;
57 bool hasparams; 58 bool hasparams;
59 bool isspecial;
58 bool inuse; 60 bool inuse;
59 }; 61 };
60 DECLARRAY(macro, static UNUSED); 62 DECLARRAY(macro, static UNUSED);
61 DEFARRAY(macro, static); 63 DEFARRAY(macro, static);
62 DECLARRAY(macroarray, static UNUSED); 64 DECLARRAY(macroarray, static UNUSED);
74 expansionitem_create_string(const char *string) 76 expansionitem_create_string(const char *string)
75 { 77 {
76 struct expansionitem *ei; 78 struct expansionitem *ei;
77 79
78 ei = domalloc(sizeof(*ei)); 80 ei = domalloc(sizeof(*ei));
79 ei->isstring = true; 81 ei->itemtype = EI_STRING;
80 ei->string = dostrdup(string); 82 ei->string = dostrdup(string);
81 return ei; 83 return ei;
82 } 84 }
83 85
84 static 86 static
86 expansionitem_create_stringlen(const char *string, size_t len) 88 expansionitem_create_stringlen(const char *string, size_t len)
87 { 89 {
88 struct expansionitem *ei; 90 struct expansionitem *ei;
89 91
90 ei = domalloc(sizeof(*ei)); 92 ei = domalloc(sizeof(*ei));
91 ei->isstring = true; 93 ei->itemtype = EI_STRING;
92 ei->string = dostrndup(string, len); 94 ei->string = dostrndup(string, len);
93 return ei; 95 return ei;
94 } 96 }
95 97
96 static 98 static
98 expansionitem_create_param(unsigned param) 100 expansionitem_create_param(unsigned param)
99 { 101 {
100 struct expansionitem *ei; 102 struct expansionitem *ei;
101 103
102 ei = domalloc(sizeof(*ei)); 104 ei = domalloc(sizeof(*ei));
103 ei->isstring = false; 105 ei->itemtype = EI_PARAM;
104 ei->param = param; 106 ei->param = param;
105 return ei; 107 return ei;
106 } 108 }
107 109
108 static 110 static
111 struct expansionitem *
112 expansionitem_create_file(void)
113 {
114 struct expansionitem *ei;
115
116 ei = domalloc(sizeof(*ei));
117 ei->itemtype = EI_FILE;
118 return ei;
119 }
120
121 static
122 struct expansionitem *
123 expansionitem_create_line(void)
124 {
125 struct expansionitem *ei;
126
127 ei = domalloc(sizeof(*ei));
128 ei->itemtype = EI_LINE;
129 return ei;
130 }
131
132 static
109 void 133 void
110 expansionitem_destroy(struct expansionitem *ei) 134 expansionitem_destroy(struct expansionitem *ei)
111 { 135 {
112 if (ei->isstring) { 136 if (ei->itemtype == EI_STRING) {
113 dostrfree(ei->string); 137 dostrfree(ei->string);
114 } 138 }
115 dofree(ei, sizeof(*ei)); 139 dofree(ei, sizeof(*ei));
116 } 140 }
117 141
118 static 142 static
119 bool 143 bool
120 expansionitem_eq(const struct expansionitem *ei1, 144 expansionitem_eq(const struct expansionitem *ei1,
121 const struct expansionitem *ei2) 145 const struct expansionitem *ei2)
122 { 146 {
123 if (ei1->isstring != ei2->isstring) { 147 if ((ei1->itemtype == EI_STRING) != (ei2->itemtype == EI_STRING)) {
124 return false; 148 return false;
125 } 149 }
126 if (ei1->isstring) { 150 if (ei1->itemtype == EI_STRING) {
127 if (strcmp(ei1->string, ei2->string) != 0) { 151 if (strcmp(ei1->string, ei2->string) != 0) {
128 return false; 152 return false;
129 } 153 }
130 } else { 154 } else {
131 if (ei1->param != ei2->param) { 155 if (ei1->param != ei2->param) {
171 macro_eq(const struct macro *m1, const struct macro *m2) 195 macro_eq(const struct macro *m1, const struct macro *m2)
172 { 196 {
173 unsigned num1, num2, i; 197 unsigned num1, num2, i;
174 struct expansionitem *ei1, *ei2; 198 struct expansionitem *ei1, *ei2;
175 const char *p1, *p2; 199 const char *p1, *p2;
200
201 if (m2->isspecial) {
202 return false;
203 }
176 204
177 if (strcmp(m1->name, m2->name) != 0) { 205 if (strcmp(m1->name, m2->name) != 0) {
178 return false; 206 return false;
179 } 207 }
180 208
571 expansionitemarray_add(&m->expansion, ei, NULL); 599 expansionitemarray_add(&m->expansion, ei, NULL);
572 macro_define_common_end(m); 600 macro_define_common_end(m);
573 } 601 }
574 602
575 void 603 void
604 macro_define_file(struct place *p)
605 {
606 struct macro *m;
607 struct expansionitem *ei;
608
609 m = macro_define_common_start(p, "__FILE__", p);
610 m->isspecial = true;
611 ei = expansionitem_create_file();
612 expansionitemarray_add(&m->expansion, ei, NULL);
613 macro_define_common_end(m);
614 }
615
616 void
617 macro_define_line(struct place *p)
618 {
619 struct macro *m;
620 struct expansionitem *ei;
621
622 m = macro_define_common_start(p, "__LINE__", p);
623 m->isspecial = true;
624 ei = expansionitem_create_line();
625 expansionitemarray_add(&m->expansion, ei, NULL);
626 macro_define_common_end(m);
627 }
628
629 void
576 macro_define_params(struct place *p1, const char *macro, 630 macro_define_params(struct place *p1, const char *macro,
577 struct place *p2, const char *params, 631 struct place *p2, const char *params,
578 struct place *p3, const char *expansion) 632 struct place *p3, const char *expansion)
579 { 633 {
580 struct macro *m; 634 struct macro *m;
740 unsigned i, num; 794 unsigned i, num;
741 size_t len; 795 size_t len;
742 char *arg; 796 char *arg;
743 char *ret; 797 char *ret;
744 unsigned numargs, numparams; 798 unsigned numargs, numparams;
799 char numbuf[64];
745 800
746 numargs = stringarray_num(&es->args); 801 numargs = stringarray_num(&es->args);
747 numparams = stringarray_num(&es->curmacro->params); 802 numparams = stringarray_num(&es->curmacro->params);
748 803
749 if (numargs == 0 && numparams == 1) { 804 if (numargs == 0 && numparams == 1) {
764 819
765 len = 0; 820 len = 0;
766 num = expansionitemarray_num(&es->curmacro->expansion); 821 num = expansionitemarray_num(&es->curmacro->expansion);
767 for (i=0; i<num; i++) { 822 for (i=0; i<num; i++) {
768 ei = expansionitemarray_get(&es->curmacro->expansion, i); 823 ei = expansionitemarray_get(&es->curmacro->expansion, i);
769 if (ei->isstring) { 824 switch (ei->itemtype) {
825 case EI_STRING:
770 len += strlen(ei->string); 826 len += strlen(ei->string);
771 } else { 827 break;
828 case EI_PARAM:
772 arg = stringarray_get(&es->args, ei->param); 829 arg = stringarray_get(&es->args, ei->param);
773 len += strlen(arg); 830 len += strlen(arg);
831 break;
832 case EI_FILE:
833 len += strlen(place_getname(p)) + 2;
834 break;
835 case EI_LINE:
836 len += snprintf(numbuf, sizeof(numbuf), "%u", p->line);
837 break;
774 } 838 }
775 } 839 }
776 840
777 ret = domalloc(len+1); 841 ret = domalloc(len+1);
778 *ret = '\0'; 842 *ret = '\0';
779 for (i=0; i<num; i++) { 843 for (i=0; i<num; i++) {
780 ei = expansionitemarray_get(&es->curmacro->expansion, i); 844 ei = expansionitemarray_get(&es->curmacro->expansion, i);
781 if (ei->isstring) { 845 switch (ei->itemtype) {
846 case EI_STRING:
782 strcat(ret, ei->string); 847 strcat(ret, ei->string);
783 } else { 848 break;
849 case EI_PARAM:
784 arg = stringarray_get(&es->args, ei->param); 850 arg = stringarray_get(&es->args, ei->param);
785 strcat(ret, arg); 851 strcat(ret, arg);
852 break;
853 case EI_FILE:
854 strcat(ret, "\"");
855 strcat(ret, place_getname(p));
856 strcat(ret, "\"");
857 break;
858 case EI_LINE:
859 snprintf(numbuf, sizeof(numbuf), "%u", p->line);
860 strcat(ret, numbuf);
861 break;
786 } 862 }
787 } 863 }
788 864
789 return ret; 865 return ret;
790 } 866 }
881 break; 957 break;
882 } 958 }
883 m = macrotable_findlen(buf, len, false); 959 m = macrotable_findlen(buf, len, false);
884 if (m == NULL || m->inuse) { 960 if (m == NULL || m->inuse) {
885 expand_send(es, p, buf, len); 961 expand_send(es, p, buf, len);
962 } else if (m->isspecial) {
963 es->curmacro = m;
964 newbuf = expand_substitute(p, es);
965 expand_send(es, p, newbuf, strlen(newbuf));
966 dostrfree(newbuf);
967 es->curmacro = NULL;
968 m->inuse = false;
886 } else if (!m->hasparams) { 969 } else if (!m->hasparams) {
887 m->inuse = true; 970 m->inuse = true;
888 assert(expansionitemarray_num(&m->expansion) == 1); 971 assert(expansionitemarray_num(&m->expansion) == 1);
889 ei = expansionitemarray_get(&m->expansion, 0); 972 ei = expansionitemarray_get(&m->expansion, 0);
890 assert(ei->isstring); 973 assert(ei->itemtype == EI_STRING);
891 newbuf = macroexpand(p, ei->string, 974 newbuf = macroexpand(p, ei->string,
892 strlen(ei->string), false); 975 strlen(ei->string), false);
893 doexpand(es, p, newbuf, strlen(newbuf)); 976 doexpand(es, p, newbuf, strlen(newbuf));
894 dostrfree(newbuf); 977 dostrfree(newbuf);
895 m->inuse = false; 978 m->inuse = false;