forked from enlightenment/efl
Expand the command line to handle multiple files, or multiple commands
with a single file each. Needs a serious pounding. The spec is incomplete on this stuff, no telling what strange ways apps will try to abuse it. SVN revision: 26850
This commit is contained in:
parent
abcd2dbe90
commit
a23d884945
|
@ -848,6 +848,7 @@ ecore_desktop_get_command(Ecore_Desktop * desktop, Ecore_List * files, int fill)
|
||||||
if (desktop->exec_params)
|
if (desktop->exec_params)
|
||||||
params = strdup(desktop->exec_params);
|
params = strdup(desktop->exec_params);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
if (files)
|
if (files)
|
||||||
{
|
{
|
||||||
char *file;
|
char *file;
|
||||||
|
@ -856,209 +857,258 @@ if (files)
|
||||||
while((file = ecore_list_next(files)) != NULL)
|
while((file = ecore_list_next(files)) != NULL)
|
||||||
printf("FILE FOR COMMAND IS - %s\n", file);
|
printf("FILE FOR COMMAND IS - %s\n", file);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
do
|
if (files)
|
||||||
{
|
ecore_list_goto_first(files);
|
||||||
if (fill)
|
|
||||||
{
|
|
||||||
Ecore_DList *command;
|
|
||||||
char *p, *t, buf[PATH_MAX + 10];
|
|
||||||
int len = 0;
|
|
||||||
|
|
||||||
if (!params) params = strdup("%F");
|
/* FIXME: The string handling could be better, but it's good enough for now. */
|
||||||
if (!params) goto error;
|
do
|
||||||
command = ecore_dlist_new();
|
{
|
||||||
if (!command) goto error;
|
if (fill)
|
||||||
|
{
|
||||||
|
Ecore_DList *command;
|
||||||
|
char *p, *t, buf[PATH_MAX + 10], *big_buf = NULL;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
ecore_dlist_set_free_cb(command, free);
|
command = ecore_dlist_new();
|
||||||
t = params;
|
if (!command) goto error;
|
||||||
for (p = params; *p; p++)
|
|
||||||
{
|
|
||||||
if (*p == '%')
|
|
||||||
{
|
|
||||||
*p = '\0';
|
|
||||||
ecore_dlist_append(command, strdup(t));
|
|
||||||
*p = '%';
|
|
||||||
t = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (t < p)
|
|
||||||
{
|
|
||||||
ecore_dlist_append(command, strdup(t));
|
|
||||||
}
|
|
||||||
if (!ecore_dlist_is_empty(command))
|
|
||||||
{
|
|
||||||
if (files)
|
|
||||||
ecore_list_goto_first(files);
|
|
||||||
ecore_dlist_goto_first(command);
|
|
||||||
while ((p = ecore_dlist_next(command)) != NULL)
|
|
||||||
{
|
|
||||||
int do_file = 0, is_single = 0, is_URL = 0, is_directory = 0, is_file = 0;
|
|
||||||
|
|
||||||
t = NULL;
|
ecore_dlist_set_free_cb(command, free);
|
||||||
if (p[0] == '%')
|
/* Grab a fresh copy of the params. The default is %F as per rasters request. */
|
||||||
switch (p[1])
|
if (params) free(params);
|
||||||
{
|
if (desktop->exec_params)
|
||||||
case 'f': /* Single file name, multiple invokations if multiple files. If the file is on the net, download first and point to temp file. */
|
params = strdup(desktop->exec_params);
|
||||||
do_file = 1;
|
else
|
||||||
is_single = 1;
|
params = strdup("%F");
|
||||||
break;
|
if (!params) goto error;
|
||||||
|
/* Split it up. */
|
||||||
|
t = params;
|
||||||
|
for (p = params; *p; p++)
|
||||||
|
{
|
||||||
|
if (*p == '%')
|
||||||
|
{
|
||||||
|
*p = '\0';
|
||||||
|
ecore_dlist_append(command, strdup(t));
|
||||||
|
len += strlen(t);
|
||||||
|
*p = '%';
|
||||||
|
t = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (t < p)
|
||||||
|
{
|
||||||
|
ecore_dlist_append(command, strdup(t));
|
||||||
|
}
|
||||||
|
free(params);
|
||||||
|
params = NULL;
|
||||||
|
t = NULL;
|
||||||
|
p = NULL;
|
||||||
|
/* Check the bits for replacables. */
|
||||||
|
if (!ecore_dlist_is_empty(command))
|
||||||
|
{
|
||||||
|
ecore_dlist_goto_first(command);
|
||||||
|
while ((p = ecore_dlist_next(command)) != NULL)
|
||||||
|
{
|
||||||
|
int do_file = 0, is_single = 0, is_URL = 0, is_directory = 0, is_file = 0;
|
||||||
|
|
||||||
case 'u': /* Single URL, multiple invokations if multiple URLs. */
|
t = NULL;
|
||||||
do_file = 1;
|
if (p[0] == '%')
|
||||||
is_single = 1;
|
switch (p[1])
|
||||||
is_URL = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'c': /* Translated Name field from .desktop file. */
|
|
||||||
t = desktop->name;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'k': /* Location of the .desktop file, may be a URL, or empty. */
|
|
||||||
t = desktop->original_path;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'F': /* Multiple file names. If the files are on the net, download first and point to temp files. */
|
|
||||||
do_file = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'U': /* Multiple URLs. */
|
|
||||||
do_file = 1;
|
|
||||||
is_URL = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'd': /* Directory of the file in %f. */
|
|
||||||
do_file = 1;
|
|
||||||
is_single = 1;
|
|
||||||
is_directory = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'D': /* Directories of the files in %F. */
|
|
||||||
do_file = 1;
|
|
||||||
is_directory = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'n': /* Single filename without path. */
|
|
||||||
do_file = 1;
|
|
||||||
is_single = 1;
|
|
||||||
is_file = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'N': /* Multiple filenames without paths. */
|
|
||||||
do_file = 1;
|
|
||||||
is_file = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'i': /* "--icon Icon" field from .desktop file, or empty. */
|
|
||||||
if (desktop->icon)
|
|
||||||
{
|
|
||||||
snprintf(buf, sizeof(buf), "--icon %s", desktop->icon);
|
|
||||||
t = buf;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'm': /* Deprecated mini icon, the spec says we can just drop it. */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'v': /* Device field from .desktop file. */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '%': /* A '%' character. */
|
|
||||||
t = "%";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (do_file && (files))
|
|
||||||
{
|
|
||||||
char *file;
|
|
||||||
|
|
||||||
while((file = ecore_list_next(files)) != NULL)
|
|
||||||
{
|
{
|
||||||
char *text = NULL, *escaped = NULL;
|
case 'f': /* Single file name, multiple invokations if multiple files. If the file is on the net, download first and point to temp file. */
|
||||||
|
do_file = 1;
|
||||||
if (is_URL)
|
is_single = 1;
|
||||||
{
|
|
||||||
/* FIXME: The spec is unclear about what they mean by URL,
|
|
||||||
* GIMP uses %U, but doesn't understand file://foo
|
|
||||||
* For now, just make this the same as is_file.
|
|
||||||
*/
|
|
||||||
// text = malloc(strlen(file) + 10);
|
|
||||||
// if (text)
|
|
||||||
// sprintf(text, "file://%s", file);
|
|
||||||
text = strdup(file);
|
|
||||||
}
|
|
||||||
else if (is_directory)
|
|
||||||
{
|
|
||||||
/* FIXME: for onefang
|
|
||||||
* if filename does not start with ./ or ../ or / then assume it
|
|
||||||
* is a path relative to cwd i.e. "file.png" or "blah/file.png" and
|
|
||||||
* thus %d/%D would be ./ implicitly (but may need to be explicit
|
|
||||||
* in the command line)
|
|
||||||
*/
|
|
||||||
text = ecore_file_get_dir(file);
|
|
||||||
}
|
|
||||||
else if (is_file)
|
|
||||||
text = strdup(ecore_file_get_file(file));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* FIXME: If the file is on the net, download first and point to temp file. */
|
|
||||||
text = strdup(file);
|
|
||||||
}
|
|
||||||
if (text)
|
|
||||||
{
|
|
||||||
escaped = ecore_file_escape_name(text);
|
|
||||||
free(text);
|
|
||||||
}
|
|
||||||
if (escaped)
|
|
||||||
{
|
|
||||||
/* FIXME: Need to append these if we are looping. */
|
|
||||||
snprintf(buf, sizeof(buf), "%s", escaped);
|
|
||||||
t = buf;
|
|
||||||
free(escaped);
|
|
||||||
}
|
|
||||||
if (is_single)
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
if (t)
|
|
||||||
{
|
|
||||||
len += strlen(t);
|
|
||||||
ecore_dlist_previous(command);
|
|
||||||
ecore_dlist_insert(command, strdup(t));
|
|
||||||
ecore_dlist_next(command);
|
|
||||||
ecore_dlist_next(command);
|
|
||||||
}
|
|
||||||
len += strlen(p);
|
|
||||||
}
|
|
||||||
free(params);
|
|
||||||
params = malloc(len + 1);
|
|
||||||
if (params)
|
|
||||||
{
|
|
||||||
params[0] = '\0';
|
|
||||||
ecore_dlist_goto_first(command);
|
|
||||||
while ((p = ecore_dlist_next(command)) != NULL)
|
|
||||||
{
|
|
||||||
if (p[0] == '%')
|
|
||||||
strcat(params, &p[2]);
|
|
||||||
else
|
|
||||||
strcat(params, p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ecore_list_destroy(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: still need to loop if there are files left. */
|
case 'u': /* Single URL, multiple invokations if multiple URLs. */
|
||||||
sub_result = ecore_desktop_merge_command(desktop->exec, params);
|
do_file = 1;
|
||||||
if (sub_result)
|
is_single = 1;
|
||||||
{
|
is_URL = 1;
|
||||||
printf("FULL COMMAND IS - %s\n", sub_result);
|
break;
|
||||||
ecore_list_append(result, sub_result);
|
|
||||||
}
|
case 'c': /* Translated Name field from .desktop file. */
|
||||||
}
|
t = desktop->name;
|
||||||
while((files) && (ecore_list_current(files)));
|
break;
|
||||||
|
|
||||||
|
case 'k': /* Location of the .desktop file, may be a URL, or empty. */
|
||||||
|
t = desktop->original_path;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'F': /* Multiple file names. If the files are on the net, download first and point to temp files. */
|
||||||
|
do_file = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'U': /* Multiple URLs. */
|
||||||
|
do_file = 1;
|
||||||
|
is_URL = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'd': /* Directory of the file in %f. */
|
||||||
|
do_file = 1;
|
||||||
|
is_single = 1;
|
||||||
|
is_directory = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'D': /* Directories of the files in %F. */
|
||||||
|
do_file = 1;
|
||||||
|
is_directory = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'n': /* Single filename without path. */
|
||||||
|
do_file = 1;
|
||||||
|
is_single = 1;
|
||||||
|
is_file = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'N': /* Multiple filenames without paths. */
|
||||||
|
do_file = 1;
|
||||||
|
is_file = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'i': /* "--icon Icon" field from .desktop file, or empty. */
|
||||||
|
if (desktop->icon)
|
||||||
|
{
|
||||||
|
snprintf(buf, sizeof(buf), "--icon %s", desktop->icon);
|
||||||
|
t = buf;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'm': /* Deprecated mini icon, the spec says we can just drop it. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'v': /* Device field from .desktop file. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '%': /* A '%' character. */
|
||||||
|
t = "%";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* TAke care of any file expansions. */
|
||||||
|
if (do_file && (files))
|
||||||
|
{
|
||||||
|
char *file;
|
||||||
|
size_t big_len;
|
||||||
|
|
||||||
|
/* Pre load the big_buf so that the reallocs are quick. WEemight eventually need more than PATH_MAX. */
|
||||||
|
big_buf = malloc(PATH_MAX);
|
||||||
|
big_buf[0] = '\0';
|
||||||
|
big_len = 0;
|
||||||
|
while((file = ecore_list_next(files)) != NULL)
|
||||||
|
{
|
||||||
|
char *text = NULL, *escaped = NULL;
|
||||||
|
|
||||||
|
if (is_URL)
|
||||||
|
{
|
||||||
|
/* FIXME: The spec is unclear about what they mean by URL,
|
||||||
|
* GIMP uses %U, but doesn't understand file://foo
|
||||||
|
* GIMP is also happy if you pass it a raw file name.
|
||||||
|
* For now, just make this the same as is_file.
|
||||||
|
*/
|
||||||
|
text = strdup(file);
|
||||||
|
}
|
||||||
|
else if (is_directory)
|
||||||
|
{
|
||||||
|
/* FIXME: for onefang
|
||||||
|
* if filename does not start with ./ or ../ or / then assume it
|
||||||
|
* is a path relative to cwd i.e. "file.png" or "blah/file.png" and
|
||||||
|
* thus %d/%D would be ./ implicitly (but may need to be explicit
|
||||||
|
* in the command line)
|
||||||
|
*/
|
||||||
|
text = ecore_file_get_dir(file);
|
||||||
|
}
|
||||||
|
else if (is_file)
|
||||||
|
text = strdup(ecore_file_get_file(file));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* FIXME: If the file is on the net, download
|
||||||
|
* first and point to temp file.
|
||||||
|
*
|
||||||
|
* This I think is the clue to how the whole
|
||||||
|
* file/url thing is supposed to work. This is
|
||||||
|
* purely speculation though, and you can get
|
||||||
|
* into lots of trouble with specs that require
|
||||||
|
* geussing like this.
|
||||||
|
*
|
||||||
|
* %u%U - pass filenames or URLS.
|
||||||
|
* %f%F - pass filenames, download URLS and pass path to temp file.
|
||||||
|
*
|
||||||
|
* WE are not currently getting URLs passed to us anyway.
|
||||||
|
*/
|
||||||
|
text = strdup(file);
|
||||||
|
}
|
||||||
|
if (text)
|
||||||
|
{
|
||||||
|
escaped = ecore_file_escape_name(text);
|
||||||
|
free(text);
|
||||||
|
text = NULL;
|
||||||
|
}
|
||||||
|
/* Add it to the big buf. */
|
||||||
|
if (escaped)
|
||||||
|
{
|
||||||
|
big_len += strlen(escaped) + 1;
|
||||||
|
big_buf = realloc(big_buf, big_len);
|
||||||
|
strcat(big_buf, " ");
|
||||||
|
strcat(big_buf, escaped);
|
||||||
|
t = big_buf;
|
||||||
|
free(escaped);
|
||||||
|
escaped = NULL;
|
||||||
|
}
|
||||||
|
if (is_single)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Insert this bit into the command. */
|
||||||
|
if (t)
|
||||||
|
{
|
||||||
|
len += strlen(t);
|
||||||
|
ecore_dlist_previous(command);
|
||||||
|
ecore_dlist_insert(command, strdup(t));
|
||||||
|
ecore_dlist_next(command);
|
||||||
|
ecore_dlist_next(command);
|
||||||
|
}
|
||||||
|
if (big_buf)
|
||||||
|
{
|
||||||
|
free(big_buf);
|
||||||
|
big_buf = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Put it all together. */
|
||||||
|
params = malloc(len + 1);
|
||||||
|
if (params)
|
||||||
|
{
|
||||||
|
params[0] = '\0';
|
||||||
|
ecore_dlist_goto_first(command);
|
||||||
|
while ((p = ecore_dlist_next(command)) != NULL)
|
||||||
|
{
|
||||||
|
if (p[0] == '%')
|
||||||
|
strcat(params, &p[2]);
|
||||||
|
else
|
||||||
|
strcat(params, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ecore_list_destroy(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the command to the list of commands. */
|
||||||
|
/* NOTE: params might be just desktop->exec_params, or it might have been built from bits. */
|
||||||
|
sub_result = ecore_desktop_merge_command(desktop->exec, params);
|
||||||
|
if (sub_result)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("FULL COMMAND IS - %s\n", sub_result);
|
||||||
|
#endif
|
||||||
|
ecore_list_append(result, sub_result);
|
||||||
|
}
|
||||||
|
/* If there is any "single file" things to fill in, and we have more files,
|
||||||
|
* go back and do it all again for the next file.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
while((fill) && (files) && (ecore_list_current(files)));
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (params) free(params);
|
if (params) free(params);
|
||||||
|
|
Loading…
Reference in New Issue