source: util.c @ f4d0975

barnowl_perlaimdebianowlrelease-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since f4d0975 was f1e629d, checked in by Erik Nygren <nygren@mit.edu>, 18 years ago
New API for perl message formatting functions. Legacy variables are still supported for owl::format_msg and owl::receive_msg, but these functions are now also passed an owl::Message object which contains methods for accessing the contents of the message. See perlwrap.pm (and docs TBD) for the available methods. *** WARNING: The exact API for owl::Message has *** not yet stabilized. Added "style" command for creating new styles. Usage: style <name> perl <function_name> Added support for "show styles". Changed global style table from list to dictionary. Changed AIM password prompt from "Password:" to "AIM Password:". Messages are reformatted after a window resize to allow styles to take into account the width of the window. When perl throws an error, the message is put in the msgwin if possible. Added perl functions for: owl::getcurmsg() -- returns an owl::Message object for the active message in the current view. owl::getnumcols() -- returns the column width of the window owl::zephyr_getrealm() -- returns the zephyr realm owl::zephyr_getsender() -- returns the zephyr sender Made owl::COMMAND("foo"); be syntactic sugar for owl::command("COMMAND foo"); *** Is this a good or bad idea? *** This feature may be taken out before release. Added perlwrap.pm to contain perl code to be compiled into the binary. This is transformed into perlwrap.c by encapsulate.pl. Renamed readconfig.c to perlconfig.c and changed variables accordingly. Minor bugfixes in cmd.c and commands.c
  • Property mode set to 100644
