Hint added.
[AROS.git] / workbench / c / Shell / convertBackTicks.c
blobf10b5268475552d22d0f30d0ae98b8d84ebbc1f9
1 /*
2 Copyright (C) 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <proto/dos.h>
8 #include <stdio.h>
10 #include "buffer.h"
11 #include "Shell.h"
13 #include <aros/debug.h>
15 // TODO: remove these comments when fixed and validated
16 // TODO: C++ style comments should be avoided
17 // FIXME: why use a $ in a filename ? just to try the resistance of bad FS
18 // TODO: use pipes instead of plain file ?
20 #define SHELL_EMBED "T:Shell$embed"
22 /* BackTicks handling... like V45, we allow several embedded
23 * commands, while V40 only allows one per line.
25 LONG convertBackTicks(ShellState *ss, Buffer *in, Buffer *out, BOOL *quoted)
27 Buffer embedIn = {0}, embedOut = {0}; /* TODO pre-alloc */
28 LONG c = 0, error = 0, n = in->len, p = 0;
29 TEXT buf[512] = SHELL_EMBED;
30 ShellState ess = {0};
32 ess.ss_DOSBase = DOSBase;
33 ess.ss_SysBase = SysBase;
35 for (++in->cur; in->cur < n; p = c)
37 c = in->buf[in->cur];
39 if (p == '*')
41 c = 0;
42 bufferCopy(in, &embedIn, 1, SysBase);
44 else if (c == '`')
45 break;
46 else
47 bufferCopy(in, &embedIn, 1, SysBase);
50 if (c != '`')
52 bufferCopy(&embedIn, out, embedIn.len, SysBase);
53 goto freebufs;
56 ++in->cur; /* last backtick */
58 if (embedIn.len <= 0) /* `` empty command, no output */
59 goto freebufs;
61 initDefaultInterpreterState(&ess);
63 /* The Amiga shell has severe problems when using
64 * redirections in embedded commands so here, the
65 * semantics differ somewhat. Unix shells seems to be
66 * a little bit sloppy with this, too.
67 * If you really wanted to, you could track down
68 * uses of > and >> and make them work inside ` `, too,
69 * but this seems to be rather much work for little gain.
71 if ((error = Redirection_init(&ess)))
72 goto cleanup;
74 /* Construct temporary output filename */
75 l2a(ss->cliNumber, buf + sizeof(SHELL_EMBED) - 1);
77 if (!(ess.newOut = Open(buf, MODE_NEWFILE)))
79 error = IoErr();
80 goto cleanup;
83 ess.oldOut = SelectOutput(ess.newOut);
85 /* Embedded command isn't echo'ed, but its result will be integrated
86 in final command line, which will be echo'ed if the var is set. */
87 D(bug("[Shell] embedded command: %s\n", embedIn.buf));
88 if ((error = checkLine(&ess, &embedIn, &embedOut, FALSE)) == 0)
90 LONG i, len = -1, size;
92 /* copy result to output */
93 if ((size = Seek(ess.newOut, 0, OFFSET_BEGINNING)) >= 0)
95 while ((len = Read(ess.newOut, buf, 512)) > 0)
97 for (i = 0; i < len - 1; ++i) /* replace all \n but last */
98 if (buf[i] == '\n')
99 buf[i] = ' ';
101 size -= len;
103 if (size <= 0 && buf[i] == '\n')
104 --len;
106 bufferAppend(buf, len, out, SysBase);
110 if (len == -1)
111 error = IoErr();
114 cleanup:
115 Redirection_release(&ess);
116 /* TODO: delete generated file */
117 freebufs:
118 bufferFree(&embedIn, SysBase);
119 bufferFree(&embedOut, SysBase);
121 D(bug("[Shell] embedded command done, error = %d\n", error));
122 return error;