handles: Use name value1 value2 ... */
| 800 | handles: Use name value1 value2 ... |
| 801 | */ |
| 802 | static const char *use_macro(cmd_parms * cmd, void *dummy, const char *arg) |
| 803 | { |
| 804 | char *name, *recursion, *where; |
| 805 | const char *errmsg; |
| 806 | ap_macro_t *macro; |
| 807 | apr_array_header_t *replacements; |
| 808 | apr_array_header_t *contents; |
| 809 | |
| 810 | debug(fprintf(stderr, "use_macro -%s-\n", arg)); |
| 811 | |
| 812 | /* must be initialized, or no macros has been defined */ |
| 813 | if (ap_macros == NULL) { |
| 814 | return "no macro defined before " USE_MACRO; |
| 815 | } |
| 816 | |
| 817 | /* get lowercase macro name */ |
| 818 | name = ap_getword_conf(cmd->temp_pool, &arg); |
| 819 | ap_str_tolower(name); |
| 820 | |
| 821 | if (empty_string_p(name)) { |
| 822 | return "no macro name specified with " USE_MACRO; |
| 823 | } |
| 824 | |
| 825 | /* get macro definition */ |
| 826 | macro = apr_hash_get(ap_macros, name, APR_HASH_KEY_STRING); |
| 827 | |
| 828 | if (!macro) { |
| 829 | return apr_psprintf(cmd->temp_pool, "macro '%s' undefined", name); |
| 830 | } |
| 831 | |
| 832 | /* recursion is detected here by looking at the config file name, |
| 833 | * which may already contains "macro 'foo'". Ok, it looks like a hack, |
| 834 | * but otherwise it is uneasy to keep this data available somewhere... |
| 835 | * the name has just the needed visibility and liveness. |
| 836 | */ |
| 837 | recursion = |
| 838 | apr_pstrcat(cmd->temp_pool, "macro '", macro->name, "'", NULL); |
| 839 | |
| 840 | if (ap_strstr((char *) cmd->config_file->name, recursion)) { |
| 841 | return apr_psprintf(cmd->temp_pool, |
| 842 | "recursive use of macro '%s' is invalid", |
| 843 | macro->name); |
| 844 | } |
| 845 | |
| 846 | /* get macro arguments */ |
| 847 | replacements = get_arguments(cmd->temp_pool, arg); |
| 848 | |
| 849 | if (macro->arguments->nelts != replacements->nelts) { |
| 850 | return apr_psprintf(cmd->temp_pool, |
| 851 | "macro '%s' (%s) used " |
| 852 | "with %d arguments instead of %d", |
| 853 | macro->name, macro->location, |
| 854 | replacements->nelts, macro->arguments->nelts); |
| 855 | } |
| 856 | |
| 857 | where = apr_psprintf(cmd->temp_pool, |
| 858 | "macro '%s' (%s) used on line %d of \"%s\"", |
| 859 | macro->name, macro->location, |
nothing calls this directly
no test coverage detected