Mercurial > ~dholland > hg > tradcpp > index.cgi
comparison macro.c @ 87:2b153df78214
Don't bomb out if a function-like macro is given no arguments.
Instead, do the traditional thing and just emit the macro name.
author | David A. Holland |
---|---|
date | Mon, 10 Jun 2013 21:56:09 -0400 |
parents | c91dc1315745 |
children | 36066289e31a |
comparison
equal
deleted
inserted
replaced
86:70d7ebeb4523 | 87:2b153df78214 |
---|---|
821 dostrfree(newbuf2); | 821 dostrfree(newbuf2); |
822 | 822 |
823 es->curmacro->inuse = false; | 823 es->curmacro->inuse = false; |
824 } | 824 } |
825 | 825 |
826 /* | |
827 * The traditional behavior if a function-like macro appears without | |
828 * arguments is to pretend it isn't a macro; that is, just emit its | |
829 * name. | |
830 */ | |
831 static | |
832 void | |
833 expand_missingargs(struct expstate *es, struct place *p, bool needspace) | |
834 { | |
835 if (es->curmacro == NULL) { | |
836 /* defined */ | |
837 expand_send(es, p, "defined", 7); | |
838 return; | |
839 } | |
840 expand_send(es, p, es->curmacro->name, strlen(es->curmacro->name)); | |
841 /* send a space in case we ate whitespace after the macro name */ | |
842 if (needspace) { | |
843 expand_send(es, p, " ", 1); | |
844 } | |
845 } | |
846 | |
826 static | 847 static |
827 void | 848 void |
828 expand_got_ws(struct expstate *es, struct place *p, char *buf, size_t len) | 849 expand_got_ws(struct expstate *es, struct place *p, char *buf, size_t len) |
829 { | 850 { |
830 switch (es->state) { | 851 switch (es->state) { |
875 es->state = ES_WANTLPAREN; | 896 es->state = ES_WANTLPAREN; |
876 } | 897 } |
877 break; | 898 break; |
878 case ES_WANTLPAREN: | 899 case ES_WANTLPAREN: |
879 if (es->curmacro != NULL) { | 900 if (es->curmacro != NULL) { |
880 complain(p, "Expected arguments for macro %s", | 901 expand_missingargs(es, p, true); |
881 es->curmacro->name); | 902 es->state = ES_NORMAL; |
882 complain_fail(); | 903 /* try again */ |
904 expand_got_word(es, p, buf, len); | |
883 } else { | 905 } else { |
884 /* "defined foo" means "defined(foo)" */ | 906 /* "defined foo" means "defined(foo)" */ |
885 expand_newarg(es, buf, len); | 907 expand_newarg(es, buf, len); |
886 es->state = ES_NORMAL; | 908 es->state = ES_NORMAL; |
887 expand_domacro(es, p); | 909 expand_domacro(es, p); |
888 break; | |
889 } | 910 } |
890 break; | 911 break; |
891 case ES_NOARG: | 912 case ES_NOARG: |
892 expand_newarg(es, buf, len); | 913 expand_newarg(es, buf, len); |
893 es->state = ES_HAVEARG; | 914 es->state = ES_HAVEARG; |
928 switch (es->state) { | 949 switch (es->state) { |
929 case ES_NORMAL: | 950 case ES_NORMAL: |
930 expand_send(es, p, buf, len); | 951 expand_send(es, p, buf, len); |
931 break; | 952 break; |
932 case ES_WANTLPAREN: | 953 case ES_WANTLPAREN: |
933 if (es->curmacro) { | 954 expand_missingargs(es, p, false); |
934 complain(p, "Expected arguments for macro %s", | 955 es->state = ES_NORMAL; |
935 es->curmacro->name); | 956 /* try again */ |
936 } else { | 957 expand_got_rparen(es, p, buf, len); |
937 complain(p, "Expected arguments for defined()"); | |
938 } | |
939 complain_fail(); | |
940 break; | 958 break; |
941 case ES_NOARG: | 959 case ES_NOARG: |
942 assert(es->argparens == 0); | 960 assert(es->argparens == 0); |
943 es->state = ES_NORMAL; | 961 es->state = ES_NORMAL; |
944 expand_domacro(es, p); | 962 expand_domacro(es, p); |
962 switch (es->state) { | 980 switch (es->state) { |
963 case ES_NORMAL: | 981 case ES_NORMAL: |
964 expand_send(es, p, buf, len); | 982 expand_send(es, p, buf, len); |
965 break; | 983 break; |
966 case ES_WANTLPAREN: | 984 case ES_WANTLPAREN: |
967 if (es->curmacro) { | 985 expand_missingargs(es, p, false); |
968 complain(p, "Expected arguments for macro %s", | 986 es->state = ES_NORMAL; |
969 es->curmacro->name); | 987 /* try again */ |
970 } else { | 988 expand_got_comma(es, p, buf, len); |
971 complain(p, "Expected arguments for defined()"); | |
972 } | |
973 complain_fail(); | |
974 break; | 989 break; |
975 case ES_NOARG: | 990 case ES_NOARG: |
976 assert(es->argparens == 0); | 991 assert(es->argparens == 0); |
977 expand_newarg(es, buf, 0); | 992 expand_newarg(es, buf, 0); |
978 break; | 993 break; |
993 switch (es->state) { | 1008 switch (es->state) { |
994 case ES_NORMAL: | 1009 case ES_NORMAL: |
995 expand_send(es, p, buf, len); | 1010 expand_send(es, p, buf, len); |
996 break; | 1011 break; |
997 case ES_WANTLPAREN: | 1012 case ES_WANTLPAREN: |
998 if (es->curmacro) { | 1013 expand_missingargs(es, p, false); |
999 complain(p, "Expected arguments for macro %s", | 1014 es->state = ES_NORMAL; |
1000 es->curmacro->name); | 1015 /* try again */ |
1001 } else { | 1016 expand_got_other(es, p, buf, len); |
1002 complain(p, "Expected arguments for defined()"); | |
1003 } | |
1004 complain_fail(); | |
1005 break; | 1017 break; |
1006 case ES_NOARG: | 1018 case ES_NOARG: |
1007 expand_newarg(es, buf, len); | 1019 expand_newarg(es, buf, len); |
1008 es->state = ES_HAVEARG; | 1020 es->state = ES_HAVEARG; |
1009 break; | 1021 break; |
1020 switch (es->state) { | 1032 switch (es->state) { |
1021 case ES_NORMAL: | 1033 case ES_NORMAL: |
1022 expand_send_eof(es, p); | 1034 expand_send_eof(es, p); |
1023 break; | 1035 break; |
1024 case ES_WANTLPAREN: | 1036 case ES_WANTLPAREN: |
1025 if (es->curmacro) { | 1037 expand_missingargs(es, p, false); |
1026 complain(p, "Expected arguments for macro %s", | |
1027 es->curmacro->name); | |
1028 } else { | |
1029 complain(p, "Expected arguments for defined()"); | |
1030 } | |
1031 complain_fail(); | |
1032 break; | 1038 break; |
1033 case ES_NOARG: | 1039 case ES_NOARG: |
1034 case ES_HAVEARG: | 1040 case ES_HAVEARG: |
1035 if (es->curmacro) { | 1041 if (es->curmacro) { |
1036 complain(p, "Unclosed argument list for macro %s", | 1042 complain(p, "Unclosed argument list for macro %s", |