TEST(wchar, wcsstr_wcswcs) {
  const wchar_t* haystack = L"matches hello world, not the second hello world";
  const wchar_t* empty_needle = L"";
  const wchar_t* good_needle = L"ll";
  const wchar_t* bad_needle = L"wort";

  ASSERT_EQ(haystack, wcsstr(haystack, empty_needle));
  ASSERT_EQ(&haystack[10], wcsstr(haystack, good_needle));
  ASSERT_EQ(NULL, wcsstr(haystack, bad_needle));

  ASSERT_EQ(haystack, wcswcs(haystack, empty_needle));
  ASSERT_EQ(&haystack[10], wcswcs(haystack, good_needle));
  ASSERT_EQ(NULL, wcswcs(haystack, bad_needle));
}
wchar_t* UnescapeQuotes(wchar_t* data)
{
	while(wchar_t* quotePos = wcswcs(data, L"\\\""))
		for (++quotePos;quotePos < data + wcslen(data); ++quotePos)
			(*(quotePos - 1)) = *quotePos;
	return data;
}
示例#3
0
StringList *split(wchar *str,wchar *delimiter)
{
	int len_delimiter=wcslen(delimiter);
	StringList *ret=new StringList();
	wchar *p,*q;
	p=str;
	while(1){
		q=wcswcs(p,delimiter);
		if(q!=NULL){
			ret->put(-1,p,0,q-p);
			p=q+len_delimiter;
		}else{
			ret->put(-1,p);
			break;
		}
	}
	return ret;
}
示例#4
0
static TACommandVerdict wcswcs_cmd(TAThread thread,TAInputStream stream)
{
    wchar_t* ws1;
    wchar_t* ws2;
    wchar_t* res;

    // Prepare
    ws1 = (wchar_t*)readPointer(&stream);
    ws2 = (wchar_t*)readPointer(&stream);

    START_TARGET_OPERATION(thread);

    // Execute
    res = wcswcs(ws1, ws2);

    END_TARGET_OPERATION(thread);

    // Response
    writePointer(thread, res);
    sendResponse(thread);

    return taDefaultVerdict;
}
示例#5
0
/*
 * Do grep on a single file.
 * Return true in any lines matched.
 *
 * We have two strategies:
 * The fast one is used when we have a single pattern with
 * a string known to occur in the pattern. We can then
 * do a BMG match on the whole buffer.
 * This is an order of magnitude faster.
 * Otherwise we split the buffer into lines,
 * and check for a match on each line.
 */
