Здравствуйте, aeropunk, Вы писали:
A>Спасибо! Да, использование default shell — это лучший из имеющихся у меня вариантов. A>Но еще красивее было бы решить задачу без его использования.
Требования к разбиению строки на аргументы описаны в соответствующем разделе POSIX, и поэтому вполне можно полагаться на default shell.
A>М.б. все-таки есть библиотека?
В Unix для многих вещей библиотеки отсуствуют. За ненадобностью.
wrote:
> Мне нужно решить одну задачку. Я уверен, что она решена уже много раз, но я столкнулся с ней впервые, и встретил некоторое затруднение. Мне не хочется решать ее в очередной раз, но хочется воспользоваться уже имеющимся хорошим опытом предшественников. > > Есть программка, которая должна запускать другие программки. При этом все аргументы запускаемой программы хранятся конфиругационном файле в одном строковом параметре. > > Задачка состоит в том, чтобы нарезать командную строку, полученную из конфигурационного файла на отдельные аргументы для последующей передачи этих агрументов в один из 6 вызовов семейства exec. Как это сделать? Хочется воспользоваться чем-нибудь уже готовым и лучше всего системным, чтобы не пришлось отлавливать потом баги в очередной сторонней библиотеке. > > Предшественник, от которого мне досталась эта программка, особо не заморачивался и просто порезал все по пробельным символам, не подумав о том, что некоторые аргументы сами по себе могут содержать пробельные символы.
Здравствуйте, Аноним, Вы писали:
А>Спасибо, но так я и сам умею. Именно этого и хотелось избежать. А>Хотелось бы найти вызов какой-нибудь проверенной бибилиотеки,
входящий в большинство UNIX-реализаций.
Такой думаю нет. Сам С++ вообще-то не очень стандартен для юниксов .
Хотя если интересует просто распространенная библиотека которую _можно_
поставить на любой юникс, то думаю стоит посмотреть на ACE. Ибо я
думаю вам еще много чего может понадобится .
А>P.S. Прошу прощения, что сразу не указал, язык программирования C++.
Во. АСЕ как раз С++ .
Здравствуйте, aka50, Вы писали:
A>>К сожалению, я не знаком с ACE, буду благодарен за ссылочку A>http://www.cs.wustl.edu/~schmidt/ACE.html
A>А вообще пришло мне тут в голову... а почему бы yacc/lex не воспользоваться? A>Есть везде... да и либ особых не тянет. Проверено временем .
А готовая грамматика для yacc/lex для парсинга аргументов командной строки откуда возмется?
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Что-то я запутался в трех соснах. В исходном сообщении:
Задачка состоит в том, чтобы нарезать командную строку, полученную из конфигурационного файла на отдельные аргументы для последующей передачи этих агрументов в один из 6 вызовов семейства exec. Как это сделать? Хочется воспользоваться чем-нибудь уже готовым и лучше всего системным, чтобы не пришлось отлавливать потом баги в очередной сторонней библиотеке.
Т.е., раз exec, значит нужно запустить новый процесс вместо старого. Тогда вообще ничего мудрить не нужно -- через exec зовем shell и скармливаем ему всю строку параметров, без fork-а.
Или же не вся задача была озвучена.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Нарезка командной строки
От:
Аноним
Дата:
23.08.05 11:42
Оценка:
Мне нужно решить одну задачку. Я уверен, что она решена уже много раз, но я столкнулся с ней впервые, и встретил некоторое затруднение. Мне не хочется решать ее в очередной раз, но хочется воспользоваться уже имеющимся хорошим опытом предшественников.
Есть программка, которая должна запускать другие программки. При этом все аргументы запускаемой программы хранятся конфиругационном файле в одном строковом параметре.
Задачка состоит в том, чтобы нарезать командную строку, полученную из конфигурационного файла на отдельные аргументы для последующей передачи этих агрументов в один из 6 вызовов семейства exec. Как это сделать? Хочется воспользоваться чем-нибудь уже готовым и лучше всего системным, чтобы не пришлось отлавливать потом баги в очередной сторонней библиотеке.
Предшественник, от которого мне досталась эта программка, особо не заморачивался и просто порезал все по пробельным символам, не подумав о том, что некоторые аргументы сами по себе могут содержать пробельные символы.
<skip>
А>Предшественник, от которого мне досталась эта программка, особо не заморачивался и просто порезал все по пробельным символам, не подумав о том, что некоторые аргументы сами по себе могут содержать пробельные символы.
Не указан язык, но я так пронимаю С.
Не знаю поможет или нет .
Я этим очень давно под С пользовался. Понимает кавычки разные, можно указать чем разбито и т.д.
Ну и собственно никакой отвественности не несу .
/* Splits line into parts.*/
int
splitline(char *line,char **args,int maxargs,char *delim)
{
int argcnt = 0;
char c,s;
char *d;
char q = 0;
int qs = 0;
if (line == NULL || delim == NULL)
return argcnt;
for (d = delim; (s = *d++) != 0; ) {
if (s == '\'' || s == '\"') {
qs++;
break;
}
}
/* skip leading delimiters */
cont:
c = *line++;
if (c == 0)
goto done;
for (d = delim; (s = *d++) != 0; ){
/* here we found string in quotes */
if (qs && (c == '\'' || c == '\"')) {
q = c;
c = *line++;
break;
}
if (c == s)
goto cont; /* if ok, try to find next delimiter */
}
if (c == 0)
goto done;
args[argcnt++] = line-1;
if (argcnt == maxargs)
goto done;
for(;;) {
c = *line++;
if (c == 0)
goto done;
if (q && c!= q)
continue; /* check for quote */
if (q)
q = 0; /* if we passed throught quote zero it */
for (d = delim; (s = *d++)!= 0; ) {
if (c == s) {
char *w = line - 1;
*w = '\0';
goto cont;
}
}
}
if (q)
argcnt = 0;
done:
return argcnt;
}
Re[2]: Нарезка командной строки
От:
Аноним
Дата:
23.08.05 12:00
Оценка:
Спасибо, но так я и сам умею. Именно этого и хотелось избежать.
Хотелось бы найти вызов какой-нибудь проверенной бибилиотеки, входящий в большинство UNIX-реализаций.
Программа должна работать под 6 различными UNIX-платформами и под виндами (в данном случае винды не рассматриваем).
P.S. Прошу прощения, что сразу не указал, язык программирования C++.
Здравствуйте, Аноним, Вы писали:
А>Спасибо, но так я и сам умею. Именно этого и хотелось избежать. А>Хотелось бы найти вызов какой-нибудь проверенной бибилиотеки, входящий в большинство UNIX-реализаций. А>Программа должна работать под 6 различными UNIX-платформами и под виндами (в данном случае винды не рассматриваем).
А>P.S. Прошу прощения, что сразу не указал, язык программирования C++.
Прошу прощения, что лезу в чужой монастырь (Юниксов в глаза не видал), но Boost.Program_options -- возможно то, что вам надо.
Re[4]: Нарезка командной строки
От:
Аноним
Дата:
23.08.05 12:57
Оценка:
Да, я смотрел Boost.Program_Options.
Там есть parse_command_line, parse_config_file и parse_evironment.
Первый парсер сам принимает аргументами argc и argv, а последние два по смыслу не подходят.
Возможно я там что-то недосмотрел, поэтому буду благодарен, если меня ткнут носом.
P.S. Срочность задачи (как обычно ) заставила меня создать эту ветку до того момента, как мне пришло письмо c данными для активации акаунта на этом форуме. Теперь я активировался. Мой позывной — аэропанк
Здравствуйте, aka50, Вы писали:
A>Такой думаю нет.
Есть масса различных командных оболочек, многие из них существуют уже очень давно, все они как-то решают вставшую передо мной задачу. Синтаксис многих командных оболочек весьма похож, если не идентичен.
Это размышление и натолкнуло меня на мысль, что должна существовать какая-то стандартная для POSIX библиотека, решающая эту задачу.
wrote:
> Мне нужно решить одну задачку. Я уверен, что она решена уже много раз, но я столкнулся с ней впервые, и встретил некоторое затруднение. Мне не хочется решать ее в очередной раз, но хочется воспользоваться уже имеющимся хорошим опытом предшественников. > > Есть программка, которая должна запускать другие программки. При этом все аргументы запускаемой программы хранятся конфиругационном файле в одном строковом параметре.
А нельзя ли переписать кофигурационный файл так, чтобы каждый аргумент был на отдельной строке? Тогда его и парсить не нужно.
Builds a counted argument vector (ala argc/argv) from either a string or a set of separate tokens. Can substitute environment variable values for tokens that are environment variable references.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
ME>А нельзя ли переписать кофигурационный файл так, чтобы каждый аргумент был на отдельной строке? Тогда его и парсить не нужно.
ME>-- ME>Maxim Yegorushkin
Вообще можно, но по нескольким причинам не стоит это делать.
1. Заказчик уже приучен к данному формату конфигурационного файла, и он будет недоволен его изменением.
2. По причине 1 нужно веское обоснование изменению формата конфигурационного файла. Привести объяснение вроде "мы не умеем" — означает признаться в своем непрофессионализме.
3. Просто интересно (самому или в вашей помощью) найти красивое решение этой задачи.
eao197 wrote:
> Здравствуйте, MaximE, Вы писали: > > <...код поскипан...> > > Как чисто Unix-овое решение -- самый лучший вариант. Только под Windows без fork-а такого не сделаешь. Разве что под cygwin-ом работать.
eao197 wrote:
> Здравствуйте, MaximE, Вы писали: > > <...код поскипан...> > > Как чисто Unix-овое решение -- самый лучший вариант. Только под Windows без fork-а такого не сделаешь. Разве что под cygwin-ом работать.
Спасибо! Да, использование default shell — это лучший из имеющихся у меня вариантов.
Но еще красивее было бы решить задачу без его использования.
М.б. все-таки есть библиотека?
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, MaximE, Вы писали:
E><...код поскипан...>
E>Как чисто Unix-овое решение -- самый лучший вариант. Только под Windows без fork-а такого не сделаешь. Разве что под cygwin-ом работать.
На Wiondows можно не отвлекаться.
Там в отдельной обвязке:
#ifdef WIN32
...
#endif
идет вызов CreateProcess, который как раз принимает все аргументы одной строкой.
Здравствуйте, aeropunk, Вы писали:
A>Спасибо! Да, использование default shell — это лучший из имеющихся у меня вариантов. A>Но еще красивее было бы решить задачу без его использования. A>М.б. все-таки есть библиотека?
Здравствуйте, eao197, Вы писали:
A>>Но еще красивее было бы решить задачу без его использования.
А почему красивее? Ведь это же типичный Unix-way: если есть готовый инструмент, который решает конкретную задачу, то нужно использовать этот инструмент для решения данной задачи. shell -- как раз такой инструмент.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
E>Задачка состоит в том, чтобы нарезать командную строку, полученную из конфигурационного файла на отдельные аргументы для последующей передачи этих агрументов в один из 6 вызовов семейства exec. Как это сделать? Хочется воспользоваться чем-нибудь уже готовым и лучше всего системным, чтобы не пришлось отлавливать потом баги в очередной сторонней библиотеке.
E>Т.е., раз exec, значит нужно запустить новый процесс вместо старого. Тогда вообще ничего мудрить не нужно -- через exec зовем shell и скармливаем ему всю строку параметров, без fork-а.
E>Или же не вся задача была озвучена.
Скажем так, задача имеет два направления: практическое и общепознавательное.
Естественным образом практическое направление имеет для меня более высокий приоритет.
Поэтому если не будет найдено другое решение, я реализую fork — execv c вызовом default shell, которому будет передано 2 параметра: -с и ищеющиеся из конфигурационного файла параметры. Т.е. собственно "назерка" будет изящно обойдена. Для решения практической части задачи это будет вполне достаточно.
С общепознавательной т.з. может потребоваться в самой программе иметь нарезку командной строки (не своей, а какой угодно). Здесь опять может сработать фокус с default shell. Для этого достаточно написать простенькую программку, которая будет (в общем случае не важно каким образом) отсылать родителю свои собственные аргументы, полученные из main. Но породжение нового процесса для этой цели с моей т.з. выглядит несколько тяжеловесно.
P.S. Прошу прощения, fork конечно же подразумевался.
Здравствуйте, aeropunk, Вы писали:
A>Здравствуйте, aka50, Вы писали:
A>>Такой думаю нет.
A>Есть масса различных командных оболочек, многие из них существуют уже очень давно, все они как-то решают вставшую передо мной задачу. Синтаксис многих командных оболочек весьма похож, если не идентичен.
Каждая оболочка имеет свое решение этой проблемы. Например zsh:
/* parse string into a list */
/**/
mod_export Eprog
parse_string(char *s)
{
Eprog p;
int oldlineno = lineno;
lexsave();
inpush(s, INP_LINENO, NULL);
strinbeg(0);
lineno = 1;
p = parse_list();
lineno = oldlineno;
if (tok == LEXERR && !lastval)
lastval = 1;
strinend();
inpop();
lexrestore();
return p;
}
/**/
mod_export Eprog
parse_list(void)
{
int c = 0;
tok = ENDINPUT;
incmdpos = 1;
yylex();
init_parse();
par_list(&c);
if (tok != ENDINPUT) {
clear_hdocs();
tok = LEXERR;
yyerror(0);
return NULL;
}
return bld_eprog();
}
ну и т.д. Ведь она не только разбивает по параметрам, но и выполняет еще кучу всяких вещей типа выполнения операторов while, for, раскрытие
"*.txt" и переменных окружения...
A>Это размышление и натолкнуло меня на мысль, что должна существовать какая-то стандартная для POSIX библиотека, решающая эту задачу.
Не. Каждый шел решает ее по своему к сожалению.
Здравствуйте, aeropunk, Вы писали:
A>Здравствуйте, eao197, Вы писали:
A>Поэтому если не будет найдено другое решение, я реализую fork — execv c вызовом default shell, которому будет передано 2 параметра: -с и ищеющиеся из конфигурационного файла параметры. Т.е. собственно "назерка" будет изящно обойдена. Для решения практической части задачи это будет вполне достаточно.
Тем более, что это уже реализовано:
#include <stdlib.h>
system(const char* command);
А насчет нарезки — стоило бы посмотреть как эта самая нарезка реализована в исходниках вашего default shell-a