source: util.c @ de03334

barnowl_perlaimdebianowlrelease-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since de03334 was de03334, checked in by James M. Kretchmar <kretch@mit.edu>, 18 years ago
Idletimes now appear in the buddylist
  • Property mode set to 100644
File size: 19.2 KB
RevLine 
[7d4fbcd]1#include "owl.h"
2#include <stdlib.h>
3#include <string.h>
[5145235]4#include <unistd.h>
[486688f]5#include <unistd.h>
[7d4fbcd]6#include <ctype.h>
7
[1aee7d9]8static const char fileIdent[] = "$Id$";
9
[e4eebe8]10void sepbar(char *in)
11{
[7d4fbcd]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
[73624b4]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
[7d4fbcd]33  wmove(sepwin, 0, 2); 
34
35  if (owl_messagelist_get_size(ml)==0) {
36    strcpy(buff, " (-/-) ");
37  } else {
[1c6c4d3]38    snprintf(buff, 1024, " (%i/%i/%i) ", owl_global_get_curmsg(&g)+1,
[7d4fbcd]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);
[1c6c4d3]72    snprintf(buff, 1024, " right: %i ", owl_global_get_rightshift(&g));
[7d4fbcd]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
[e4eebe8]120void pophandler_quit(int ch)
121{
[7d4fbcd]122  if (ch=='q') {
123    owl_popwin_close(owl_global_get_popwin(&g));
124  }
125}
126
[e4eebe8]127char **atokenize(char *buffer, char *sep, int *i)
128{
[7d4fbcd]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) {
[42abb10]160  /* skips n tokens and returns where that would be.
161   * TODO: handle quotes more sanely. */
162 
[7d4fbcd]163  int inquotes=0;
164  while (*buff && n>0) {
165      while (*buff == ' ') buff++;
166      while (*buff && (inquotes || *buff != ' ')) { 
[e1c4636]167        if (*buff == '"' || *buff == '\'') inquotes=!inquotes;
[7d4fbcd]168        buff++;
169      }
170      while (*buff == ' ') buff++;
171      n--;
172  }
173  return buff;
174}
175
[e4eebe8]176void atokenize_free(char **tok, int nels)
177{
[7d4fbcd]178  int i;
179  for (i=0; i<nels; i++) {
180    owl_free(tok[i]);
181  }
182  owl_free(tok);
183}
184
185
[e4eebe8]186void owl_parsefree(char **argv, int argc)
187{
[7d4fbcd]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
[e4eebe8]198char **owl_parseline(char *line, int *argc)
199{
[7d4fbcd]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
[de03334]282/* caller must free the return */
283char *owl_util_seconds_to_timestr(int seconds)
284{
285  int days, minutes, hours;
286  long run;
287  char *out;
288
289  run=seconds;
290
291  days=run/86400;
292  run-=days*86400;
293  hours=run/3600;
294  run-=hours*3600;
295  minutes=run/60;
296  run-=minutes*60;
297
298  if (days>0) {
299    out=owl_sprintf("%i d %2.2i:%2.2i:%2.2li", days, hours, minutes, run);
300  } else {
301    out=owl_sprintf("     %2.2i:%2.2i:%2.2li", hours, minutes, run);
302  }
303  return(out);
304}
305
[7d4fbcd]306
[e4eebe8]307/* return the index of the last char before a change from the first one */
308int owl_util_find_trans(char *in, int len)
309{
[7d4fbcd]310  int i;
311  for (i=1; i<len; i++) {
312    if (in[i] != in[0]) return(i-1);
313  }
314  return(i);
315}
316
317
[e4eebe8]318/* downcase the string 'foo' */
319void downstr(char *foo)
320{
[7d4fbcd]321  int i;
322  for (i=0; foo[i]!='\0'; i++) {
323    foo[i]=tolower(foo[i]);
324  }
325}
326
[e4eebe8]327/* exactly like strstr but case insensitive */
328char *stristr(char *a, char *b)
329{
[7d4fbcd]330  char *x, *y, *ret;
331
332  if ((x=owl_strdup(a))==NULL) return(NULL);
333  if ((y=owl_strdup(b))==NULL) return(NULL);
334  downstr(x);
335  downstr(y);
336  ret=strstr(x, y);
[1fd0b25]337  if (ret==NULL) {
338    owl_free(x);
339    owl_free(y);
340    return(NULL);
341  }
342  ret=ret-x+a;
[7d4fbcd]343  owl_free(x);
344  owl_free(y);
345  return(ret);
346}
347
[e4eebe8]348/* Caller must free response.
349 * Takes in strings which are space-separated lists of tokens
350 * and returns a single string containing no token more than once.
351 * If prohibit is non-null, no token may start with a character
352 * in prohibit.
353 */
354char *owl_util_uniq(char *A, char *B, char *prohibit)
355{
[42abb10]356 
[e50cd56]357  char *cat, **tok;
358  int toklen, i, j, first=1;
359  cat = owl_malloc(strlen(A)+strlen(B)+3);
360  strcpy(cat, A);
361  strcat(cat, " ");
362  strcat(cat, B);
363  tok = atokenize(cat, " ", &toklen);
364  strcpy(cat, "");
365  for (i=0; i<toklen; i++) {
366    int dup=0;
367    for (j=0; j<i; j++) {
368      if (!strcmp(tok[i], tok[j])) dup=1;
369    }
370    if (!dup && (!prohibit || !strchr(prohibit, tok[i][0]))) {
371      if (!first) {
372        strcat(cat, " ");
373      }
374      first=0;
375      strcat(cat, tok[i]);
376    }
377  }
378  atokenize_free(tok, toklen);
379  return(cat);
380}
381
[e4eebe8]382/* return 1 if a string is only whitespace, otherwise 0 */
383int only_whitespace(char *s)
384{
[10b866d]385  int i;
386  for (i=0; s[i]; i++) {
[1fd0b25]387    if (!isspace((int) s[i])) return(0);
[10b866d]388  }
389  return(1);
390}
[7d4fbcd]391
[42abb10]392/* hooks for doing memory allocation et. al. in owl */
393
[e4eebe8]394void *owl_malloc(size_t size)
395{
[7d4fbcd]396  return(malloc(size));
397}
398
[e4eebe8]399void owl_free(void *ptr)
400{
[7d4fbcd]401  free(ptr);
402}
403
[e4eebe8]404char *owl_strdup(const char *s1)
405{
[7d4fbcd]406  return(strdup(s1));
407}
408
[e4eebe8]409void *owl_realloc(void *ptr, size_t size)
410{
[7d4fbcd]411  return(realloc(ptr, size));
412}
413
[e4eebe8]414
415/* allocates memory and returns the string or null.
416 * caller must free the string.
417 * from Linux sprintf man page.
418 */
419char *owl_sprintf(const char *fmt, ...)
420{
[1c6c4d3]421  int n, size = 100;
422  char *p;
423  va_list ap;
[42abb10]424  if ((p = owl_malloc (size)) == NULL) return (NULL);
[1c6c4d3]425  while (1) {
426    /* Try to print in the allocated space. */
427    va_start(ap, fmt);
428    n = vsnprintf (p, size, fmt, ap);
429    va_end(ap);
430    /* If that worked, return the string. */
431    if (n > -1 && n < size)
432      return p;
433    /* Else try again with more space. */
434    if (n > -1)    /* glibc 2.1 */
435      size = n+1; /* precisely what is needed */
436    else           /* glibc 2.0 */
437      size *= 2;  /* twice the old size */
438    if ((p = owl_realloc (p, size)) == NULL)
439      return NULL;
440  }
441}
442
[e4eebe8]443/* Strip a local realm fron the zephyr user name.
444 * The caller must free the return
445 */
446char *short_zuser(char *in)
447{
[be97670]448  char *out, *ptr;
449
[7d4fbcd]450  out=owl_strdup(in);
451  ptr=strchr(out, '@');
452  if (ptr) {
[09489b89]453    if (!strcasecmp(ptr+1, owl_zephyr_get_realm())) {
[7d4fbcd]454      *ptr='\0';
455    }
456  }
457  return(out);
458}
459
[e4eebe8]460/* Append a local realm to the zephyr user name if necessary.
461 * The caller must free the return.
462 */
463char *long_zuser(char *in)
464{
[1c6c4d3]465  char *ptr;
[7d4fbcd]466
[1c6c4d3]467  if (NULL != (ptr=strchr(in, '@'))) {
468    return owl_strdup(in);
469  } else {
[09489b89]470    return owl_sprintf("%s@%s", in, owl_zephyr_get_realm());
[1c6c4d3]471  }
[7d4fbcd]472}
[f9c43ae]473
474
[e4eebe8]475/* strip out the instance from a zsender's principal.  Preserves the
476 * realm if present.  daemon.webzephyr is a special case.  The
477 * caller must free the return
478 */
479char *owl_util_smartstripped_user(char *in)
480{
[f9c43ae]481  char *ptr, *realm, *out;
482
483  out=owl_strdup(in);
484
485  /* bail immeaditly if we don't have to do any work */
486  ptr=strchr(in, '.');
487  if (!strchr(in, '/') && !ptr) {
[5a6e6b9]488    /* no '/' and no '.' */
[f9c43ae]489    return(out);
490  }
491  if (ptr && strchr(in, '@') && (ptr > strchr(in, '@'))) {
[5a6e6b9]492    /* There's a '.' but it's in the realm */
[f9c43ae]493    return(out);
494  }
[e7cc1c3]495  if (!strncasecmp(in, OWL_WEBZEPHYR_PRINCIPAL, strlen(OWL_WEBZEPHYR_PRINCIPAL))) {
[5a6e6b9]496    return(out);
497  }
498
[f9c43ae]499  /* remove the realm from ptr, but hold on to it */
500  realm=strchr(out, '@');
501  if (realm) realm[0]='\0';
502
503  /* strip */
504  ptr=strchr(out, '.');
505  if (!ptr) ptr=strchr(out, '/');
506  ptr[0]='\0';
507
508  /* reattach the realm if we had one */
509  if (realm) {
510    strcat(out, "@");
511    strcat(out, realm+1);
512  }
513
514  return(out);
515}
[7d4fbcd]516
[e4eebe8]517char *owl_getquoting(char *line)
518{
[7d4fbcd]519  if (line[0]=='\0') return("'");
520  if (strchr(line, '\'')) return("\"");
521  if (strchr(line, '"')) return("'");
522  if (strchr(line, ' ')) return("'");
523  return("");
524}
525
[e4eebe8]526
527
528/* Return a string with any occurances of 'from' replaced with 'to'.
529 * Does not currently handle backslash quoting, but may in the future.
530 * Caller must free returned string.
531 */
532char *owl_util_substitute(char *in, char *from, char *to)
533{
[42abb10]534 
[e1c4636]535  char *out;
536  int   outlen, tolen, fromlen, inpos=0, outpos=0;
537
538  if (!*from) return owl_strdup(in);
539
540  outlen = strlen(in)+1;
541  tolen  = strlen(to);
542  fromlen  = strlen(from);
543  out = malloc(outlen);
544
545  while (in[inpos]) {
546    if (!strncmp(in+inpos, from, fromlen)) {
547      outlen += tolen;
548      out = owl_realloc(out, outlen);
549      strcpy(out+outpos, to);
550      inpos += fromlen;
551      outpos += tolen;
552    } else {
553      out[outpos] = in[inpos];
554      inpos++; outpos++;
555    }
556  }
557  out[outpos] = '\0';
558  return(out);
559}
560
[e4eebe8]561/* replace all instances of character a in buff with the character
562 * b.  buff must be null terminated.
563 */
564void owl_util_tr(char *buff, char a, char b)
565{
[ed2412d]566  int i;
567
568  owl_function_debugmsg("In: %s", buff);
569  for (i=0; buff[i]!='\0'; i++) {
570    if (buff[i]==a) buff[i]=b;
571  }
572  owl_function_debugmsg("Out: %s", buff);
573}
[7d4fbcd]574
[e4eebe8]575
576/* Return the owl color associated with the named color */
577int owl_util_string_to_color(char *color)
578{
[7d4fbcd]579  if (!strcasecmp(color, "black")) {
580    return(OWL_COLOR_BLACK);
581  } else if (!strcasecmp(color, "red")) {
582    return(OWL_COLOR_RED);
583  } else if (!strcasecmp(color, "green")) {
584    return(OWL_COLOR_GREEN);
585  } else if (!strcasecmp(color, "yellow")) {
586    return(OWL_COLOR_YELLOW);
587  } else if (!strcasecmp(color, "blue")) {
588    return(OWL_COLOR_BLUE);
589  } else if (!strcasecmp(color, "magenta")) {
590    return(OWL_COLOR_MAGENTA);
591  } else if (!strcasecmp(color, "cyan")) {
592    return(OWL_COLOR_CYAN);
593  } else if (!strcasecmp(color, "white")) {
594    return(OWL_COLOR_WHITE);
595  } else if (!strcasecmp(color, "default")) {
596    return(OWL_COLOR_DEFAULT);
597  }
598  return(OWL_COLOR_DEFAULT);
599}
600
[e4eebe8]601/* Return a string name of the given owl color */
602char *owl_util_color_to_string(int color)
603{
[7d4fbcd]604  if (color==OWL_COLOR_BLACK)   return("black");
605  if (color==OWL_COLOR_RED)     return("red");
606  if (color==OWL_COLOR_GREEN)   return("green");
607  if (color==OWL_COLOR_YELLOW)  return("yellow");
608  if (color==OWL_COLOR_BLUE)    return("blue");
609  if (color==OWL_COLOR_MAGENTA) return("magenta");
610  if (color==OWL_COLOR_CYAN)    return("cyan");
611  if (color==OWL_COLOR_WHITE)   return("white");
612  if (color==OWL_COLOR_DEFAULT) return("default");
613  return("Unknown color");
614}
[e1c4636]615
[e4eebe8]616/* Get the default tty name.  Caller must free the return */
617char *owl_util_get_default_tty()
618{
[5145235]619  char *out, *tmp;
[61e79a9]620
621  if (getenv("DISPLAY")) {
622    out=owl_strdup(getenv("DISPLAY"));
[5145235]623  } else if ((tmp=ttyname(fileno(stdout)))!=NULL) {
624    out=owl_strdup(tmp);
[61e79a9]625    if (!strncmp(out, "/dev/", 5)) {
626      owl_free(out);
[5145235]627      out=owl_strdup(tmp+5);
[61e79a9]628    }
629  } else {
[5145235]630    out=owl_strdup("unknown");
[61e79a9]631  }
632  return(out);
633}
634
635
[e4eebe8]636/* Animation hack */
637void owl_hack_animate()
638{
[4b464a4]639  owl_messagelist *ml;
640  owl_message *m;
641  owl_fmtext *fm;
642  char *text, *ptr;
643  int place;
644
645  /* grab the first message and make sure its id is 0 */
646  ml=owl_global_get_msglist(&g);
647  m=owl_messagelist_get_element(ml, 0);
648  if (!m) return;
649  if (owl_message_get_id(m)!=0) return;
650
651  fm=owl_message_get_fmtext(m);
652  text=owl_fmtext_get_text(fm);
653
654  ptr=strstr(text, "OvO");
655  if (ptr) {
656    place=ptr-text;
657    owl_fmtext_set_char(fm, place, '-');
658    owl_fmtext_set_char(fm, place+2, '-');
659
660    owl_mainwin_redisplay(owl_global_get_mainwin(&g));
[a15a84f]661    if (owl_popwin_is_active(owl_global_get_popwin(&g))) {
662      owl_popwin_refresh(owl_global_get_popwin(&g));
663      /* TODO: this is a broken kludge */
664      if (owl_global_get_viewwin(&g)) {
665        owl_viewwin_redisplay(owl_global_get_viewwin(&g), 0);
666      }
667    }
[4b464a4]668    owl_global_set_needrefresh(&g);
669    return;
670  }
671
672  ptr=strstr(text, "-v-");
673  if (ptr) {
674    place=ptr-text;
675    owl_fmtext_set_char(fm, place, 'O');
676    owl_fmtext_set_char(fm, place+2, 'O');
677
678    owl_mainwin_redisplay(owl_global_get_mainwin(&g));
[a15a84f]679    if (owl_popwin_is_active(owl_global_get_popwin(&g))) {
680      owl_popwin_refresh(owl_global_get_popwin(&g));
681      /* TODO: this is a broken kludge */
682      if (owl_global_get_viewwin(&g)) {
683        owl_viewwin_redisplay(owl_global_get_viewwin(&g), 0);
684      }
685    }
[4b464a4]686    owl_global_set_needrefresh(&g);
687    return;
688  }
689}
[e1c4636]690
[e4eebe8]691/* strip leading and trailing new lines.  Caller must free the
692 * return.
693 */
694char *owl_util_stripnewlines(char *in)
695{
[7e3e00a]696 
697  char  *tmp, *ptr1, *ptr2, *out;
698
699  ptr1=tmp=owl_strdup(in);
700  while (ptr1[0]=='\n') {
701    ptr1++;
702  }
703  ptr2=ptr1+strlen(ptr1)-1;
704  while (ptr2[0]=='\n' && ptr2>ptr1) {
705    ptr2[0]='\0';
706    ptr2--;
707  }
708
709  out=owl_strdup(ptr1);
710  owl_free(tmp);
711  return(out);
712}
713
[38cf544c]714/* Delete the line matching "line" from the named file.  If no such
715 * line is found the file is left intact.  If backup==1 then create a
716 * backupfile containing the original contents.  This is an
717 * inefficient impelementation which reads the entire file into
718 * memory.
719 */
720void owl_util_file_deleteline(char *filename, char *line, int backup)
721{
722  char buff[LINE], *text;
[e6449bc]723  char *backupfilename="";
724  FILE *file, *backupfile=NULL;
[38cf544c]725  int size, newline;
726
727  /* open the file for reading */
728  file=fopen(filename, "r");
729  if (!file) {
730    owl_function_makemsg("Error opening file %s", filename);
731    return;
732  }
[e6449bc]733
[38cf544c]734  /* open the backup file for writing */
735  if (backup) {
736    backupfilename=owl_sprintf("%s.backup", filename);
737    backupfile=fopen(backupfilename, "w");
738    if (!backupfile) {
739      owl_function_makemsg("Error opening file %s for writing", backupfilename);
[378fa14]740      owl_free(backupfilename);
[38cf544c]741      return;
742    }
[378fa14]743    owl_free(backupfilename);
[38cf544c]744  }
745
746  /* we'll read the entire file into memory, minus the line we don't want and
747   * and at the same time create the backup file if necessary
748   */
749  text=owl_malloc(LINE);
750  strcpy(text, "");
751  size=LINE;
752  while (fgets(buff, LINE, file)!=NULL) {
753    /* strip the newline */
754    newline=0;
755    if (buff[strlen(buff)-1]=='\n') {
756      buff[strlen(buff)-1]='\0';
757      newline=1;
758    }
759   
760    /* if we don't match the line, add to saved text in memory */
761    if (strcasecmp(buff, line)) {
762      size+=LINE;
763      text=owl_realloc(text, size);
764      strcat(text, buff);
765      if (newline) strcat(text, "\n");
766    }
767
768    /* write to backupfile if necessary */
769    if (backup) fputs(buff, backupfile);
770  }
[65ad073]771  if (backup) fclose(backupfile);
[38cf544c]772  fclose(file);
773
774  /* now rewrite the original file from memory */
775  file=fopen(filename, "w");
776  if (!file) {
777    owl_function_makemsg("WARNING: Error opening %s for writing.  Use %s to restore.", filename, backupfilename);
778    owl_function_beep();
779    owl_free(line);
780    return;
781  }
782
783  fputs(text, file);
784  fclose(file);
785}
786
[e1c4636]787/**************************************************************************/
788/************************* REGRESSION TESTS *******************************/
789/**************************************************************************/
790
791#ifdef OWL_INCLUDE_REG_TESTS
792
793#define FAIL_UNLESS(desc,pred) printf("\t%-4s: %s\n", (pred)?"ok":(numfailed++,"FAIL"), desc)
794
[e4eebe8]795int owl_util_regtest(void)
796{
[e1c4636]797  int numfailed=0;
798
799  printf("BEGIN testing owl_util\n");
800
801  FAIL_UNLESS("owl_util_substitute 1",
802              !strcmp("foo", owl_util_substitute("foo", "", "Y")));
803  FAIL_UNLESS("owl_util_substitute 2",
804              !strcmp("fYZYZ", owl_util_substitute("foo", "o", "YZ")));
805  FAIL_UNLESS("owl_util_substitute 3",
806              !strcmp("foo", owl_util_substitute("fYZYZ", "YZ", "o")));
807  FAIL_UNLESS("owl_util_substitute 4",
808              !strcmp("/u/foo/meep", owl_util_substitute("~/meep", "~", "/u/foo")));
809
810  FAIL_UNLESS("skiptokens 1", 
811              !strcmp("bar quux", skiptokens("foo bar quux", 1)));
812  FAIL_UNLESS("skiptokens 2", 
813              !strcmp("meep", skiptokens("foo 'bar quux' meep", 2)));
814
[e50cd56]815  FAIL_UNLESS("owl_util_uniq 1", 
816              !strcmp("foo bar x", owl_util_uniq("foo", "bar x", "-")));
817  FAIL_UNLESS("owl_util_uniq 2", 
818              !strcmp("foo bar x", owl_util_uniq("foo", "bar -y x", "-")));
819  FAIL_UNLESS("owl_util_uniq 3", 
820              !strcmp("meep foo bar", owl_util_uniq("meep foo", "bar foo meep", "-")));
821
[e1c4636]822  if (numfailed) printf("*** WARNING: failures encountered with owl_util\n");
823  printf("END testing owl_util (%d failures)\n", numfailed);
824  return(numfailed);
825}
826
827#endif /* OWL_INCLUDE_REG_TESTS */
Note: See TracBrowser for help on using the repository browser.