source: util.c @ 425c013

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