source: util.c @ 75be7c0

barnowl_perlaimdebianowlrelease-1.10release-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 75be7c0 was 1fd0b25, checked in by James M. Kretchmar <kretch@mit.edu>, 22 years ago
Added the 'search' command. '/' is a keybinding for 'search' '?' is a keybinding for 'search -r' Fixed stristr, which was completely broken renamed owl_fmtext_ztext_stylestrip to owl_function_ztext_styletsrip and put it in functions.c
  • Property mode set to 100644
File size: 12.9 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 *pretty_sender(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_sender(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
496
497/**************************************************************************/
498/************************* REGRESSION TESTS *******************************/
499/**************************************************************************/
500
501#ifdef OWL_INCLUDE_REG_TESTS
502
503#define FAIL_UNLESS(desc,pred) printf("\t%-4s: %s\n", (pred)?"ok":(numfailed++,"FAIL"), desc)
504
505int owl_util_regtest(void) {
506  int numfailed=0;
507
508  printf("BEGIN testing owl_util\n");
509
510  FAIL_UNLESS("owl_util_substitute 1",
511              !strcmp("foo", owl_util_substitute("foo", "", "Y")));
512  FAIL_UNLESS("owl_util_substitute 2",
513              !strcmp("fYZYZ", owl_util_substitute("foo", "o", "YZ")));
514  FAIL_UNLESS("owl_util_substitute 3",
515              !strcmp("foo", owl_util_substitute("fYZYZ", "YZ", "o")));
516  FAIL_UNLESS("owl_util_substitute 4",
517              !strcmp("/u/foo/meep", owl_util_substitute("~/meep", "~", "/u/foo")));
518
519  FAIL_UNLESS("skiptokens 1", 
520              !strcmp("bar quux", skiptokens("foo bar quux", 1)));
521  FAIL_UNLESS("skiptokens 2", 
522              !strcmp("meep", skiptokens("foo 'bar quux' meep", 2)));
523
524  FAIL_UNLESS("owl_util_uniq 1", 
525              !strcmp("foo bar x", owl_util_uniq("foo", "bar x", "-")));
526  FAIL_UNLESS("owl_util_uniq 2", 
527              !strcmp("foo bar x", owl_util_uniq("foo", "bar -y x", "-")));
528  FAIL_UNLESS("owl_util_uniq 3", 
529              !strcmp("meep foo bar", owl_util_uniq("meep foo", "bar foo meep", "-")));
530
531  if (numfailed) printf("*** WARNING: failures encountered with owl_util\n");
532  printf("END testing owl_util (%d failures)\n", numfailed);
533  return(numfailed);
534}
535
536#endif /* OWL_INCLUDE_REG_TESTS */
Note: See TracBrowser for help on using the repository browser.