source: util.c @ 4b464a4

barnowl_perlaimdebianowlrelease-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 4b464a4 was 4b464a4, checked in by James M. Kretchmar <kretch@mit.edu>, 19 years ago
Messages now have a direciton (in, out or none). Filters can this direction Outbound messages are no longer type 'admin' but are of the appropriate message type (i.e. 'zephyr') and are direction 'out'. Smartnarrow now works on outgoing messages 'info' updated to show more information for admin and outgoing messages Renamed pretty_sender to short_zuser and renamed long_sender to long_zuser
  • Property mode set to 100644
File size: 13.7 KB
Line 
1#include "owl.h"
2#include <stdlib.h>
3#include <string.h>
4#include <malloc.h>
5#include <ctype.h>
6
7static const char fileIdent[] = "$Id$";
8
9void sepbar(char *in) {
10  char buff[1024];
11  WINDOW *sepwin;
12  owl_messagelist *ml;
13  owl_view *v;
14  int x, y, i;
15  char *foo, *appendtosepbar;
16
17  sepwin=owl_global_get_curs_sepwin(&g);
18  ml=owl_global_get_msglist(&g);
19  v=owl_global_get_current_view(&g);
20
21  werase(sepwin);
22  wattron(sepwin, A_REVERSE);
23  whline(sepwin, ACS_HLINE, owl_global_get_cols(&g));
24
25  wmove(sepwin, 0, 2); 
26
27  if (owl_messagelist_get_size(ml)==0) {
28    strcpy(buff, " (-/-) ");
29  } else {
30    snprintf(buff, 1024, " (%i/%i/%i) ", owl_global_get_curmsg(&g)+1,
31            owl_view_get_size(v),
32            owl_messagelist_get_size(ml));
33  }
34  waddstr(sepwin, buff);
35
36  foo=owl_view_get_filtname(v);
37  if (strcmp(foo, "all")) wattroff(sepwin, A_REVERSE);
38  waddstr(sepwin, " ");
39  waddstr(sepwin, owl_view_get_filtname(v));
40  waddstr(sepwin, " ");
41  if (strcmp(foo, "all")) wattron(sepwin, A_REVERSE);
42
43  if (owl_mainwin_is_curmsg_truncated(owl_global_get_mainwin(&g))) {
44    getyx(sepwin, y, x);
45    wmove(sepwin, y, x+2);
46    wattron(sepwin, A_BOLD);
47    waddstr(sepwin, " <truncated> ");
48    wattroff(sepwin, A_BOLD);
49  }
50
51  i=owl_mainwin_get_last_msg(owl_global_get_mainwin(&g));
52  if ((i != -1) &&
53      (i < owl_view_get_size(v)-1)) {
54    getyx(sepwin, y, x);
55    wmove(sepwin, y, x+2);
56    wattron(sepwin, A_BOLD);
57    waddstr(sepwin, " <more> ");
58    wattroff(sepwin, A_BOLD);
59  }
60
61  if (owl_global_get_rightshift(&g)>0) {
62    getyx(sepwin, y, x);
63    wmove(sepwin, y, x+2);
64    snprintf(buff, 1024, " right: %i ", owl_global_get_rightshift(&g));
65    waddstr(sepwin, buff);
66  }
67
68  if (owl_global_is_zaway(&g)) {
69    getyx(sepwin, y, x);
70    wmove(sepwin, y, x+2);
71    wattron(sepwin, A_BOLD);
72    wattroff(sepwin, A_REVERSE);
73    waddstr(sepwin, " ZAWAY ");
74    wattron(sepwin, A_REVERSE);
75    wattroff(sepwin, A_BOLD);
76  }
77
78  if (owl_global_get_curmsg_vert_offset(&g)) {
79    getyx(sepwin, y, x);
80    wmove(sepwin, y, x+2);
81    wattron(sepwin, A_BOLD);
82    wattroff(sepwin, A_REVERSE);
83    waddstr(sepwin, " SCROLL ");
84    wattron(sepwin, A_REVERSE);
85    wattroff(sepwin, A_BOLD);
86  }
87 
88  if (in) {
89    getyx(sepwin, y, x);
90    wmove(sepwin, y, x+2);
91    waddstr(sepwin, in);
92  }
93
94  appendtosepbar = owl_global_get_appendtosepbar(&g);
95  if (appendtosepbar && *appendtosepbar) {
96    getyx(sepwin, y, x);
97    wmove(sepwin, y, x+2);
98    waddstr(sepwin, " ");
99    waddstr(sepwin, owl_global_get_appendtosepbar(&g));
100    waddstr(sepwin, " ");
101  }
102
103  getyx(sepwin, y, x);
104  wmove(sepwin, y, owl_global_get_cols(&g)-1);
105   
106  wattroff(sepwin, A_BOLD);
107  wattroff(sepwin, A_REVERSE);
108  wnoutrefresh(sepwin);
109}
110
111
112void pophandler_quit(int ch) {
113  if (ch=='q') {
114    owl_popwin_close(owl_global_get_popwin(&g));
115  }
116}
117
118char **atokenize(char *buffer, char *sep, int *i) {
119  /* each element of return must be freed by user */
120  char **args;
121  char *workbuff, *foo;
122  int done=0, first=1, count=0;
123
124  workbuff=owl_malloc(strlen(buffer)+1);
125  memcpy(workbuff, buffer, strlen(buffer)+1);
126
127  args=NULL;
128  while (!done) {
129    if (first) {
130      first=0;
131      foo=(char *)strtok(workbuff, sep);
132    } else {
133      foo=(char *)strtok(NULL, sep);
134    }
135    if (foo==NULL) {
136      done=1;
137    } else {
138      args=(char **)owl_realloc(args, sizeof(char *) * (count+1));
139      args[count]=owl_malloc(strlen(foo)+1);
140      strcpy(args[count], foo);
141      count++;
142    }
143  }
144  *i=count;
145  owl_free(workbuff);
146  return(args);
147}
148
149/* skips n tokens and returns where that would be.
150 * TODO: handle quotes more sanely. */
151char *skiptokens(char *buff, int n) {
152  int inquotes=0;
153  while (*buff && n>0) {
154      while (*buff == ' ') buff++;
155      while (*buff && (inquotes || *buff != ' ')) { 
156        if (*buff == '"' || *buff == '\'') inquotes=!inquotes;
157        buff++;
158      }
159      while (*buff == ' ') buff++;
160      n--;
161  }
162  return buff;
163}
164
165void atokenize_free(char **tok, int nels) {
166  int i;
167  for (i=0; i<nels; i++) {
168    owl_free(tok[i]);
169  }
170  owl_free(tok);
171}
172
173
174void owl_parsefree(char **argv, int argc) {
175  int i;
176
177  if (!argv) return;
178 
179  for (i=0; i<argc; i++) {
180    if (argv[i]) owl_free(argv[i]);
181  }
182  owl_free(argv);
183}
184
185char **owl_parseline(char *line, int *argc) {
186  /* break a command line up into argv, argc.  The caller must free
187     the returned values.  If there is an error argc will be set to
188     -1, argv will be NULL and the caller does not need to free
189     anything */
190
191  char **argv;
192  int i, len, between=1;
193  char *curarg;
194  char quote;
195
196  argv=owl_malloc(sizeof(char *));
197  len=strlen(line);
198  curarg=owl_malloc(len+10);
199  strcpy(curarg, "");
200  quote='\0';
201  *argc=0;
202  for (i=0; i<len+1; i++) {
203    /* find the first real character */
204    if (between) {
205      if (line[i]==' ' || line[i]=='\t' || line[i]=='\0') {
206        continue;
207      } else {
208        between=0;
209        i--;
210        continue;
211      }
212    }
213
214    /* deal with a quote character */
215    if (line[i]=='"' || line[i]=="'"[0]) {
216      /* if this type of quote is open, close it */
217      if (quote==line[i]) {
218        quote='\0';
219        continue;
220      }
221
222      /* if no quoting is open then open with this */
223      if (quote=='\0') {
224        quote=line[i];
225        continue;
226      }
227
228      /* if another type of quote is open then treat this as a literal */
229      curarg[strlen(curarg)+1]='\0';
230      curarg[strlen(curarg)]=line[i];
231      continue;
232    }
233
234    /* if it's not a space or end of command, then use it */
235    if (line[i]!=' ' && line[i]!='\t' && line[i]!='\n' && line[i]!='\0') {
236      curarg[strlen(curarg)+1]='\0';
237      curarg[strlen(curarg)]=line[i];
238      continue;
239    }
240
241    /* otherwise, if we're not in quotes, add the whole argument */
242    if (quote=='\0') {
243      /* add the argument */
244      argv=owl_realloc(argv, sizeof(char *)*((*argc)+1));
245      argv[*argc]=owl_malloc(strlen(curarg)+2);
246      strcpy(argv[*argc], curarg);
247      *argc=*argc+1;
248      strcpy(curarg, "");
249      between=1;
250      continue;
251    }
252
253    /* if it is a space and we're in quotes, then use it */
254    curarg[strlen(curarg)+1]='\0';
255    curarg[strlen(curarg)]=line[i];
256  }
257
258  /* check for unbalanced quotes */
259  if (quote!='\0') {
260    owl_parsefree(argv, *argc);
261    *argc=-1;
262    return(NULL);
263  }
264
265  return(argv);
266}
267
268
269
270int owl_util_find_trans(char *in, int len) {
271  /* return the index of the last char before a change from the first
272     one */
273  int i;
274  for (i=1; i<len; i++) {
275    if (in[i] != in[0]) return(i-1);
276  }
277  return(i);
278}
279
280
281void downstr(char *foo) {
282  int i;
283  for (i=0; foo[i]!='\0'; i++) {
284    foo[i]=tolower(foo[i]);
285  }
286}
287
288char *stristr(char *a, char *b) {
289  char *x, *y, *ret;
290
291  if ((x=owl_strdup(a))==NULL) return(NULL);
292  if ((y=owl_strdup(b))==NULL) return(NULL);
293  downstr(x);
294  downstr(y);
295  ret=strstr(x, y);
296  if (ret==NULL) {
297    owl_free(x);
298    owl_free(y);
299    return(NULL);
300  }
301  ret=ret-x+a;
302  owl_free(x);
303  owl_free(y);
304  return(ret);
305}
306
307/* Caller must free response.
308   Takes in strings which are space-separated lists of tokens
309   and returns a single string containing no token more than once.
310   If prohibit is non-null, no token may start with a character
311   in prohibit.
312*/
313char *owl_util_uniq(char *A, char *B, char *prohibit) {
314  char *cat, **tok;
315  int toklen, i, j, first=1;
316  cat = owl_malloc(strlen(A)+strlen(B)+3);
317  strcpy(cat, A);
318  strcat(cat, " ");
319  strcat(cat, B);
320  tok = atokenize(cat, " ", &toklen);
321  strcpy(cat, "");
322  for (i=0; i<toklen; i++) {
323    int dup=0;
324    for (j=0; j<i; j++) {
325      if (!strcmp(tok[i], tok[j])) dup=1;
326    }
327    if (!dup && (!prohibit || !strchr(prohibit, tok[i][0]))) {
328      if (!first) {
329        strcat(cat, " ");
330      }
331      first=0;
332      strcat(cat, tok[i]);
333    }
334  }
335  atokenize_free(tok, toklen);
336  return(cat);
337}
338
339
340
341/* returns if a string is only whitespace */
342int only_whitespace(char *s) {
343  int i;
344  for (i=0; s[i]; i++) {
345    if (!isspace((int) s[i])) return(0);
346  }
347  return(1);
348}
349
350void *owl_malloc(size_t size) {
351  return(malloc(size));
352}
353
354void owl_free(void *ptr) {
355  free(ptr);
356}
357
358char *owl_strdup(const char *s1) {
359  return(strdup(s1));
360}
361
362void *owl_realloc(void *ptr, size_t size) {
363  return(realloc(ptr, size));
364}
365
366/* allocates memory and returns the string or null.
367 * caller must free the string.
368 * from Linux sprintf man page.
369 */
370char *owl_sprintf(const char *fmt, ...) {
371  int n, size = 100;
372  char *p;
373  va_list ap;
374  if ((p = owl_malloc (size)) == NULL)
375    return NULL;
376  while (1) {
377    /* Try to print in the allocated space. */
378    va_start(ap, fmt);
379    n = vsnprintf (p, size, fmt, ap);
380    va_end(ap);
381    /* If that worked, return the string. */
382    if (n > -1 && n < size)
383      return p;
384    /* Else try again with more space. */
385    if (n > -1)    /* glibc 2.1 */
386      size = n+1; /* precisely what is needed */
387    else           /* glibc 2.0 */
388      size *= 2;  /* twice the old size */
389    if ((p = owl_realloc (p, size)) == NULL)
390      return NULL;
391  }
392}
393
394char *short_zuser(char *in) {
395  char *out, *ptr;
396 
397  /* the caller must free the return */
398  out=owl_strdup(in);
399  ptr=strchr(out, '@');
400  if (ptr) {
401    if (!strcasecmp(ptr+1, ZGetRealm())) {
402      *ptr='\0';
403    }
404  }
405  return(out);
406}
407
408char *long_zuser(char *in) {
409  char *ptr;
410
411  /* the caller must free the return */
412  if (NULL != (ptr=strchr(in, '@'))) {
413    return owl_strdup(in);
414  } else {
415    return owl_sprintf("%s@%s", in, ZGetRealm());
416  }
417}
418                 
419
420char *owl_getquoting(char *line) {
421  if (line[0]=='\0') return("'");
422  if (strchr(line, '\'')) return("\"");
423  if (strchr(line, '"')) return("'");
424  if (strchr(line, ' ')) return("'");
425  return("");
426}
427
428/* Caller must free returned string.
429 * Returns a string with any occurances of 'from' replaced with 'to'.
430 * Does not currently handle backslash quoting, but may in the future.
431 */
432char *owl_util_substitute(char *in, char *from, char *to) {
433  char *out;
434  int   outlen, tolen, fromlen, inpos=0, outpos=0;
435
436  if (!*from) return owl_strdup(in);
437
438  outlen = strlen(in)+1;
439  tolen  = strlen(to);
440  fromlen  = strlen(from);
441  out = malloc(outlen);
442
443  while (in[inpos]) {
444    if (!strncmp(in+inpos, from, fromlen)) {
445      outlen += tolen;
446      out = owl_realloc(out, outlen);
447      strcpy(out+outpos, to);
448      inpos += fromlen;
449      outpos += tolen;
450    } else {
451      out[outpos] = in[inpos];
452      inpos++; outpos++;
453    }
454  }
455  out[outpos] = '\0';
456  return(out);
457}
458
459
460int owl_util_string_to_color(char *color) {
461  if (!strcasecmp(color, "black")) {
462    return(OWL_COLOR_BLACK);
463  } else if (!strcasecmp(color, "red")) {
464    return(OWL_COLOR_RED);
465  } else if (!strcasecmp(color, "green")) {
466    return(OWL_COLOR_GREEN);
467  } else if (!strcasecmp(color, "yellow")) {
468    return(OWL_COLOR_YELLOW);
469  } else if (!strcasecmp(color, "blue")) {
470    return(OWL_COLOR_BLUE);
471  } else if (!strcasecmp(color, "magenta")) {
472    return(OWL_COLOR_MAGENTA);
473  } else if (!strcasecmp(color, "cyan")) {
474    return(OWL_COLOR_CYAN);
475  } else if (!strcasecmp(color, "white")) {
476    return(OWL_COLOR_WHITE);
477  } else if (!strcasecmp(color, "default")) {
478    return(OWL_COLOR_DEFAULT);
479  }
480  return(OWL_COLOR_DEFAULT);
481}
482
483char *owl_util_color_to_string(int color) {
484  if (color==OWL_COLOR_BLACK)   return("black");
485  if (color==OWL_COLOR_RED)     return("red");
486  if (color==OWL_COLOR_GREEN)   return("green");
487  if (color==OWL_COLOR_YELLOW)  return("yellow");
488  if (color==OWL_COLOR_BLUE)    return("blue");
489  if (color==OWL_COLOR_MAGENTA) return("magenta");
490  if (color==OWL_COLOR_CYAN)    return("cyan");
491  if (color==OWL_COLOR_WHITE)   return("white");
492  if (color==OWL_COLOR_DEFAULT) return("default");
493  return("Unknown color");
494}
495
496void owl_hack_animate() {
497  owl_messagelist *ml;
498  owl_message *m;
499  owl_fmtext *fm;
500  char *text, *ptr;
501  int place;
502
503  /* grab the first message and make sure its id is 0 */
504  ml=owl_global_get_msglist(&g);
505  m=owl_messagelist_get_element(ml, 0);
506  if (!m) return;
507  if (owl_message_get_id(m)!=0) return;
508
509  fm=owl_message_get_fmtext(m);
510  text=owl_fmtext_get_text(fm);
511
512  ptr=strstr(text, "OvO");
513  if (ptr) {
514    place=ptr-text;
515    owl_fmtext_set_char(fm, place, '-');
516    owl_fmtext_set_char(fm, place+2, '-');
517
518    owl_mainwin_redisplay(owl_global_get_mainwin(&g));
519    owl_global_set_needrefresh(&g);
520    return;
521  }
522
523  ptr=strstr(text, "-v-");
524  if (ptr) {
525    place=ptr-text;
526    owl_fmtext_set_char(fm, place, 'O');
527    owl_fmtext_set_char(fm, place+2, 'O');
528
529    owl_mainwin_redisplay(owl_global_get_mainwin(&g));
530    owl_global_set_needrefresh(&g);
531    return;
532  }
533}
534
535/**************************************************************************/
536/************************* REGRESSION TESTS *******************************/
537/**************************************************************************/
538
539#ifdef OWL_INCLUDE_REG_TESTS
540
541#define FAIL_UNLESS(desc,pred) printf("\t%-4s: %s\n", (pred)?"ok":(numfailed++,"FAIL"), desc)
542
543int owl_util_regtest(void) {
544  int numfailed=0;
545
546  printf("BEGIN testing owl_util\n");
547
548  FAIL_UNLESS("owl_util_substitute 1",
549              !strcmp("foo", owl_util_substitute("foo", "", "Y")));
550  FAIL_UNLESS("owl_util_substitute 2",
551              !strcmp("fYZYZ", owl_util_substitute("foo", "o", "YZ")));
552  FAIL_UNLESS("owl_util_substitute 3",
553              !strcmp("foo", owl_util_substitute("fYZYZ", "YZ", "o")));
554  FAIL_UNLESS("owl_util_substitute 4",
555              !strcmp("/u/foo/meep", owl_util_substitute("~/meep", "~", "/u/foo")));
556
557  FAIL_UNLESS("skiptokens 1", 
558              !strcmp("bar quux", skiptokens("foo bar quux", 1)));
559  FAIL_UNLESS("skiptokens 2", 
560              !strcmp("meep", skiptokens("foo 'bar quux' meep", 2)));
561
562  FAIL_UNLESS("owl_util_uniq 1", 
563              !strcmp("foo bar x", owl_util_uniq("foo", "bar x", "-")));
564  FAIL_UNLESS("owl_util_uniq 2", 
565              !strcmp("foo bar x", owl_util_uniq("foo", "bar -y x", "-")));
566  FAIL_UNLESS("owl_util_uniq 3", 
567              !strcmp("meep foo bar", owl_util_uniq("meep foo", "bar foo meep", "-")));
568
569  if (numfailed) printf("*** WARNING: failures encountered with owl_util\n");
570  printf("END testing owl_util (%d failures)\n", numfailed);
571  return(numfailed);
572}
573
574#endif /* OWL_INCLUDE_REG_TESTS */
Note: See TracBrowser for help on using the repository browser.