* xmlXPathSubstringFunction: * @ctxt: the XPath Parser context * @nargs: the number of arguments * * Implement the substring() XPath function * string substring(string, number, number?) * The substring function returns the substring of the first argument * starting at the position specified in the second argument with * length specified in the third argument. For example, * substring
| 8048 | * - substring("12345", -1 div 0, 1 div 0) returns "" |
| 8049 | */ |
| 8050 | void |
| 8051 | xmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs) { |
| 8052 | xmlXPathObjectPtr str, start, len; |
| 8053 | double le=0, in; |
| 8054 | int i = 1, j = INT_MAX; |
| 8055 | |
| 8056 | if (nargs < 2) { |
| 8057 | CHECK_ARITY(2); |
| 8058 | } |
| 8059 | if (nargs > 3) { |
| 8060 | CHECK_ARITY(3); |
| 8061 | } |
| 8062 | /* |
| 8063 | * take care of possible last (position) argument |
| 8064 | */ |
| 8065 | if (nargs == 3) { |
| 8066 | CAST_TO_NUMBER; |
| 8067 | CHECK_TYPE(XPATH_NUMBER); |
| 8068 | len = valuePop(ctxt); |
| 8069 | le = len->floatval; |
| 8070 | xmlXPathReleaseObject(ctxt->context, len); |
| 8071 | } |
| 8072 | |
| 8073 | CAST_TO_NUMBER; |
| 8074 | CHECK_TYPE(XPATH_NUMBER); |
| 8075 | start = valuePop(ctxt); |
| 8076 | in = start->floatval; |
| 8077 | xmlXPathReleaseObject(ctxt->context, start); |
| 8078 | CAST_TO_STRING; |
| 8079 | CHECK_TYPE(XPATH_STRING); |
| 8080 | str = valuePop(ctxt); |
| 8081 | |
| 8082 | if (!(in < INT_MAX)) { /* Logical NOT to handle NaNs */ |
| 8083 | i = INT_MAX; |
| 8084 | } else if (in >= 1.0) { |
| 8085 | i = (int)in; |
| 8086 | if (in - floor(in) >= 0.5) |
| 8087 | i += 1; |
| 8088 | } |
| 8089 | |
| 8090 | if (nargs == 3) { |
| 8091 | double rin, rle, end; |
| 8092 | |
| 8093 | rin = floor(in); |
| 8094 | if (in - rin >= 0.5) |
| 8095 | rin += 1.0; |
| 8096 | |
| 8097 | rle = floor(le); |
| 8098 | if (le - rle >= 0.5) |
| 8099 | rle += 1.0; |
| 8100 | |
| 8101 | end = rin + rle; |
| 8102 | if (!(end >= 1.0)) { /* Logical NOT to handle NaNs */ |
| 8103 | j = 1; |
| 8104 | } else if (end < INT_MAX) { |
| 8105 | j = (int)end; |
| 8106 | } |
| 8107 | } |
nothing calls this directly
no test coverage detected