static int
grep(int fd, const char *fn)
{
	PATTERN *pp;
	off_t	data_len;	/* length of the data chunk */
	off_t	line_len;	/* length of the current line */
	off_t	line_offset;	/* current line's offset from the beginning */
	off_t	blkoffset;	/* line_offset but context-compatible */
	long long	lineno, linenum;
	long long	matches = 0;	/* Number of matching lines */
	long long	conacnt = 0, conbcnt = 0; 	/* context line count */
	int	newlinep;	/* 0 if the last line of file has no newline */
	char	*ptr, *ptrend, *prntptr, *prntptrend;
	char	*nextptr = NULL, *nextend = NULL;
	char	*conptr = NULL, *conptrend = NULL;
	char	*matchptr = NULL;
	int	conaprnt = 0, conbprnt = 0, lastmatch = 0;
	int	nearmatch = conmatches ? 1 : 0; /* w/in N+1 of last match */
	size_t	prntlen;

	if (patterns == NULL)
		return (0);	/* no patterns to match -- just return */

	pp = patterns;

	if (use_bmg) {
		bmgcomp(pp->pattern, strlen(pp->pattern));
	}

	if (use_wchar && outline == NULL) {
		outbuflen = BUFSIZE + 1;
		outline = malloc(sizeof (wchar_t) * outbuflen);
		if (outline == NULL) {
			(void) fprintf(stderr, gettext("%s: out of memory\n"),
			    cmdname);
			exit(2);
		}
	}

	if (prntbuf == NULL) {
		prntbuflen = BUFSIZE;
		if ((prntbuf = malloc(prntbuflen + 1)) == NULL) {
			(void) fprintf(stderr, gettext("%s: out of memory\n"),
			    cmdname);
			exit(2);
		}
	}

	if (conflag && (conbuf == NULL)) {
		conbuflen = BUFSIZE;
		if ((conbuf = malloc(BUFSIZE+1)) == NULL) {
			(void) fprintf(stderr, gettext("%s: out of memory\n"),
			    cmdname);
			exit(2);
		}
	}

	blkoffset = line_offset = 0;
	lineno = 0;
	linenum = 1;
	newlinep = 1;
	data_len = 0;
	for (; ; ) {
		long	count;
		off_t	offset = 0;
		int	eof = 0, rv = REG_NOMATCH;
		char	separate;

		if (data_len == 0) {
			/*
			 * If no data in the buffer, reset ptr
			 */
			ptr = prntbuf;
			if (conptr == NULL)
				conptrend = conptr = conbuf;
		}
		if (ptr == prntbuf) {
			/*
			 * The current data chunk starts from prntbuf.
			 * This means either the buffer has no data
			 * or the buffer has no newline.
			 * So, read more data from input.
			 */
			count = read(fd, ptr + data_len, prntbuflen - data_len);
			if (count < 0) {
				/* read error */
				if (cflag) {
					if (outfn && !rflag) {
						(void) fprintf(stdout,
						    "%s:", fn);
					}
					if (!qflag && !rflag) {
						(void) fprintf(stdout, "%lld\n",
						    matches);
					}
				}
				return (0);
			} else if (count == 0) {
				/* no new data */
				eof = 1;

				/* we never want to match EOF */
				pp = (PATTERN *) !nvflag;

				if (data_len == 0) {
					/* end of file already reached */
					if (conflag) {
						*conptrend = '\n';
						goto L_next_line;
					} else {
						goto out;
					}
				}
				/* last line of file has no newline */
				ptrend = ptr + data_len;
				newlinep = 0;
				goto L_start_process;
			}
			offset = data_len;
			data_len += count;
		}

		/*
		 * Look for newline in the chunk
		 * between ptr + offset and ptr + data_len - offset.
		 */
		ptrend = find_nl(ptr + offset, data_len - offset);
		if (ptrend == NULL) {
			/* no newline found in this chunk */
			if (ptr > prntbuf) {
				/*
				 * Move remaining data to the beginning
				 * of the buffer.
				 * Remaining data lie from ptr for
				 * data_len bytes.
				 */
				(void) memmove(prntbuf, ptr, data_len);
			}
			if (data_len == prntbuflen) {
				/*
				 * Not enough room in the buffer
				 */
				prntbuflen += BUFSIZE;
				prntbuf = realloc(prntbuf, prntbuflen + 1);
				if (prntbuf == NULL) {
					(void) fprintf(stderr,
					    gettext("%s: out of memory\n"),
					    cmdname);
					exit(2);
				}
			}
			ptr = prntbuf;
			/* read the next input */
			continue;
		}
L_start_process:

		/*
		 * Beginning of the chunk:	ptr
		 * End of the chunk:		ptr + data_len
		 * Beginning of the line:	ptr
		 * End of the line:		ptrend
		 */

		if (use_bmg) {
			/*
			 * Use Boyer-Moore-Gosper algorithm to find out if
			 * this chunk (not this line) contains the specified
			 * pattern.  If not, restart from the last line
			 * of this chunk.
			 */
			char	*bline;
			bline = bmgexec(ptr, ptr + data_len);
			if (bline == NULL) {
				/*
				 * No pattern found in this chunk.
				 * Need to find the last line
				 * in this chunk.
				 */
				ptrend = rfind_nl(ptr, data_len);

				/*
				 * When this chunk does not contain newline,
				 * ptrend becomes NULL, which should happen
				 * when the last line of file does not end
				 * with a newline.  At such a point,
				 * newlinep should have been set to 0.
				 * Therefore, just after jumping to
				 * L_skip_line, the main for-loop quits,
				 * and the line_len value won't be
				 * used.
				 */
				line_len = ptrend - ptr;
				goto L_skip_line;
			}
			if (bline > ptrend) {
				/*
				 * Pattern found not in the first line
				 * of this chunk.
				 * Discard the first line.
				 */
				line_len = ptrend - ptr;
				goto L_skip_line;
			}
			/*
			 * Pattern found in the first line of this chunk.
			 * Using this result.
			 */
			*ptrend = '\0';
			line_len = ptrend - ptr;

			/*
			 * before jumping to L_next_line,
			 * need to handle xflag if specified
			 */
			if (xflag && (line_len != bmglen ||
			    strcmp(bmgpat, ptr) != 0)) {
				/* didn't match */
				pp = NULL;
			} else {
				pp = patterns; /* to make it happen */
			}
			goto L_next_line;
		}
		lineno++;
		/*
		 * Line starts from ptr and ends at ptrend.
		 * line_len will be the length of the line.
		 */
		*ptrend = '\0';
		line_len = ptrend - ptr;

		/*
		 * From now, the process will be performed based
		 * on the line from ptr to ptrend.
		 */
		if (use_wchar) {
			size_t	len;

			if (line_len >= outbuflen) {
				outbuflen = line_len + 1;
				outline = realloc(outline,
				    sizeof (wchar_t) * outbuflen);
				if (outline == NULL) {
					(void) fprintf(stderr,
					    gettext("%s: out of memory\n"),
					    cmdname);
					exit(2);
				}
			}

			len = mbstowcs(outline, ptr, line_len);
			if (len == (size_t)-1) {
				(void) fprintf(stderr, gettext(
	"%s: input file \"%s\": line %lld: invalid multibyte character\n"),
				    cmdname, fn, lineno);
				/* never match a line with invalid sequence */
				goto L_skip_line;
			}
			outline[len] = L'\0';

			if (iflag) {
				wchar_t	*cp;
				for (cp = outline; *cp != '\0'; cp++) {
					*cp = towlower((wint_t)*cp);
				}
			}

			if (xflag) {
				for (pp = patterns; pp; pp = pp->next) {
					if (outline[0] == pp->wpattern[0] &&
					    wcscmp(outline,
					    pp->wpattern) == 0) {
						/* matched */
						rv = REG_OK;
						break;
					}
				}
			} else {
				for (pp = patterns; pp; pp = pp->next) {
					if (wcswcs(outline, pp->wpattern)
					    != NULL) {
						/* matched */
						rv = REG_OK;
						break;
					}
				}
			}
		} else if (Fflag) {
			/* fgrep in byte-oriented handling */
			char	*fptr;
			if (iflag) {
				fptr = istrdup(ptr);
			} else {
				fptr = ptr;
			}
			if (xflag) {
				/* fgrep -x */
				for (pp = patterns; pp; pp = pp->next) {
					if (fptr[0] == pp->pattern[0] &&
					    strcmp(fptr, pp->pattern) == 0) {
						/* matched */
						rv = REG_OK;
						break;
					}
				}
			} else {
				for (pp = patterns; pp; pp = pp->next) {
					if (strstr(fptr, pp->pattern) != NULL) {
						/* matched */
						rv = REG_OK;
						break;
					}
				}
			}
		} else {
			/* grep or egrep */
			for (pp = patterns; pp; pp = pp->next) {
				rv = regexec(&pp->re, ptr, 0, NULL, 0);
				if (rv == REG_OK) {
					/* matched */
					break;
				}

				switch (rv) {
				case REG_NOMATCH:
					break;
				case REG_ECHAR:
					(void) fprintf(stderr, gettext(
	    "%s: input file \"%s\": line %lld: invalid multibyte character\n"),
					    cmdname, fn, lineno);
					break;
				default:
					(void) regerror(rv, &pp->re, errstr,
					    sizeof (errstr));
					(void) fprintf(stderr, gettext(
	    "%s: input file \"%s\": line %lld: %s\n"),
					    cmdname, fn, lineno, errstr);
					exit(2);
				}
			}
		}

		/*
		 * Context is set up as follows:
		 * For a 'Before' context, we maintain a set of pointers
		 * containing 'N' lines of context. If the current number of
		 * lines contained is greater than N, and N isn't a match, the
		 * start pointer is moved forward to the next newline.
		 *
		 * If we ever find a match, we print out immediately.
		 * 'nearmatch' tells us if we're within N+1 lines of the last
		 * match ; if we are, and we find another match, we don't
		 * separate the matches. 'nearmatch' becomes false when
		 * a line gets rotated out of the context.
		 *
		 * For an 'After' context, we simply wait until we've found a
		 * match, then create a context N+1 lines big. If we don't find
		 * a match within the context, we print out the current context.
		 * Otherwise, we save a reference to the new matching line,
		 * print out the other context, and reset our context pointers
		 * to the new matching line.
		 *
		 * 'nearmatch' becomes false when we find a non-matching line
		 * that isn't a part of any context.
		 *
		 * A full-context is implemented as a combination of the
		 * 'Before' and 'After' context logic. Before we find a match,
		 * we follow the Before logic. When we find a match, we
		 * follow the After logic. 'nearmatch' is handled by the Before
		 * logic.
		 */

		if (!conflag)
			goto L_next_line;

		if (line_len + (conptrend - conbuf) > conbuflen) {
			char *oldconbuf = conbuf;
			char *oldconptr = conptr;
			long tmp = matchptr - conptr;

			conbuflen += BUFSIZE;
			conbuf = realloc(conbuf, conbuflen + 1);
			if (conbuf == NULL) {
				(void) fprintf(stderr,
				    gettext("%s: out of memory\n"),
				    cmdname);
				exit(2);
			}

			conptr = conbuf + (conptr - oldconbuf);
			conptrend = conptr + (conptrend - oldconptr);
			if (matchptr)
				matchptr = conptr + tmp;
		}
		(void) memcpy((conptrend > conptr) ?
		    conptrend + 1 : conptrend, ptr, line_len);
		conptrend += line_len + (conptrend > conptr);
		*conptrend = '\n';

		if (!nvflag == rv) {
			/* matched */
			if (lastmatch) {
				if (conflag & AFTER) {
					conaprnt = 1;
					nextend = conptrend;
					conptrend = conptr + lastmatch;
					nextptr = conptrend + 1;
					*nextend = '\n';
				}
			} else {
				if (conflag == AFTER) {
					conptr = conptrend - (line_len);
					linenum = lineno;
					blkoffset = line_offset;
				}
				blkoffset = line_offset -
				    (conptrend - conptr - line_len);
			}

			if (conflag == BEFORE)
				conbprnt = 1;

			lastmatch = conptrend - conptr;
			goto L_next_line;
		}

		if (!lastmatch) {
			if (conflag & BEFORE) {
				if (conbcnt >= conblen) {
					char *tmp = conptr;
					conptr = find_nl(conptr,
					    conptrend - conptr) + 1;
					if (bflag)
						blkoffset += conptr - tmp;
					linenum++;
					nearmatch = 1;
				} else {
					conbcnt++;
				}
			}
			if (conflag == AFTER)
				nearmatch = 1;
		} else  {
			if (++conacnt >= conalen && !conaprnt && conalen)
				conaprnt = 1;
			else
				lastmatch = conptrend - conptr;
		}

L_next_line:
		/*
		 * Here, if pp points to non-NULL, something has been matched
		 * to the pattern.
		 */
		if (nvflag == (pp != NULL)) {
			matches++;
			if (!nextend)
				matchptr = conflag ? conptrend : ptrend;
		}

		/*
		 * Set up some print context so that we can treat
		 * single-line matches as a zero-N context.
		 * Apply CLI flags to each line of the context.
		 *
		 * For context, we only print if we both have a match and are
		 * either at the end of the data stream, or we've previously
		 * declared that we want to print for a particular context.
		 */
		if (lastmatch && (eof || conaprnt || conbprnt)) {

			/*
			 * We'd normally do this earlier, but we had to
			 * escape early because we reached the end of the data.
			 */
			if (eof && nextptr)
				conptrend = nextend;

			prntlen = conptrend - conptr + 1;
			prntptrend = prntptr = conptr;
			if (conmatches++ && nearmatch && !cflag)
				(void) fwrite("--\n", 1, 3, stdout);
		} else if (!conflag && nvflag == (pp != NULL)) {
			*ptrend = '\n';
			prntlen = line_len + 1;
			prntptrend = prntptr = ptr;
			linenum = lineno;
			blkoffset = line_offset;
		} else if (eof) {
			/* No match and no more data */
			goto out;
		} else {
			/* No match, or we're not done building context */
			goto L_skip_line;
		}

		while ((prntptrend = find_nl(prntptrend+1, prntlen)) != NULL) {

			/*
			 * GNU grep uses '-' for context lines and ':' for
			 * matching lines, so replicate that here.
			 */
			if (prntptrend == matchptr) {
				if (eof && nextptr) {
					matchptr = nextend;
					nextptr = NULL;
				} else {
					matchptr = NULL;
				}
				separate = ':';
			} else {
				separate = '-';
			}

			/*
			 * Handle q, l, and c flags.
			 */
			if (qflag) {
				/* no need to continue */
				/*
				 * End of this line is ptrend.
				 * We have read up to ptr + data_len.
				 */
				off_t	pos;
				pos = ptr + data_len - (ptrend + 1);
				(void) lseek(fd, -pos, SEEK_CUR);
				exit(0);
			}
			if (lflag) {
				(void) printf("%s\n", fn);
				goto out;
			}
			if (!cflag) {
				if (Hflag || outfn) {
					(void) printf("%s%c", fn, separate);
				}
				if (bflag) {
					(void) printf("%lld%c", (offset_t)
					    (blkoffset / BSIZE), separate);
				}
				if (nflag) {
					(void) printf("%lld%c", linenum,
					    separate);
				}
				(void) fwrite(prntptr, 1,
				    prntptrend - prntptr + 1, stdout);
			}
			if (ferror(stdout)) {
				return (0);
			}
			linenum++;
			prntlen -= prntptrend - prntptr + 1;
			blkoffset += prntptrend - prntptr + 1;
			prntptr = prntptrend + 1;
		}

		if (eof)
			goto out;

		/*
		 * Update context buffer and variables post-print
		 */
		if (conflag) {
			conptr = conbuf;
			conaprnt = conbprnt = 0;
			nearmatch = 0;
			conacnt = conbcnt = 0;

			if (nextptr) {
				(void) memmove(conbuf, nextptr,
				    nextend - nextptr + 1);
				blkoffset += nextptr - conptrend - 1;
				conptrend = conptr + (nextend - nextptr);
				matchptr = conptrend;
				linenum = lineno;
				lastmatch = conptrend - conptr;
			} else {
				conptrend = conptr;
				conacnt = 0;
				lastmatch = 0;
			}
			nextptr = nextend = NULL;
		}

L_skip_line:
		if (!newlinep)
			break;

		data_len -= line_len + 1;
		line_offset += line_len + 1;
		ptr = ptrend + 1;
	}

out:
	if (cflag) {
		if (Hflag || outfn) {
			(void) printf("%s:", fn);
		}
		if (!qflag) {
			(void) printf("%lld\n", matches);
		}
	}
	return (matches != 0);
}
示例#6
0
int APICaller::GetData(LPCWSTR path, char **dataOut)
{
    char *readBuffer = NULL;
    DWORD cumulativeRead = 0;
    BOOL dataCompressed = FALSE;

    // Attempt to get a connection
    if (!GetConnection()) {
        return 0;
    }

    HINTERNET request = WinHttpOpenRequest(connection, L"GET", path, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);

    if (request != NULL)
    {
        WinHttpAddRequestHeaders(request, L"Accept-Encoding: gzip, deflate", (DWORD)-1, WINHTTP_ADDREQ_FLAG_ADD);

        if (WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0))
        {
            if (WinHttpReceiveResponse(request, NULL))
            {
                DWORD toRead = 0;
                DWORD bytesRead = 0;

                do {
                    if (!WinHttpQueryDataAvailable(request, &toRead)) {
                        break;
                    }

                    if (toRead == 0) {
                        break;
                    }

                    readBuffer = (char*)((readBuffer == NULL) ? malloc(toRead) : realloc(readBuffer, cumulativeRead + toRead + 1));

                    if (WinHttpReadData(request, readBuffer+cumulativeRead, toRead, &bytesRead)) {
                        cumulativeRead += bytesRead;
                    }

                } while (toRead > 0);

                readBuffer[cumulativeRead] = '\0';

                //get compression status
                WCHAR *headerInfo = GetHeader(request, WINHTTP_QUERY_CONTENT_ENCODING);
                dataCompressed = wcswcs(headerInfo, L"gzip") != NULL;
                delete[] headerInfo;
            }
        }

        WinHttpCloseHandle(request);
    }

    //Decompress data if necessary
    if (readBuffer != NULL && cumulativeRead > 0) {
        if (dataCompressed) {
            char *inflateBuffer = new char[cumulativeRead*50];
            cumulativeRead = decompress(readBuffer, cumulativeRead, inflateBuffer, cumulativeRead*50);
            inflateBuffer[cumulativeRead] = NULL;
            *dataOut = inflateBuffer;
        } else {
            char *buffer = new char[cumulativeRead+1];
            memcpy(buffer, readBuffer, cumulativeRead+1);
            *dataOut = buffer;
        }
        free(readBuffer);
    }

    return cumulativeRead;
}