/* Allocate and initialize to the empty string a new window message buffer. The * return value must be freed using wmbc_free. */ WinMsgBuf *wmb_create() { WinMsgBuf *w = malloc(sizeof(WinMsgBuf)); if (w == NULL) return NULL; w->buf = malloc(WINMSGBUF_SIZE); if (w->buf == NULL) { free(w); return NULL; } w->size = WINMSGBUF_SIZE; wmb_reset(w); return w; }
/* TODO: const char *str for safety and reassurance */ char *MakeWinMsgEv(WinMsgBuf *winmsg, char *str, Window *win, int chesc, int padlen, Event *ev, int rec) { static int tick; char *s = str; struct timeval now; int qmnumrend = 0; int numpad = 0; int lastpad = 0; WinMsgBufContext *wmbc; WinMsgEsc esc; WinMsgCond *cond = alloca(sizeof(WinMsgCond)); /* TODO: temporary to work into existing code */ if (winmsg == NULL) { if (g_winmsg == NULL) { if ((g_winmsg = wmb_create()) == NULL) Panic(0, "%s", strnomem); } winmsg = g_winmsg; } if (cond == NULL) Panic(0, "%s", strnomem); if (rec > WINMSG_RECLIMIT) return winmsg->buf; /* set to sane state (clear garbage) */ wmc_deinit(cond); /* TODO: we can get rid of this once winmsg is properly handled by caller */ if (winmsg->numrend > 0) winmsg->numrend = 0; wmb_reset(winmsg); wmbc = wmbc_create(winmsg); if (wmbc == NULL) Panic(0, "%s", strnomem); tick = 0; gettimeofday(&now, NULL); for (s = str; *s; s++) { if (*s != chesc) { if ((chesc == '%') && (*s == '^')) { s++; if (*s != '^' && *s >= 64) wmbc_putchar(wmbc, *s & 0x1f); continue; } wmbc_putchar(wmbc, *s); continue; } if (*++s == chesc) /* double escape ? */ continue; /* initialize escape */ if ((esc.flags.plus = (*s == '+')) != 0) s++; if ((esc.flags.minus = (*s == '-')) != 0) s++; if ((esc.flags.zero = (*s == '0')) != 0) s++; esc.num = 0; while (*s >= '0' && *s <= '9') esc.num = esc.num * 10 + (*s++ - '0'); if ((esc.flags.lng = (*s == 'L')) != 0) s++; switch (*s) { case WINESC_COND: WinMsgDoEscEx(Cond, &qmnumrend); break; case WINESC_COND_ELSE: WinMsgDoEscEx(CondElse, &qmnumrend); break; case WINESC_HSTATUS: WinMsgDoEscEx(Hstatus, win, &tick, rec); break; case WINESC_BACKTICK: WinMsgDoEscEx(Backtick, esc.num, win, &tick, &now, rec); break; case WINESC_CMD: case WINESC_CMD_ARGS: WinMsgDoEscEx(WinArgv, win); break; case WINESC_WIN_NAMES: case WINESC_WIN_NAMES_NOCUR: WinMsgDoEscEx(WinNames, (*s == WINESC_WIN_NAMES_NOCUR), win); break; case WINESC_WFLAGS: WinMsgDoEscEx(Wflags, win); break; case WINESC_WIN_TITLE: WinMsgDoEscEx(WinTitle, win); break; case WINESC_REND_START: WinMsgDoEsc(Rend); break; case WINESC_HOST: WinMsgDoEsc(HostName); break; case WINESC_SESS_NAME: WinMsgDoEsc(SessName); break; case WINESC_PID: WinMsgDoEsc(Pid); break; case WINESC_FOCUS: WinMsgDoEscEx(Focus, win, ev); break; case WINESC_COPY_MODE: WinMsgDoEscEx(CopyMode, ev); break; case WINESC_ESC_SEEN: WinMsgDoEsc(EscSeen); break; case WINESC_TRUNC_POS: WinMsgDoEscEx(TruncPos, ((esc.num > 100) ? 100 : esc.num), esc.flags.lng); break; case WINESC_PAD: case WINESC_TRUNC: WinMsgDoEscEx(PadOrTrunc, &numpad, &lastpad, padlen); break; case WINESC_WIN_SIZE: WinMsgDoEscEx(WinSize, win); break; case WINESC_WIN_NUM: WinMsgDoEscEx(WinNum, win); break; case WINESC_WIN_LOGNAME: WinMsgDoEscEx(WinLogName, win); break; } } if (wmc_is_active(cond) && !wmc_is_set(cond)) wmbc->p = wmc_end(cond, wmbc->p, NULL) + 1; wmbc_putchar(wmbc, '\0' ); wmbc->p--; /* TODO: temporary to work with old code */ if (numpad) { if (padlen > MAXSTR - 1) padlen = MAXSTR - 1; pad_expand(winmsg, winmsg->buf, wmbc->p, numpad, padlen); } if (ev) { evdeq(ev); /* just in case */ ev->timeout.tv_sec = 0; ev->timeout.tv_usec = 0; } if (ev && tick) { now.tv_usec = 100000; if (tick == 1) now.tv_sec++; else now.tv_sec += tick - (now.tv_sec % tick); ev->timeout = now; } wmbc_free(wmbc); return winmsg->buf; }