mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-27 06:19:36 +00:00
Refactor the code to split a string into an argv array of words to pass
to execvp. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@9568 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
b1cc3aad86
commit
1ac3dbbaca
@ -1,3 +1,9 @@
|
|||||||
|
2005-02-02 Angus Leeming <leeming@lyx.org>
|
||||||
|
|
||||||
|
* forkedcall.C (generateChild): overhaul the code to split a string
|
||||||
|
into an argv array of words. Now respects simple quoting reasonably
|
||||||
|
well.
|
||||||
|
|
||||||
2005-02-01 Angus Leeming <leeming@lyx.org>
|
2005-02-01 Angus Leeming <leeming@lyx.org>
|
||||||
|
|
||||||
* fs_extras.C: #include <windows.h>
|
* fs_extras.C: #include <windows.h>
|
||||||
|
@ -257,48 +257,60 @@ int Forkedcall::generateChild()
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// Split the input command up into an array of words stored
|
// Split the input command up into an array of words stored
|
||||||
// in a contiguous block of memory.
|
// in a contiguous block of memory. The array contains pointers
|
||||||
char const * const c_str = line.c_str();
|
// to each word.
|
||||||
// Don't forget the terminating `\0' character.
|
// Don't forget the terminating `\0' character.
|
||||||
|
char const * const c_str = line.c_str();
|
||||||
vector<char> vec(c_str, c_str + line.size() + 1);
|
vector<char> vec(c_str, c_str + line.size() + 1);
|
||||||
// Turn the string into an array of words, each terminated with '\0'.
|
|
||||||
std::replace(vec.begin(), vec.end(), ' ', '\0');
|
|
||||||
|
|
||||||
// Build an array of pointers to each word.
|
// Splitting the command up into an array of words means replacing
|
||||||
vector<char>::iterator vit = vec.begin();
|
// the whitespace between words with '\0'. Life is complicated
|
||||||
vector<char>::iterator vend = vec.end();
|
// however, because words protected by quotes can contain whitespace.
|
||||||
vector<char *> argv;
|
//
|
||||||
char prev = '\0';
|
// The strategy we adopt is:
|
||||||
for (; vit != vend; ++vit) {
|
// 1. If we're not inside quotes, then replace white space with '\0'.
|
||||||
if (*vit != '\0' && prev == '\0')
|
// 2. If we are inside quotes, then don't replace the white space
|
||||||
argv.push_back(&*vit);
|
// but do remove the quotes themselves. We do this naively by
|
||||||
prev = *vit;
|
// replacing the quote with '\0' which is fine if quotes
|
||||||
}
|
// delimit the entire word.
|
||||||
// Strip quotes. Does so naively, assuming that the word begins
|
char inside_quote = 0;
|
||||||
// and ends in quotes.
|
vector<char>::iterator it = vec.begin();
|
||||||
vector<char *>::iterator ait = argv.begin();
|
vector<char>::iterator const end = vec.end();
|
||||||
vector<char *>::iterator const aend = argv.end();
|
for (; it != end; ++it) {
|
||||||
for (; ait != aend; ++ait) {
|
char const c = *it;
|
||||||
char * word = *ait;
|
if (!inside_quote) {
|
||||||
std::size_t const len = strlen(word);
|
if (c == ' ')
|
||||||
if (len >= 2) {
|
*it = '\0';
|
||||||
char & first = word[0];
|
else if (c == '\'' || c == '"') {
|
||||||
char & last = word[len-1];
|
*it = '\0';
|
||||||
|
inside_quote = c;
|
||||||
if (first == last &&
|
|
||||||
(first == '\'' || first == '"')) {
|
|
||||||
first = '\0';
|
|
||||||
last = '\0';
|
|
||||||
*ait += 1;
|
|
||||||
}
|
}
|
||||||
|
} else if (c == inside_quote) {
|
||||||
|
*it = '\0';
|
||||||
|
inside_quote = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ait = argv.begin();
|
// Build an array of pointers to each word.
|
||||||
for (; ait != aend; ++ait)
|
it = vec.begin();
|
||||||
std::cout << *ait << std::endl;
|
vector<char *> argv;
|
||||||
|
char prev = '\0';
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
if (*it != '\0' && prev == '\0')
|
||||||
|
argv.push_back(&*it);
|
||||||
|
prev = *it;
|
||||||
|
}
|
||||||
argv.push_back(0);
|
argv.push_back(0);
|
||||||
|
|
||||||
|
// Debug output.
|
||||||
|
vector<char *>::iterator ait = argv.begin();
|
||||||
|
vector<char *>::iterator const aend = argv.end();
|
||||||
|
lyxerr << "<command>\n";
|
||||||
|
for (; ait != aend; ++ait)
|
||||||
|
if (*ait)
|
||||||
|
lyxerr << '\t'<< *ait << '\n';
|
||||||
|
lyxerr << "</command>" << std::endl;
|
||||||
|
|
||||||
#ifndef __EMX__
|
#ifndef __EMX__
|
||||||
pid_t const cpid = ::fork();
|
pid_t const cpid = ::fork();
|
||||||
if (cpid == 0) {
|
if (cpid == 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user