Changeset 5632

Restore the coloured CLI prompt functionality

Comitted by:  mjagdis
Date:  Feb 14 2010 * 23:33 (about 1 year ago)

Affected files:

callweaver/trunk/corelib/console.c (unified diff)

r5630r5632
3636
3737 CALLWEAVER_FILE_VERSION("$HeadURL$", "$Revision$")
3838
39 #include <callweaver/dynstr.h>
3940 #include <callweaver/app.h>
4041 #include <callweaver/cli.h>
4142 #include <callweaver/time.h>
------
5657 #endif
5758
5859
59 #define CALLWEAVER_PROMPT "%s*CLI> "
60 #define CALLWEAVER_PROMPT "%H*CLI%# "
6061
6162
6263 static struct {
------
8485 static unsigned int remotepid;
8586 static char remoteversion[256];
8687
88 static struct cw_dynstr prompt = CW_DYNSTR_INIT;
89
8790 static char *clr_eol;
8891
8992 static int prompting;
------
146149 }
147150
148151
149 static char *cli_prompt(void)
152 static int promptput(int c)
150153 {
151 static char prompt[200];
152 char *pfmt;
153 int color_used = 0;
154 #if 0
155 char term_code[20];
156 #endif
154 cw_dynstr_printf(&prompt, "%c", c);
155 return c;
156 }
157157
158 if ((pfmt = getenv("CALLWEAVER_PROMPT"))) {
159 char *t = pfmt, *p = prompt;
160 memset(prompt, 0, sizeof(prompt));
161 while (*t != '\0' && *p < sizeof(prompt)) {
162 if (*t == '%') {
163 #if 0
164 int i;
165 #endif
166 struct timeval tv;
167 struct tm tm;
158 static void promptattr(const char **attr)
159 {
160 cw_dynstr_printf(&prompt, "%c", RL_PROMPT_START_IGNORE);
161 terminal_write_attr(*attr, promptput);
162 cw_dynstr_printf(&prompt, "%c", RL_PROMPT_END_IGNORE);
163 free((void *)(*attr));
164 *attr = NULL;
165 }
166
167 static void set_prompt(const char *pfmt)
168 {
169 struct tm tm;
170 struct timeval tv;
171 const char *t, *p;
172 const char *astart = NULL, *aend = NULL;
173
174 cw_dynstr_reset(&prompt);
175
176 if (!pfmt)
177 pfmt = CALLWEAVER_PROMPT;
178
179 t = pfmt;
180 while ((p = strchr(t, '%'))) {
181 cw_dynstr_printf(&prompt, "%.*s", (int)(p - t), t);
182 t = p + 1;
168183 #ifdef linux
169 FILE *LOADAVG;
184 FILE *LOADAVG;
170185 #endif
171186
187 switch (*t) {
188 case 'C': { /* colour */
189 char *q = NULL;
190 int fg, bg, i;
191
192 if (aend)
193 promptattr(&aend);
194 if (t[1] == '{' && (p = strchr(&t[2], '}'))) {
195 q = alloca(p - &t[2] + 1);
196 memcpy(q, &t[2], p - &t[2]);
197 q[p - &t[2]] = '\0';
198 t = p;
199 } else if (t[1] == '*') {
200 t++;
201 } else if (sscanf(&t[1], "%d;%d%n", &fg, &bg, &i) >= 2 && fg >= 0 && fg <= 16 && bg >= 0 && bg <= 16) {
202 q = alloca(sizeof("fg=XX,bg=XX"));
203 sprintf(q, "fg=%d,bg=%d", fg, bg);
204 t += i;
205 } else if (sscanf(&t[1], "%d%n", &fg, &i) >= 1 && fg >= 0 && fg <= 16) {
206 q = alloca(sizeof("fg=XX"));
207 sprintf(q, "fg=%d", fg);
208 t += i;
209 }
210 if (q) {
211 terminal_highlight(&astart, &aend, q);
212 if (astart)
213 promptattr(&astart);
214 }
215 break;
216 }
217 case 'd': /* date */
218 cw_dynstr_need(&prompt, sizeof("YYYY-MM-DD"));
219 tv = cw_tvnow();
220 if (localtime_r(&(tv.tv_sec), &tm))
221 strftime(&prompt.data[prompt.used], prompt.size - prompt.used, "%Y-%m-%d", &tm);
222 break;
223 case 'H': /* short remote hostname */
224 if ((p = strchr(remotehostname, '.'))) {
225 cw_dynstr_printf(&prompt, "%.*s", (int)(p - remotehostname), remotehostname);
226 break;
227 }
228 /* fall through */
229 case 'h': /* remote hostname */
230 cw_dynstr_printf(&prompt, "%s", remotehostname);
231 break;
232 #ifdef linux
233 case 'l': /* load avg */
172234 t++;
173 switch (*t) {
174 case 'C': /* color */
175 t++;
176 #if 0
177 if (sscanf(t, "%d;%d%n", &fgcolor, &bgcolor, &i) == 2) {
178 strncat(p, cw_term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1);
179 t += i - 1;
180 } else if (sscanf(t, "%d%n", &fgcolor, &i) == 1) {
181 strncat(p, cw_term_color_code(term_code, fgcolor, 0, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1);
182 t += i - 1;
235 if ((LOADAVG = fopen("/proc/loadavg", "r"))) {
236 float avg1, avg2, avg3;
237 int actproc, totproc, npid, which;
238 fscanf(LOADAVG, "%f %f %f %d/%d %d", &avg1, &avg2, &avg3, &actproc, &totproc, &npid);
239 if (sscanf(t, "%d", &which) == 1) {
240 switch (which) {
241 case 1:
242 cw_dynstr_printf(&prompt, "%.2f", avg1);
243 break;
244 case 2:
245 cw_dynstr_printf(&prompt, "%.2f", avg2);
246 break;
247 case 3:
248 cw_dynstr_printf(&prompt, "%.2f", avg3);
249 break;
250 case 4:
251 cw_dynstr_printf(&prompt, "%d/%d", actproc, totproc);
252 break;
253 case 5:
254 cw_dynstr_printf(&prompt, "%d", npid);
255 break;
183256 }
184
185 /* If the color has been reset correctly, then there's no need to reset it later */
186 if ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) {
187 color_used = 0;
188 } else {
189 color_used = 1;
190 }
191 #endif
192 break;
193 case 'd': /* date */
194 memset(&tm, 0, sizeof(struct tm));
195 tv = cw_tvnow();
196 if (localtime_r(&(tv.tv_sec), &tm)) {
197 strftime(p, sizeof(prompt) - strlen(prompt), "%Y-%m-%d", &tm);
198 }
199 break;
200 case 'h': /* remote hostname */
201 strncat(p, remotehostname, sizeof(prompt) - strlen(prompt) - 1);
202 break;
203 case 'H': { /* short remote hostname */
204 char *q = strchr(remotehostname, '.');
205 int n = (q ? q - remotehostname : strlen(remotehostname));
206 int l = sizeof(prompt) - strlen(prompt) - 1;
207 strncat(p, remotehostname, n > l ? l : n);
208 break;
209257 }
210 #ifdef linux
211 case 'l': /* load avg */
212 t++;
213 if ((LOADAVG = fopen("/proc/loadavg", "r"))) {
214 float avg1, avg2, avg3;
215 int actproc, totproc, npid, which;
216 fscanf(LOADAVG, "%f %f %f %d/%d %d",
217 &avg1, &avg2, &avg3, &actproc, &totproc, &npid);
218 if (sscanf(t, "%d", &which) == 1) {
219 switch (which) {
220 case 1:
221 snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg1);
222 break;
223 case 2:
224 snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg2);
225 break;
226 case 3:
227 snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg3);
228 break;
229 case 4:
230 snprintf(p, sizeof(prompt) - strlen(prompt), "%d/%d", actproc, totproc);
231 break;
232 case 5:
233 snprintf(p, sizeof(prompt) - strlen(prompt), "%d", npid);
234 break;
235 }
236 }
237 }
238 break;
239 #endif
240 case 't': /* time */
241 memset(&tm, 0, sizeof(struct tm));
242 tv = cw_tvnow();
243 if (localtime_r(&(tv.tv_sec), &tm)) {
244 strftime(p, sizeof(prompt) - strlen(prompt), "%H:%M:%S", &tm);
245 }
246 break;
247 case '#': /* process console or remote? */
248 if (! option_remote) {
249 strncat(p, "#", sizeof(prompt) - strlen(prompt) - 1);
250 } else {
251 strncat(p, ">", sizeof(prompt) - strlen(prompt) - 1);
252 }
253 break;
254 case '%': /* literal % */
255 strncat(p, "%", sizeof(prompt) - strlen(prompt) - 1);
256 break;
257 case '\0': /* % is last character - prevent bug */
258 t--;
259 break;
260258 }
261 while (*p != '\0') {
262 p++;
263 }
264 t++;
265 } else {
266 *p = *t;
267 p++;
268 t++;
269 }
270 }
271 if (color_used) {
272 /* Force colors back to normal at end */
273 #if 0
274 cw_term_color_code(term_code, COLOR_WHITE, COLOR_BLACK, sizeof(term_code));
275 if (strlen(term_code) > sizeof(prompt) - strlen(prompt)) {
276 strncat(prompt + sizeof(prompt) - strlen(term_code) - 1, term_code, strlen(term_code));
277 } else {
278 strncat(p, term_code, sizeof(term_code));
279 }
259 break;
280260 #endif
261 case 't': /* time */
262 cw_dynstr_need(&prompt, sizeof("HH:MM:SS"));
263 tv = cw_tvnow();
264 if (localtime_r(&(tv.tv_sec), &tm))
265 strftime(&prompt.data[prompt.used], prompt.size - prompt.used, "%H:%M:%S", &tm);
266 break;
267 case '#': /* process console or remote? */
268 cw_dynstr_printf(&prompt, "%c", (option_remote ? '>' : '#'));
269 break;
270 case '%': /* literal % */
271 cw_dynstr_printf(&prompt, "%c", '%');
272 break;
273 case '\0': /* % is last character - prevent bug */
274 t--;
275 break;
281276 }
282 } else
283 snprintf(prompt, sizeof(prompt), CALLWEAVER_PROMPT, remotehostname);
277 t++;
278 }
279 cw_dynstr_printf(&prompt, "%s", t);
284280
285 return (prompt);
281 if (aend)
282 promptattr(&aend);
286283 }
287284
288285
286 static char *cli_prompt(void)
287 {
288 return prompt.data;
289 }
290
291
289292 static int read_message(int s, int nresp)
290293 {
291294 static char buf_level[16];
------
486489 if (level != CW_EVENT_NUM_VERBOSE) {
487490 fwrite(field[F_DATE].buf, 1, field_len[F_DATE], stdout);
488491 if (level >= 0 && level < arraysize(level_attr) && level_attr[level].on)
489 terminal_write_attr(level_attr[level].on);
492 terminal_write_attr(level_attr[level].on, putchar);
490493 fwrite(field[F_LEVEL].buf, 1, field_len[F_LEVEL], stdout);
491494 if (level >= 0 && level < arraysize(level_attr) && level_attr[level].off)
492 terminal_write_attr(level_attr[level].off);
495 terminal_write_attr(level_attr[level].off, putchar);
493496 putchar('[');
494497 fwrite(field[F_THREADID].buf, 1, field_len[F_THREADID], stdout);
495498 fwrite("]: ", 1, 3, stdout);
------
498501 fwrite(field[F_LINE].buf, 1, field_len[F_LINE], stdout);
499502 putchar(' ');
500503 if (bold_on)
501 terminal_write_attr(bold_on);
504 terminal_write_attr(bold_on, putchar);
502505 fwrite(field[F_FUNCTION].buf, 1, field_len[F_FUNCTION], stdout);
503506 if (bold_off)
504 terminal_write_attr(bold_off);
507 terminal_write_attr(bold_off, putchar);
505508 fwrite(": ", 1, 2, stdout);
506509 }
507510 fwrite(key, 1, lval, stdout);
------
642645 cw_safe_system(s+1);
643646 else
644647 cw_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh");
648 } else if (s[0] == '@') {
649 if (!strncmp(&s[1], "set prompt ", sizeof("set prompt ") - 1)) {
650 set_prompt(&s[sizeof("set prompt ") - 1]);
651 rl_set_prompt(prompt.data);
652 } else
653 fprintf(stderr, "unknown command: %s\n", s);
645654 } else if (option_remote && (!strcasecmp(s, "quit") || !strcasecmp(s, "exit"))) {
646655 console_cleanup(NULL);
647656 exit(0);
------
832841 if (option_console && !fully_booted)
833842 kill(cw_mainpid, SIGHUP);
834843
844 set_prompt(getenv("CALLWEAVER_PROMPT"));
845
835846 progress = 0;
836847 prompting = 1;
837848 rl_callback_handler_install(cli_prompt(), console_handler);

callweaver/trunk/corelib/terminal.c (unified diff)

r5619r5632
9696 known = 0;
9797
9898 col = &fg;
99 if (l > 3) {
99 if (l >= 3) {
100100 if (!strncmp(spec, "bg=", 3)) {
101101 col = &bg;
102102 spec += 3;
------
107107 }
108108 }
109109
110 for (i = 0; i < sizeof(colours) / sizeof(colours[0]); i++) {
111 if (l == colours[i].len && !strncmp(spec, colours[i].name, l)) {
112 *col = i;
113 known = 1;
114 break;
110 i = strtol(spec, &tmp, 10);
111 if (tmp != spec && i < sizeof(colours) / sizeof(colours[0])) {
112 *col = i;
113 known = 1;
114 }
115
116 if (!known) {
117 for (i = 0; i < sizeof(colours) / sizeof(colours[0]); i++) {
118 if (l == colours[i].len && !strncmp(spec, colours[i].name, l)) {
119 *col = i;
120 known = 1;
121 break;
122 }
115123 }
116124 }
117125
------
165173 }
166174
167175 if (setab && bg != -1) {
168 p = tparm(setaf, bg);
176 p = tparm(setab, bg);
169177 i = strlen(p);
170178 bg_p = strcpy(alloca(i + 1), p);
171179 l += i;
------
181189 }
182190
183191
184 int terminal_write_attr(const char *str)
192 int terminal_write_attr(const char *str, int (*func)(int))
185193 {
186 return putp(str);
194 return tputs(str, 1, func);
187195 }
188196
189197

callweaver/trunk/corelib/terminal.h (unified diff)

r5619r5632
1717 */
1818
1919 extern void terminal_highlight(const char **start, const char **end, const char *spec);
20 extern int terminal_write_attr(const char *str);
20 extern int terminal_write_attr(const char *str, int (*putc)(int));
2121 extern void terminal_init(void);
2222 extern void terminal_set_icon(const char *s);