Fossil SCM
Add the "capexpr" TH1 command. This makes "hascap", "anoncap", and "anycap" all obsolete. We'll keep those old commands around, for legacy compatibility.
Commit
f96de5abdf2229e4c3cf760de8be924447453736ae7ca4d5c7d2218c4671aaa7
Parent
6a5cdecddc64444…
1 file changed
+58
+58
| --- src/th_main.c | ||
| +++ src/th_main.c | ||
| @@ -791,10 +791,67 @@ | ||
| 791 | 791 | Th_Free(interp, zCapList); |
| 792 | 792 | } |
| 793 | 793 | Th_SetResultInt(interp, rc); |
| 794 | 794 | return TH_OK; |
| 795 | 795 | } |
| 796 | + | |
| 797 | +/* | |
| 798 | +** TH1 command: capexpr CAPABILITY-EXPR | |
| 799 | +** | |
| 800 | +** Nmemonic: "CAPability EXPRression" | |
| 801 | +** | |
| 802 | +** The capability expression is a list. Each term of the list is a cluster | |
| 803 | +** of capability letters. The overall expression is true if any one term | |
| 804 | +** is true. A single term is true if all letters within that term are true. | |
| 805 | +** Or, if the term begins with "!", then the term is true if none of the | |
| 806 | +** terms or true. Or, if the term begins with "@" then the term is true | |
| 807 | +** if all of the capability letters in that term are available to the | |
| 808 | +** "anonymous" user. Or, if the term is "*" then it is always true. | |
| 809 | +** | |
| 810 | +** Examples: | |
| 811 | +** | |
| 812 | +** capexpr {j o r} True if any one of j, o, or r are available | |
| 813 | +** capexpr {oh} True if both o and h are available | |
| 814 | +** capexpr {@2 @3 4 5 6} 2 or 3 available for anonymous or one of | |
| 815 | +** 4, 5 or 6 is available for the user | |
| 816 | +*/ | |
| 817 | +static int capexprCmd( | |
| 818 | + Th_Interp *interp, | |
| 819 | + void *p, | |
| 820 | + int argc, | |
| 821 | + const char **argv, | |
| 822 | + int *argl | |
| 823 | +){ | |
| 824 | + char **azCap; | |
| 825 | + int *anCap; | |
| 826 | + int nCap; | |
| 827 | + int rc; | |
| 828 | + int i; | |
| 829 | + | |
| 830 | + if( argc!=2 ){ | |
| 831 | + return Th_WrongNumArgs(interp, "capexpr EXPR"); | |
| 832 | + } | |
| 833 | + rc = Th_SplitList(interp, argv[1], argl[1], &azCap, &anCap, &nCap); | |
| 834 | + if( rc ) return rc; | |
| 835 | + rc = 0; | |
| 836 | + for(i=0; i<nCap; i++){ | |
| 837 | + if( azCap[i][0]=='!' ){ | |
| 838 | + rc = !login_has_capability(azCap[i]+1, anCap[i]-1, 0); | |
| 839 | + }else if( azCap[i][0]=='@' ){ | |
| 840 | + rc = login_has_capability(azCap[i]+1, anCap[i]-1, LOGIN_ANON); | |
| 841 | + }else if( azCap[i][0]=='*' ){ | |
| 842 | + rc = 1; | |
| 843 | + }else{ | |
| 844 | + rc = login_has_capability(azCap[i], anCap[i], 0); | |
| 845 | + } | |
| 846 | + break; | |
| 847 | + } | |
| 848 | + Th_Free(interp, azCap); | |
| 849 | + Th_SetResultInt(interp, rc); | |
| 850 | + return TH_OK; | |
| 851 | +} | |
| 852 | + | |
| 796 | 853 | |
| 797 | 854 | /* |
| 798 | 855 | ** TH1 command: searchable STRING... |
| 799 | 856 | ** |
| 800 | 857 | ** Return true if searching in any of the document classes identified |
| @@ -2264,10 +2321,11 @@ | ||
| 2264 | 2321 | } aCommand[] = { |
| 2265 | 2322 | {"anoncap", hascapCmd, (void*)&anonFlag}, |
| 2266 | 2323 | {"anycap", anycapCmd, 0}, |
| 2267 | 2324 | {"artifact", artifactCmd, 0}, |
| 2268 | 2325 | {"builtin_request_js", builtinRequestJsCmd, 0}, |
| 2326 | + {"capexpr", capexprCmd, 0}, | |
| 2269 | 2327 | {"captureTh1", captureTh1Cmd, 0}, |
| 2270 | 2328 | {"cgiHeaderLine", cgiHeaderLineCmd, 0}, |
| 2271 | 2329 | {"checkout", checkoutCmd, 0}, |
| 2272 | 2330 | {"combobox", comboboxCmd, 0}, |
| 2273 | 2331 | {"copybtn", copybtnCmd, 0}, |
| 2274 | 2332 |
| --- src/th_main.c | |
| +++ src/th_main.c | |
| @@ -791,10 +791,67 @@ | |
| 791 | Th_Free(interp, zCapList); |
| 792 | } |
| 793 | Th_SetResultInt(interp, rc); |
| 794 | return TH_OK; |
| 795 | } |
| 796 | |
| 797 | /* |
| 798 | ** TH1 command: searchable STRING... |
| 799 | ** |
| 800 | ** Return true if searching in any of the document classes identified |
| @@ -2264,10 +2321,11 @@ | |
| 2264 | } aCommand[] = { |
| 2265 | {"anoncap", hascapCmd, (void*)&anonFlag}, |
| 2266 | {"anycap", anycapCmd, 0}, |
| 2267 | {"artifact", artifactCmd, 0}, |
| 2268 | {"builtin_request_js", builtinRequestJsCmd, 0}, |
| 2269 | {"captureTh1", captureTh1Cmd, 0}, |
| 2270 | {"cgiHeaderLine", cgiHeaderLineCmd, 0}, |
| 2271 | {"checkout", checkoutCmd, 0}, |
| 2272 | {"combobox", comboboxCmd, 0}, |
| 2273 | {"copybtn", copybtnCmd, 0}, |
| 2274 |
| --- src/th_main.c | |
| +++ src/th_main.c | |
| @@ -791,10 +791,67 @@ | |
| 791 | Th_Free(interp, zCapList); |
| 792 | } |
| 793 | Th_SetResultInt(interp, rc); |
| 794 | return TH_OK; |
| 795 | } |
| 796 | |
| 797 | /* |
| 798 | ** TH1 command: capexpr CAPABILITY-EXPR |
| 799 | ** |
| 800 | ** Nmemonic: "CAPability EXPRression" |
| 801 | ** |
| 802 | ** The capability expression is a list. Each term of the list is a cluster |
| 803 | ** of capability letters. The overall expression is true if any one term |
| 804 | ** is true. A single term is true if all letters within that term are true. |
| 805 | ** Or, if the term begins with "!", then the term is true if none of the |
| 806 | ** terms or true. Or, if the term begins with "@" then the term is true |
| 807 | ** if all of the capability letters in that term are available to the |
| 808 | ** "anonymous" user. Or, if the term is "*" then it is always true. |
| 809 | ** |
| 810 | ** Examples: |
| 811 | ** |
| 812 | ** capexpr {j o r} True if any one of j, o, or r are available |
| 813 | ** capexpr {oh} True if both o and h are available |
| 814 | ** capexpr {@2 @3 4 5 6} 2 or 3 available for anonymous or one of |
| 815 | ** 4, 5 or 6 is available for the user |
| 816 | */ |
| 817 | static int capexprCmd( |
| 818 | Th_Interp *interp, |
| 819 | void *p, |
| 820 | int argc, |
| 821 | const char **argv, |
| 822 | int *argl |
| 823 | ){ |
| 824 | char **azCap; |
| 825 | int *anCap; |
| 826 | int nCap; |
| 827 | int rc; |
| 828 | int i; |
| 829 | |
| 830 | if( argc!=2 ){ |
| 831 | return Th_WrongNumArgs(interp, "capexpr EXPR"); |
| 832 | } |
| 833 | rc = Th_SplitList(interp, argv[1], argl[1], &azCap, &anCap, &nCap); |
| 834 | if( rc ) return rc; |
| 835 | rc = 0; |
| 836 | for(i=0; i<nCap; i++){ |
| 837 | if( azCap[i][0]=='!' ){ |
| 838 | rc = !login_has_capability(azCap[i]+1, anCap[i]-1, 0); |
| 839 | }else if( azCap[i][0]=='@' ){ |
| 840 | rc = login_has_capability(azCap[i]+1, anCap[i]-1, LOGIN_ANON); |
| 841 | }else if( azCap[i][0]=='*' ){ |
| 842 | rc = 1; |
| 843 | }else{ |
| 844 | rc = login_has_capability(azCap[i], anCap[i], 0); |
| 845 | } |
| 846 | break; |
| 847 | } |
| 848 | Th_Free(interp, azCap); |
| 849 | Th_SetResultInt(interp, rc); |
| 850 | return TH_OK; |
| 851 | } |
| 852 | |
| 853 | |
| 854 | /* |
| 855 | ** TH1 command: searchable STRING... |
| 856 | ** |
| 857 | ** Return true if searching in any of the document classes identified |
| @@ -2264,10 +2321,11 @@ | |
| 2321 | } aCommand[] = { |
| 2322 | {"anoncap", hascapCmd, (void*)&anonFlag}, |
| 2323 | {"anycap", anycapCmd, 0}, |
| 2324 | {"artifact", artifactCmd, 0}, |
| 2325 | {"builtin_request_js", builtinRequestJsCmd, 0}, |
| 2326 | {"capexpr", capexprCmd, 0}, |
| 2327 | {"captureTh1", captureTh1Cmd, 0}, |
| 2328 | {"cgiHeaderLine", cgiHeaderLineCmd, 0}, |
| 2329 | {"checkout", checkoutCmd, 0}, |
| 2330 | {"combobox", comboboxCmd, 0}, |
| 2331 | {"copybtn", copybtnCmd, 0}, |
| 2332 |