File size: 19.2 KB
Line 
1#include "owl.h"
2#include <stdlib.h>
3#include <string.h>
4#include <unistd.h>
5#include <unistd.h>
6#include <ctype.h>
7
8static const char fileIdent[] = "$Id$";
9
10void sepbar(char *in)
11{
12  char buff[1024];
13  WINDOW *sepwin;
14  owl_messagelist *ml;
15  owl_view *v;
16  int x, y, i;
17  char *foo, *appendtosepbar;
18
19  sepwin=owl_global_get_curs_sepwin(&g);
20  ml=owl_global_get_msglist(&g);
21  v=owl_global_get_current_view(&g);
22
23  werase(sepwin);
24  wattron(sepwin, A_REVERSE);
25  whline(sepwin, ACS_HLINE, owl_global_get_cols(&g));
26
27  if (owl_global_is_sepbar_disable(&g)) {
28    getyx(sepwin, y, x);
29    wmove(sepwin, y, owl_global_get_cols(&g)-1);
30    return;
31  }
32
33  wmove(sepwin, 0, 2); 
34
35  if (owl_messagelist_get_size(ml)==0) {
36    strcpy(buff, " (-/-) ");
37  } else {
38    snprintf(buff, 1024, " (%i/%i/%i) ", owl_global_get_curmsg(&g)+1,
39            owl_view_get_size(v),
40            owl_messagelist_get_size(ml));
41  }
42  waddstr(sepwin, buff);
43
44  foo=owl_view_get_filtname(v);
45  if (strcmp(foo, "all")) wattroff(sepwin, A_REVERSE);
46  waddstr(sepwin, " ");
47  waddstr(sepwin, owl_view_get_filtname(v));
48  waddstr(sepwin, " ");
49  if (strcmp(foo, "all")) wattron(sepwin, A_REVERSE);
50
51  if (owl_mainwin_is_curmsg_truncated(owl_global_get_mainwin(&g))) {
52    getyx(sepwin, y, x);
53    wmove(sepwin, y, x+2);
54    wattron(sepwin, A_BOLD);
55    waddstr(sepwin, " <truncated> ");
56    wattroff(sepwin, A_BOLD);
57  }
58
59  i=owl_mainwin_get_last_msg(owl_global_get_mainwin(&g));
60  if ((i != -1) &&
61      (i < owl_view_get_size(v)-1)) {
62    getyx(sepwin, y, x);
63    wmove(sepwin, y, x+2);
64    wattron(sepwin, A_BOLD);
65    waddstr(sepwin, " <more> ");
66    wattroff(sepwin, A_BOLD);
67  }
68
69  if (owl_global_get_rightshift(&g)>0) {
70    getyx(sepwin, y, x);
71    wmove(sepwin, y, x+2);
72    snprintf(buff, 1024, " right: %i ", owl_global_get_rightshift(&g));
73    waddstr(sepwin, buff);
74  }
75
76  if (owl_global_is_zaway(&g)) {
77    getyx(sepwin, y, x);
78    wmove(sepwin, y, x+2);
79    wattron(sepwin, A_BOLD);
80    wattroff(sepwin, A_REVERSE);
81    waddstr(sepwin, " ZAWAY ");
82    wattron(sepwin, A_REVERSE);
83    wattroff(sepwin, A_BOLD);
84  }
85
86  if (owl_global_get_curmsg_vert_offset(&g)) {
87    getyx(sepwin, y, x);
88    wmove(sepwin, y, x+2);
89    wattron(sepwin, A_BOLD);
90    wattroff(sepwin, A_REVERSE);
91    waddstr(sepwin, " SCROLL ");
92    wattron(sepwin, A_REVERSE);
93    wattroff(sepwin, A_BOLD);
94  }
95 
96  if (in) {
97    getyx(sepwin, y, x);
98    wmove(sepwin, y, x+2);
99    waddstr(sepwin, in);
100  }
101
102  appendtosepbar = owl_global_get_appendtosepbar(&g);
103  if (appendtosepbar && *appendtosepbar) {
104    getyx(sepwin, y, x);
105    wmove(sepwin, y, x+2);
106    waddstr(sepwin, " ");
107    waddstr(sepwin, owl_global_get_appendtosepbar(&g));
108    waddstr(sepwin, " ");
109  }
110
111  getyx(sepwin, y, x);
112  wmove(sepwin, y, owl_global_get_cols(&g)-1);
113   
114  wattroff(sepwin, A_BOLD);
115  wattroff(sepwin, A_REVERSE);
116  wnoutrefresh(sepwin);
117}
118
119
120void pophandler_quit(int ch)
121{
122  if (ch=='q') {
123    owl_popwin_close(owl_global_get_popwin(&g));
124  }
125}
126
127char **atokenize(char *buffer, char *sep, int *i)
128{
129  /* each element of return must be freed by user */
130  char **args;
131  char *workbuff, *foo;
132  int done=0, first=1, count=0;
133
134  workbuff=owl_malloc(strlen(buffer)+1);
135  memcpy(workbuff, buffer, strlen(buffer)+1);
136
137  args=NULL;
138  while (!done) {
139    if (first) {
140      first=0;
141      foo=(char *)strtok(workbuff, sep);
142    } else {
143      foo=(char *)strtok(NULL, sep);
144    }
145    if (foo==NULL) {
146      done=1;
147    } else {
148      args=(char **)owl_realloc(args, sizeof(char *) * (count+1));
149      args[count]=owl_malloc(strlen(foo)+1);
150      strcpy(args[count], foo);
151      count++;
152    }
153  }
154  *i=count;
155  owl_free(workbuff);
156  return(args);
157}
158
159char *skiptokens(char *buff, int n) {
160  /* skips n tokens and returns where that would be.
161   * TODO: handle quotes more sanely. */
162 
163  int inquotes=0;
164  while (*buff && n>0) {
165      while (*buff == ' ') buff++;
166      while (*buff && (inquotes || *buff != ' ')) { 
167        if (*buff == '"' || *buff == '\'') inquotes=!inquotes;
168        buff++;
169      }
170      while (*buff == ' ') buff++;
171      n--;
172  }
173  return buff;
174}
175
176void atokenize_free(char **tok, int nels)
177{
178  int i;
179  for (i=0; i<nels; i++) {
180    owl_free(tok[i]);
181  }
182  owl_free(tok);
183}
184
185
186void owl_parsefree(char **argv, int argc)
187{
188  int i;
189
190  if (!argv) return;
191 
192  for (i=0; i<argc; i++) {
193    if (argv[i]) owl_free(argv[i]);
194  }
195  owl_free(argv);
196}
197
198char **owl_parseline(char *line, int *argc)
199{
200  /* break a command line up into argv, argc.  The caller must free
201     the returned values.  If there is an error argc will be set to
202     -1, argv will be NULL and the caller does not need to free
203     anything */
204
205  char **argv;
206  int i, len, between=1;
207  char *curarg;
208  char quote;
209
210  argv=owl_malloc(sizeof(char *));
211  len=strlen(line);
212  curarg=owl_malloc(len+10);
213  strcpy(curarg, "");
214  quote='\0';
215  *argc=0;
216  for (i=0; i<len+1; i++) {
217    /* find the first real character */
218    if (between) {
219      if (line[i]==' ' || line[i]=='\t' || line[i]=='\0') {
220        continue;
221      } else {
222        between=0;
223        i--;
224        continue;
225      }
226    }
227
228    /* deal with a quote character */
229    if (line[i]=='"' || line[i]=="'"[0]) {
230      /* if this type of quote is open, close it */
231      if (quote==line[i]) {
232        quote='\0';
233        continue;
234      }
235
236      /* if no quoting is open then open with this */
237      if (quote=='\0') {
238        quote=line[i];
239        continue;
240      }
241
242      /* if another type of quote is open then treat this as a literal */
243      curarg[strlen(curarg)+1]='\0';
244      curarg[strlen(curarg)]=line[i];
245      continue;
246    }
247
248    /* if it's not a space or end of command, then use it */
249    if (line[i]!=' ' && line[i]!='\t' && line[i]!='\n' && line[i]!='\0') {
250      curarg[strlen(curarg)+1]='\0';
251      curarg[strlen(curarg)]=line[i];
252      continue;
253    }
254
255    /* otherwise, if we're not in quotes, add the whole argument */
256    if (quote=='\0') {
257      /* add the argument */
258      argv=owl_realloc(argv, sizeof(char *)*((*argc)+1));
259      argv[*argc]=owl_malloc(strlen(curarg)+2);
260      strcpy(argv[*argc], curarg);
261      *argc=*argc+1;
262      strcpy(curarg, "");
263      between=1;
264      continue;
265    }
266
267    /* if it is a space and we're in quotes, then use it */
268    curarg[strlen(curarg)+1]='\0';
269    curarg[strlen(curarg)]=line[i];
270  }
271
272  /* check for unbalanced quotes */
273  if (quote!='\0') {
274    owl_parsefree(argv, *argc);
275    *argc=-1;
276    return(NULL);
277  }
278
279  return(argv);
280}
281
282/* caller must free the return */
283char *owl_util_minutes_to_timestr(int in)
284{
285  int days, hours;
286  long run;
287  char *out;
288
289  run=in;
290
291  days=run/1440;
292  run-=days*1440;
293  hours=run/60;
294  run-=hours*60;
295
296  if (days>0) {
297    out=owl_sprintf("%i d %2.2i:%2.2i", days, hours, run);
298  } else {
299    out=owl_sprintf("    %2.2i:%2.2i", hours, run);
300  }
301  return(out);
302}
303
304
305/* return the index of the last char before a change from the first one */
306int owl_util_find_trans(char *in, int len)
307{
308  int i;
309  for (i=1; i<len; i++) {
310    if (in[i] != in[0]) return(i-1);
311  }
312  return(i);
313}
314
315
316/* downcase the string 'foo' */
317void downstr(char *foo)
318{
319  int i;
320  for (i=0; foo[i]!='\0'; i++) {
321    foo[i]=tolower(foo[i]);
322  }
323}
324
325/* exactly like strstr but case insensitive */
326char *stristr(char *a, char *b)
327{
328  char *x, *y, *ret;
329
330  if ((x=owl_strdup(a))==NULL) return(NULL);
331  if ((y=owl_strdup(b))==NULL) return(NULL);
332  downstr(x);
333  downstr(y);
334  ret=strstr(x, y);
335  if (ret==NULL) {
336    owl_free(x);
337    owl_free(y);
338    return(NULL);
339  }
340  ret=ret-x+a;
341  owl_free(x);
342  owl_free(y);
343  return(ret);
344}
345
346/* Caller must free response.
347 * Takes in strings which are space-separated lists of tokens
348 * and returns a single string containing no token more than once.
349 * If prohibit is non-null, no token may start with a character
350 * in prohibit.
351 */
352char *owl_util_uniq(char *A, char *B, char *prohibit)
353{
354 
355  char *cat, **tok;
356  int toklen, i, j, first=1;
357  cat = owl_malloc(strlen(A)+strlen(B)+3);
358  strcpy(cat, A);
359  strcat(cat, " ");
360  strcat(cat, B);
361  tok = atokenize(cat, " ", &toklen);
362  strcpy(cat, "");
363  for (i=0; i<toklen; i++) {
364    int dup=0;
365    for (j=0; j<i; j++) {
366      if (!strcmp(tok[i], tok[j])) dup=1;
367    }
368    if (!dup && (!prohibit || !strchr(prohibit, tok[i][0]))) {
369      if (!first) {
370        strcat(cat, " ");
371      }
372      first=0;
373      strcat(cat, tok[i]);
374    }
375  }
376  atokenize_free(tok, toklen);
377  return(cat);
378}
379
380/* return 1 if a string is only whitespace, otherwise 0 */
381int only_whitespace(char *s)
382{
383  int i;
384  for (i=0; s[i]; i++) {
385    if (!isspace((int) s[i])) return(0);
386  }
387  return(1);
388}
389
390/* hooks for doing memory allocation et. al. in owl */
391
392void *owl_malloc(size_t size)
393{
394  return(malloc(size));
395}
396
397void owl_free(void *ptr)
398{
399  free(ptr);
400}
401
402char *owl_strdup(const char *s1)
403{
404  return(strdup(s1));
405}
406
407void *owl_realloc(void *ptr, size_t size)
408{
409  return(realloc(ptr, size));
410}
411
412
413/* allocates memory and returns the string or null.
414 * caller must free the string.
415 * from Linux sprintf man page.
416 */
417char *owl_sprintf(const char *fmt, ...)
418{
419  int n, size = 100;
420  char *p;
421  va_list ap;
422  if ((p = owl_malloc (size)) == NULL) return (NULL);
423  while (1) {
424    /* Try to print in the allocated space. */
425    va_start(ap, fmt);
426    n = vsnprintf (p, size, fmt, ap);
427    va_end(ap);
428    /* If that worked, return the string. */
429    if (n > -1 && n < size)
430      return p;
431    /* Else try again with more space. */
432    if (n > -1)    /* glibc 2.1 */
433      size = n+1; /* precisely what is needed */
434    else           /* glibc 2.0 */
435      size *= 2;  /* twice the old size */
436    if ((p = owl_realloc (p, size)) == NULL)
437      return NULL;
438  }
439}
440
441/* Strip a local realm fron the zephyr user name.
442 * The caller must free the return
443 */
444char *short_zuser(char *in)
445{
446  char *out, *ptr;
447
448  out=owl_strdup(in);
449  ptr=strchr(out, '@');
450  if (ptr) {
451    if (!strcasecmp(ptr+1, owl_zephyr_get_realm())) {
452      *ptr='\0';
453    }
454  }
455  return(out);
456}
457
458/* Append a local realm to the zephyr user name if necessary.
459 * The caller must free the return.
460 */
461char *long_zuser(char *in)
462{
463  char *ptr;
464
465  if (NULL != (ptr=strchr(in, '@'))) {
466    return owl_strdup(in);
467  } else {
468    return owl_sprintf("%s@%s", in, owl_zephyr_get_realm());
469  }
470}
471
472
473/* strip out the instance from a zsender's principal.  Preserves the
474 * realm if present.  daemon.webzephyr is a special case.  The
475 * caller must free the return
476 */
477char *owl_util_smartstripped_user(char *in)
478{
479  char *ptr, *realm, *out;
480
481  out=owl_strdup(in);
482
483  /* bail immeaditly if we don't have to do any work */
484  ptr=strchr(in, '.');
485  if (!strchr(in, '/') && !ptr) {
486    /* no '/' and no '.' */
487    return(out);
488  }
489  if (ptr && strchr(in, '@') && (ptr > strchr(in, '@'))) {
490    /* There's a '.' but it's in the realm */
491    return(out);
492  }
493  if (!strncasecmp(in, OWL_WEBZEPHYR_PRINCIPAL, strlen(OWL_WEBZEPHYR_PRINCIPAL))) {
494    return(out);
495  }
496
497  /* remove the realm from ptr, but hold on to it */
498  realm=strchr(out, '@');
499  if (realm) realm[0]='\0';
500
501  /* strip */
502  ptr=strchr(out, '.');
503  if (!ptr) ptr=strchr(out, '/');
504  ptr[0]='\0';
505
506  /* reattach the realm if we had one */
507  if (realm) {
508    strcat(out, "@");
509    strcat(out, realm+1);
510  }
511
512  return(out);
513}
514
515char *owl_getquoting(char *line)
516{
517  if (line[0]=='\0') return("'");
518  if (strchr(line, '\'')) return("\"");
519  if (strchr(line, '"')) return("'");
520  if (strchr(line, ' ')) return("'");
521  return("");
522}
523
524
525
526/* Return a string with any occurances of 'from' replaced with 'to'.
527 * Does not currently handle backslash quoting, but may in the future.
528 * Caller must free returned string.
529 */
530char *owl_util_substitute(char *in, char *from, char *to)
531{
532 
533  char *out;
534  int   outlen, tolen, fromlen, inpos=0, outpos=0;
535
536  if (!*from) return owl_strdup(in);
537
538  outlen = strlen(in)+1;
539  tolen  = strlen(to);
540  fromlen  = strlen(from);
541  out = malloc(outlen);
542
543  while (in[inpos]) {
544    if (!strncmp(in+inpos, from, fromlen)) {
545      outlen += tolen;
546      out = owl_realloc(out, outlen);
547      strcpy(out+outpos, to);
548      inpos += fromlen;
549      outpos += tolen;
550    } else {
551      out[outpos] = in[inpos];
552      inpos++; outpos++;
553    }
554  }
555  out[outpos] = '\0';
556  return(out);
557}
558
559/* replace all instances of character a in buff with the character
560 * b.  buff must be null terminated.
561 */
562void owl_util_tr(char *buff, char a, char b)
563{
564  int i;
565
566  owl_function_debugmsg("In: %s", buff);
567  for (i=0; buff[i]!='\0'; i++) {
568    if (buff[i]==a) buff[i]=b;
569  }
570  owl_function_debugmsg("Out: %s", buff);
571}
572
573
574/* Return the owl color associated with the named color */
575int owl_util_string_to_color(char *color)
576{
577  if (!strcasecmp(color, "black")) {
578    return(OWL_COLOR_BLACK);
579  } else if (!strcasecmp(color, "red")) {
580    return(OWL_COLOR_RED);
581  } else if (!strcasecmp(color, "green")) {
582    return(OWL_COLOR_GREEN);
583  } else if (!strcasecmp(color, "yellow")) {
584    return(OWL_COLOR_YELLOW);
585  } else if (!strcasecmp(color, "blue")) {
586    return(OWL_COLOR_BLUE);
587  } else if (!strcasecmp(color, "magenta")) {
588    return(OWL_COLOR_MAGENTA);
589  } else if (!strcasecmp(color, "cyan")) {
590    return(OWL_COLOR_CYAN);
591  } else if (!strcasecmp(color, "white")) {
592    return(OWL_COLOR_WHITE);
593  } else if (!strcasecmp(color, "default")) {
594    return(OWL_COLOR_DEFAULT);
595  }
596  return(OWL_COLOR_DEFAULT);
597}
598
599/* Return a string name of the given owl color */
600char *owl_util_color_to_string(int color)
601{
602  if (color==OWL_COLOR_BLACK)   return("black");
603  if (color==OWL_COLOR_RED)     return("red");
604  if (color==OWL_COLOR_GREEN)   return("green");
605  if (color==OWL_COLOR_YELLOW)  return("yellow");
606  if (color==OWL_COLOR_BLUE)    return("blue");
607  if (color==OWL_COLOR_MAGENTA) return("magenta");
608  if (color==OWL_COLOR_CYAN)    return("cyan");
609  if (color==OWL_COLOR_WHITE)   return("white");
610  if (color==OWL_COLOR_DEFAULT) return("default");
611  return("Unknown color");
612}
613
614/* Get the default tty name.  Caller must free the return */
615char *owl_util_get_default_tty()
616{
617  char *out, *tmp;
618
619  if (getenv("DISPLAY")) {
620    out=owl_strdup(getenv("DISPLAY"));
621  } else if ((tmp=ttyname(fileno(stdout)))!=NULL) {
622    out=owl_strdup(tmp);
623    if (!strncmp(out, "/dev/", 5)) {
624      owl_free(out);
625      out=owl_strdup(tmp+5);
626    }
627  } else {
628    out=owl_strdup("unknown");
629  }
630  return(out);
631}
632
633
634/* Animation hack */
635void owl_hack_animate()
636{
637  owl_messagelist *ml;
638  owl_message *m;
639  owl_fmtext *fm;
640  char *text, *ptr;
641  int place;
642
643  /* grab the first message and make sure its id is 0 */
644  ml=owl_global_get_msglist(&g);
645  m=owl_messagelist_get_element(ml, 0);
646  if (!m) return;
647  if (owl_message_get_id(m)!=0) return;
648
649  fm=owl_message_get_fmtext(m);
650  text=owl_fmtext_get_text(fm);
651
652  ptr=strstr(text, "OvO");
653  if (ptr) {
654    place=ptr-text;
655    owl_fmtext_set_char(fm, place, '-');
656    owl_fmtext_set_char(fm, place+2, '-');
657
658    owl_mainwin_redisplay(owl_global_get_mainwin(&g));
659    if (owl_popwin_is_active(owl_global_get_popwin(&g))) {
660      owl_popwin_refresh(owl_global_get_popwin(&g));
661      /* TODO: this is a broken kludge */
662      if (owl_global_get_viewwin(&g)) {
663        owl_viewwin_redisplay(owl_global_get_viewwin(&g), 0);
664      }
665    }
666    owl_global_set_needrefresh(&g);
667    return;
668  }
669
670  ptr=strstr(text, "-v-");
671  if (ptr) {
672    place=ptr-text;
673    owl_fmtext_set_char(fm, place, 'O');
674    owl_fmtext_set_char(fm, place+2, 'O');
675
676    owl_mainwin_redisplay(owl_global_get_mainwin(&g));
677    if (owl_popwin_is_active(owl_global_get_popwin(&g))) {
678      owl_popwin_refresh(owl_global_get_popwin(&g));
679      /* TODO: this is a broken kludge */
680      if (owl_global_get_viewwin(&g)) {
681        owl_viewwin_redisplay(owl_global_get_viewwin(&g), 0);
682      }
683    }
684    owl_global_set_needrefresh(&g);
685    return;
686  }
687}
688
689/* strip leading and trailing new lines.  Caller must free the
690 * return.
691 */
692char *owl_util_stripnewlines(char *in)
693{
694 
695  char  *tmp, *ptr1, *ptr2, *out;
696
697  ptr1=tmp=owl_strdup(in);
698  while (ptr1[0]=='\n') {
699    ptr1++;
700  }
701  ptr2=ptr1+strlen(ptr1)-1;
702  while (ptr2[0]=='\n' && ptr2>ptr1) {
703    ptr2[0]='\0';
704    ptr2--;
705  }
706
707  out=owl_strdup(ptr1);
708  owl_free(tmp);
709  return(out);
710}
711
712/* Delete the line matching "line" from the named file.  If no such
713 * line is found the file is left intact.  If backup==1 then create a
714 * backupfile containing the original contents.  This is an
715 * inefficient impelementation which reads the entire file into
716 * memory.
717 */
718void owl_util_file_deleteline(char *filename, char *line, int backup)
719{
720  char buff[LINE], *text;
721  char *backupfilename="";
722  FILE *file, *backupfile=NULL;
723  int size, newline;
724
725  /* open the file for reading */
726  file=fopen(filename, "r");
727  if (!file) {
728    owl_function_makemsg("Error opening file %s", filename);
729    return;
730  }
731
732  /* open the backup file for writing */
733  if (backup) {
734    backupfilename=owl_sprintf("%s.backup", filename);
735    backupfile=fopen(backupfilename, "w");
736    if (!backupfile) {
737      owl_function_makemsg("Error opening file %s for writing", backupfilename);
738      owl_free(backupfilename);
739      return;
740    }
741    owl_free(backupfilename);
742  }
743
744  /* we'll read the entire file into memory, minus the line we don't want and
745   * and at the same time create the backup file if necessary
746   */
747  text=owl_malloc(LINE);
748  strcpy(text, "");
749  size=LINE;
750  while (fgets(buff, LINE, file)!=NULL) {
751    /* strip the newline */
752    newline=0;
753    if (buff[strlen(buff)-1]=='\n') {
754      buff[strlen(buff)-1]='\0';
755      newline=1;
756    }
757   
758    /* if we don't match the line, add to saved text in memory */
759    if (strcasecmp(buff, line)) {
760      size+=LINE;
761      text=owl_realloc(text, size);
762      strcat(text, buff);
763      if (newline) strcat(text, "\n");
764    }
765
766    /* write to backupfile if necessary */
767    if (backup) fputs(buff, backupfile);
768  }
769  if (backup) fclose(backupfile);
770  fclose(file);
771
772  /* now rewrite the original file from memory */
773  file=fopen(filename, "w");
774  if (!file) {
775    owl_function_makemsg("WARNING: Error opening %s for writing.  Use %s to restore.", filename, backupfilename);
776    owl_function_beep();
777    owl_free(line);
778    return;
779  }
780
781  fputs(text, file);
782  fclose(file);
783}
784
785/**************************************************************************/
786/************************* REGRESSION TESTS *******************************/
787/**************************************************************************/
788
789#ifdef OWL_INCLUDE_REG_TESTS
790
791#define FAIL_UNLESS(desc,pred) printf("\t%-4s: %s\n", (pred)?"ok":(numfailed++,"FAIL"), desc)
792
793int owl_util_regtest(void)
794{
795  int numfailed=0;
796
797  printf("BEGIN testing owl_util\n");
798
799  FAIL_UNLESS("owl_util_substitute 1",
800              !strcmp("foo", owl_util_substitute("foo", "", "Y")));
801  FAIL_UNLESS("owl_util_substitute 2",
802              !strcmp("fYZYZ", owl_util_substitute("foo", "o", "YZ")));
803  FAIL_UNLESS("owl_util_substitute 3",
804              !strcmp("foo", owl_util_substitute("fYZYZ", "YZ", "o")));
805  FAIL_UNLESS("owl_util_substitute 4",
806              !strcmp("/u/foo/meep", owl_util_substitute("~/meep", "~", "/u/foo")));
807
808  FAIL_UNLESS("skiptokens 1", 
809              !strcmp("bar quux", skiptokens("foo bar quux", 1)));
810  FAIL_UNLESS("skiptokens 2", 
811              !strcmp("meep", skiptokens("foo 'bar quux' meep", 2)));
812
813  FAIL_UNLESS("owl_util_uniq 1", 
814              !strcmp("foo bar x", owl_util_uniq("foo", "bar x", "-")));
815  FAIL_UNLESS("owl_util_uniq 2", 
816              !strcmp("foo bar x", owl_util_uniq("foo", "bar -y x", "-")));
817  FAIL_UNLESS("owl_util_uniq 3", 
818              !strcmp("meep foo bar", owl_util_uniq("meep foo", "bar foo meep", "-")));
819
820  if (numfailed) printf("*** WARNING: failures encountered with owl_util\n");
821  printf("END testing owl_util (%d failures)\n", numfailed);
822  return(numfailed);
823}
824
825#endif /* OWL_INCLUDE_REG_TESTS */
Note: See TracBrowser for help on using the repository browser.