Thorsten Glaser <[email protected]> wrote:
|> - jobs names hard cut to ridiculous size (should at least be START..END, \
| not
|> STARTUNTILCUT, for, e.g., playing music or having multiple jobs which \
| read
|> RFCs)
|
|It’s pretty hard to do this well. Additionally, there are some
|memory constraints *and* terminal sizes come into play… but your
|improvement idea is noted and gives me some ideas; I know where
|and what to change, for this.
Just in case you're interested in this, here is a patch that tries
to focus display on the executable name. E.g., without the patch:
?0[steffen@sherwood steffen]$ ls -Fastr /usr/share/calendar/calendar.music &
[1] + Done ls -Fastr /usr/share/calendar/calen
And with it:
?0[steffen@nhead src]$ ls -Fastr /usr/share/calendar/calendar.music &
[1] + Done ls -Fastr /...lendar/calendar.music
It's pretty fresh, but all tests pass and i think it's just fine
now. Hope you like it!
--steffen
Date: 2013-02-23 18:16:08 +0100
Try to display executables of jobnames
---
tree.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++----------------
1 files changed, 92 insertions(+), 32 deletions(-)
diff --git a/tree.c b/tree.c
index 8015a8d..539b57d 100644
--- a/tree.c
+++ b/tree.c
@@ -736,48 +736,108 @@ fpFUNCTf(struct shf *shf, int i, bool isksh, const char *k, struct op *v)
fptreef(shf, i, "%s() %T", k, v);
}
-
/* for jobs.c */
void
vistree(char *dst, size_t sz, struct op *t)
{
unsigned int c;
- char *cp, *buf;
+ bool is_com;
+ char *cp, *buf, *dp, *dbuf;
+ unsigned char *sp, *steps;
size_t n;
- buf = alloc(sz + 8, ATEMP);
- snptreef(buf, sz + 8, "%T", t);
- cp = buf;
- vist_loop:
- if (UTFMODE && (n = utf_mbtowc(&c, cp)) != (size_t)-1) {
- if (c == 0 || n >= sz)
- /* NUL or not enough free space */
- goto vist_out;
- /* copy multibyte char */
- sz -= n;
- while (n--)
- *dst++ = *cp++;
- goto vist_loop;
+ /*
+ * When the job is a simple command then try to display as much of the
+ * executable as possible, otherwise hard cut after sz bytes.
+ */
+ if (t->type == TCOM) {
+ is_com = true;
+ buf = NULL;
+ } else {
+ is_com = false;
+ buf = alloc(sz + 8, ATEMP);
}
- if (--sz == 0 || (c = (unsigned char)(*cp++)) == 0)
- /* NUL or not enough free space */
- goto vist_out;
- if ((c & 0x60) == 0 || (c & 0x7F) == 0x7F) {
- /* C0 or C1 control character or DEL */
- if (--sz == 0)
- /* not enough free space for two chars */
- goto vist_out;
- *dst++ = (c & 0x80) ? '$' : '^';
- c = (c & 0x7F) ^ 0x40;
- } else if (UTFMODE && c > 0x7F) {
- /* better not try to display broken multibyte chars */
- c = '?';
+
+ cp = buf = snptreef(buf, sz + 8, "%T", t);
+
+ /* Temporary, sufficiently spaced output buffer and MB step info */
+ n = strlen(cp);
+ if (! is_com)
+ n = ksh_min(n, sz);
+ dp = dbuf = alloc(n * 2 + 6 /* MB_LEN_MAX */ + 1, ATEMP);
+ sp = steps = alloc(n, ATEMP);
+
+ for (;;) {
+ if (UTFMODE && (n = utf_mbtowc(&c, cp)) != (size_t)-1) {
+ if (c == (unsigned char)'\0')
+ break;
+ /* Copy over MB */
+ *sp = (unsigned char)n;
+ while (n--)
+ *dp++ = *cp++;
+ } else {
+ if ((c = (unsigned char)*cp++) == (unsigned char)'\0')
+ break;
+ if ((c & 0x60) == 0 || (c & 0x7F) == 0x7F) {
+ /* C0 or C1 control character or DEL */
+ dp[0] = (c & 0x80) ? '$' : '^';
+ dp[1] = (c & 0x7F) ^ 0x40;
+ dp += 2;
+ *sp = 2;
+ } else {
+ if (UTFMODE && c > 0x7F)
+ /* Replace broken MB chars */
+ c = (unsigned char)'?';
+ *dp++ = (char)c;
+ *sp = 1;
+ }
+ }
+ ++sp;
+ if (! is_com && sz < (size_t)(dp - dbuf))
+ break;
+ }
+
+ /* If the last character was SP, remove that (see ptree()) */
+ if (dp > dbuf && dp[-1] == ' ')
+ --dp;
+ *dp = '\0';
+
+ /* Copy over to real destination */
+ n = (size_t)(dp - dbuf);
+ cp = dst;
+ dp = dbuf;
+ sp = steps;
+
+ if (n < sz) {
+ memcpy(cp, dbuf, n);
+ cp += n;
+ } else if (! is_com) {
+ while (sz > (n = *sp++)) {
+ sz -= n;
+ while (n--)
+ *cp++ = *dp++;
+ }
+ } else {
+ char *topstart = dbuf + n - 1 - (sz - 4 - sz / 3);
+
+ sz /= 3;
+ while (sz > (n = *sp++)) {
+ sz -= n;
+ while (n--)
+ *cp++ = *dp++;
+ }
+ dp += n;
+ cp[0] = '.'; cp[1] = '.'; cp[2] = '.';
+ cp += 3;
+ while (dp < topstart)
+ dp += *sp++;
+ while (*dp != '\0')
+ *cp++ = *dp++;
}
- *dst++ = c;
- goto vist_loop;
+ *cp = '\0';
- vist_out:
- *dst = '\0';
+ afree(steps, ATEMP);
+ afree(dbuf, ATEMP);
afree(buf, ATEMP);
}