source: util.c @ 330c55a

debianrelease-1.10release-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 330c55a was f34dd65, checked in by Nelson Elhage <nelhage@mit.edu>, 16 years ago
Kill a whole bunch of unused code. I generated a list of dead functions by building with -ffunction-sections and linking with -Wl,--gc-sections -Wl,--print-gc-sections I kept a number of functions that seemed to be logical parts of an existing API, as well as stuff in varstubs.c, since that file is autogenerated.
  • Property mode set to 100644
File size: 18.7 KB
RevLine 
[7d4fbcd]1#include "owl.h"
2#include <stdlib.h>
3#include <string.h>
[5145235]4#include <unistd.h>
[7d4fbcd]5#include <ctype.h>
[f36222f]6#include <pwd.h>
[7d4fbcd]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);
[c15bbfb]25  if (owl_global_is_fancylines(&g)) {
26    whline(sepwin, ACS_HLINE, owl_global_get_cols(&g));
27  } else {
28    whline(sepwin, '-', owl_global_get_cols(&g));
29  }
[7d4fbcd]30
[73624b4]31  if (owl_global_is_sepbar_disable(&g)) {
32    getyx(sepwin, y, x);
33    wmove(sepwin, y, owl_global_get_cols(&g)-1);
34    return;
35  }
36
[7d4fbcd]37  wmove(sepwin, 0, 2); 
38
39  if (owl_messagelist_get_size(ml)==0) {
40    strcpy(buff, " (-/-) ");
41  } else {
[1c6c4d3]42    snprintf(buff, 1024, " (%i/%i/%i) ", owl_global_get_curmsg(&g)+1,
[7d4fbcd]43            owl_view_get_size(v),
44            owl_messagelist_get_size(ml));
45  }
46  waddstr(sepwin, buff);
47
48  foo=owl_view_get_filtname(v);
[330bcec]49  if (strcmp(foo, owl_global_get_view_home(&g))) wattroff(sepwin, A_REVERSE);
[7d4fbcd]50  waddstr(sepwin, " ");
51  waddstr(sepwin, owl_view_get_filtname(v));
52  waddstr(sepwin, " ");
[330bcec]53  if (strcmp(foo, owl_global_get_view_home(&g))) wattron(sepwin, A_REVERSE);
[7d4fbcd]54
55  if (owl_mainwin_is_curmsg_truncated(owl_global_get_mainwin(&g))) {
56    getyx(sepwin, y, x);
57    wmove(sepwin, y, x+2);
58    wattron(sepwin, A_BOLD);
59    waddstr(sepwin, " <truncated> ");
60    wattroff(sepwin, A_BOLD);
61  }
62
63  i=owl_mainwin_get_last_msg(owl_global_get_mainwin(&g));
64  if ((i != -1) &&
65      (i < owl_view_get_size(v)-1)) {
66    getyx(sepwin, y, x);
67    wmove(sepwin, y, x+2);
68    wattron(sepwin, A_BOLD);
69    waddstr(sepwin, " <more> ");
70    wattroff(sepwin, A_BOLD);
71  }
72
73  if (owl_global_get_rightshift(&g)>0) {
74    getyx(sepwin, y, x);
75    wmove(sepwin, y, x+2);
[1c6c4d3]76    snprintf(buff, 1024, " right: %i ", owl_global_get_rightshift(&g));
[7d4fbcd]77    waddstr(sepwin, buff);
78  }
79
[4b660cc]80  if (owl_global_is_zaway(&g) || owl_global_is_aaway(&g)) {
[7d4fbcd]81    getyx(sepwin, y, x);
82    wmove(sepwin, y, x+2);
83    wattron(sepwin, A_BOLD);
84    wattroff(sepwin, A_REVERSE);
[4b660cc]85    if (owl_global_is_zaway(&g) && owl_global_is_aaway(&g)) {
86      waddstr(sepwin, " AWAY ");
87    } else if (owl_global_is_zaway(&g)) {
88      waddstr(sepwin, " Z-AWAY ");
89    } else if (owl_global_is_aaway(&g)) {
90      waddstr(sepwin, " A-AWAY ");
91    }
[7d4fbcd]92    wattron(sepwin, A_REVERSE);
93    wattroff(sepwin, A_BOLD);
94  }
95
96  if (owl_global_get_curmsg_vert_offset(&g)) {
97    getyx(sepwin, y, x);
98    wmove(sepwin, y, x+2);
99    wattron(sepwin, A_BOLD);
100    wattroff(sepwin, A_REVERSE);
101    waddstr(sepwin, " SCROLL ");
102    wattron(sepwin, A_REVERSE);
103    wattroff(sepwin, A_BOLD);
104  }
105 
106  if (in) {
107    getyx(sepwin, y, x);
108    wmove(sepwin, y, x+2);
109    waddstr(sepwin, in);
110  }
111
112  appendtosepbar = owl_global_get_appendtosepbar(&g);
113  if (appendtosepbar && *appendtosepbar) {
114    getyx(sepwin, y, x);
115    wmove(sepwin, y, x+2);
116    waddstr(sepwin, " ");
117    waddstr(sepwin, owl_global_get_appendtosepbar(&g));
118    waddstr(sepwin, " ");
119  }
120
121  getyx(sepwin, y, x);
122  wmove(sepwin, y, owl_global_get_cols(&g)-1);
123   
124  wattroff(sepwin, A_BOLD);
125  wattroff(sepwin, A_REVERSE);
126  wnoutrefresh(sepwin);
127}
128
[e4eebe8]129char **atokenize(char *buffer, char *sep, int *i)
130{
[7d4fbcd]131  /* each element of return must be freed by user */
132  char **args;
133  char *workbuff, *foo;
134  int done=0, first=1, count=0;
135
136  workbuff=owl_malloc(strlen(buffer)+1);
137  memcpy(workbuff, buffer, strlen(buffer)+1);
138
139  args=NULL;
140  while (!done) {
141    if (first) {
142      first=0;
143      foo=(char *)strtok(workbuff, sep);
144    } else {
145      foo=(char *)strtok(NULL, sep);
146    }
147    if (foo==NULL) {
148      done=1;
149    } else {
150      args=(char **)owl_realloc(args, sizeof(char *) * (count+1));
151      args[count]=owl_malloc(strlen(foo)+1);
152      strcpy(args[count], foo);
153      count++;
154    }
155  }
156  *i=count;
157  owl_free(workbuff);
158  return(args);
159}
160
161char *skiptokens(char *buff, int n) {
[42abb10]162  /* skips n tokens and returns where that would be.
163   * TODO: handle quotes more sanely. */
164 
[7d4fbcd]165  int inquotes=0;
166  while (*buff && n>0) {
167      while (*buff == ' ') buff++;
168      while (*buff && (inquotes || *buff != ' ')) { 
[e1c4636]169        if (*buff == '"' || *buff == '\'') inquotes=!inquotes;
[7d4fbcd]170        buff++;
171      }
172      while (*buff == ' ') buff++;
173      n--;
174  }
175  return buff;
176}
177
[f36222f]178/* Return a "nice" version of the path.  Tilde expansion is done, and
179 * duplicate slashes are removed.  Caller must free the return.
180 */
181char *owl_util_makepath(char *in)
182{
183  int i, j, x;
184  char *out, user[MAXPATHLEN];
185  struct passwd *pw;
186
187  out=owl_malloc(MAXPATHLEN+1);
188  out[0]='\0';
189  j=strlen(in);
190  x=0;
191  for (i=0; i<j; i++) {
192    if (in[i]=='~') {
193      if ( (i==(j-1)) ||          /* last character */
194           (in[i+1]=='/') ) {     /* ~/ */
195        /* use my homedir */
196        pw=getpwuid(getuid());
197        if (!pw) {
198          out[x]=in[i];
199        } else {
200          out[x]='\0';
201          strcat(out, pw->pw_dir);
202          x+=strlen(pw->pw_dir);
203        }
204      } else {
205        /* another user homedir */
206        int a, b;
207        b=0;
208        for (a=i+1; i<j; a++) {
209          if (in[a]==' ' || in[a]=='/') {
210            break;
211          } else {
212            user[b]=in[a];
213            i++;
214            b++;
215          }
216        }
217        user[b]='\0';
218        pw=getpwnam(user);
219        if (!pw) {
[8766d44]220          out[x]=in[i];
[f36222f]221        } else {
222          out[x]='\0';
223          strcat(out, pw->pw_dir);
224          x+=strlen(pw->pw_dir);
225        }
226      }
227    } else if (in[i]=='/') {
228      /* check for a double / */
229      if (i<(j-1) && (in[i+1]=='/')) {
230        /* do nothing */
231      } else {
232        out[x]=in[i];
233        x++;
234      }
235    } else {
236      out[x]=in[i];
237      x++;
238    }
239  }
240  out[x]='\0';
241  return(out);
242}
243
[e4eebe8]244void atokenize_free(char **tok, int nels)
245{
[7d4fbcd]246  int i;
247  for (i=0; i<nels; i++) {
248    owl_free(tok[i]);
249  }
250  owl_free(tok);
251}
252
253
[e4eebe8]254void owl_parsefree(char **argv, int argc)
255{
[7d4fbcd]256  int i;
257
258  if (!argv) return;
259 
260  for (i=0; i<argc; i++) {
261    if (argv[i]) owl_free(argv[i]);
262  }
263  owl_free(argv);
264}
265
[e4eebe8]266char **owl_parseline(char *line, int *argc)
267{
[7d4fbcd]268  /* break a command line up into argv, argc.  The caller must free
269     the returned values.  If there is an error argc will be set to
270     -1, argv will be NULL and the caller does not need to free
271     anything */
272
273  char **argv;
274  int i, len, between=1;
275  char *curarg;
276  char quote;
277
278  argv=owl_malloc(sizeof(char *));
279  len=strlen(line);
280  curarg=owl_malloc(len+10);
281  strcpy(curarg, "");
282  quote='\0';
283  *argc=0;
284  for (i=0; i<len+1; i++) {
285    /* find the first real character */
286    if (between) {
287      if (line[i]==' ' || line[i]=='\t' || line[i]=='\0') {
288        continue;
289      } else {
290        between=0;
291        i--;
292        continue;
293      }
294    }
295
296    /* deal with a quote character */
297    if (line[i]=='"' || line[i]=="'"[0]) {
298      /* if this type of quote is open, close it */
299      if (quote==line[i]) {
300        quote='\0';
301        continue;
302      }
303
304      /* if no quoting is open then open with this */
305      if (quote=='\0') {
306        quote=line[i];
307        continue;
308      }
309
310      /* if another type of quote is open then treat this as a literal */
311      curarg[strlen(curarg)+1]='\0';
312      curarg[strlen(curarg)]=line[i];
313      continue;
314    }
315
316    /* if it's not a space or end of command, then use it */
317    if (line[i]!=' ' && line[i]!='\t' && line[i]!='\n' && line[i]!='\0') {
318      curarg[strlen(curarg)+1]='\0';
319      curarg[strlen(curarg)]=line[i];
320      continue;
321    }
322
323    /* otherwise, if we're not in quotes, add the whole argument */
324    if (quote=='\0') {
325      /* add the argument */
326      argv=owl_realloc(argv, sizeof(char *)*((*argc)+1));
327      argv[*argc]=owl_malloc(strlen(curarg)+2);
328      strcpy(argv[*argc], curarg);
329      *argc=*argc+1;
330      strcpy(curarg, "");
331      between=1;
332      continue;
333    }
334
335    /* if it is a space and we're in quotes, then use it */
336    curarg[strlen(curarg)+1]='\0';
337    curarg[strlen(curarg)]=line[i];
338  }
339
[d524c83]340  owl_free(curarg);
[95caa16]341
[7d4fbcd]342  /* check for unbalanced quotes */
343  if (quote!='\0') {
344    owl_parsefree(argv, *argc);
345    *argc=-1;
346    return(NULL);
347  }
348
349  return(argv);
350}
351
[de03334]352/* caller must free the return */
[5b85d19]353char *owl_util_minutes_to_timestr(int in)
[de03334]354{
[f1e629d]355  int days, hours;
[de03334]356  long run;
357  char *out;
358
[5b85d19]359  run=in;
[de03334]360
[5b85d19]361  days=run/1440;
362  run-=days*1440;
363  hours=run/60;
364  run-=hours*60;
[de03334]365
366  if (days>0) {
[6eaf35b]367    out=owl_sprintf("%i d %2.2i:%2.2li", days, hours, run);
[de03334]368  } else {
[6eaf35b]369    out=owl_sprintf("    %2.2i:%2.2li", hours, run);
[de03334]370  }
371  return(out);
372}
373
[42abb10]374/* hooks for doing memory allocation et. al. in owl */
375
[e4eebe8]376void *owl_malloc(size_t size)
377{
[34509d5]378  return(g_malloc(size));
[7d4fbcd]379}
380
[e4eebe8]381void owl_free(void *ptr)
382{
[34509d5]383  g_free(ptr);
[7d4fbcd]384}
385
[e4eebe8]386char *owl_strdup(const char *s1)
387{
[34509d5]388  return(g_strdup(s1));
[7d4fbcd]389}
390
[e4eebe8]391void *owl_realloc(void *ptr, size_t size)
392{
[34509d5]393  return(g_realloc(ptr, size));
[7d4fbcd]394}
395
[e4eebe8]396/* allocates memory and returns the string or null.
397 * caller must free the string.
398 */
399char *owl_sprintf(const char *fmt, ...)
400{
[1c6c4d3]401  va_list ap;
[28ee32b]402  char *ret = NULL;
403  va_start(ap, fmt);
404  ret = g_strdup_vprintf(fmt, ap);
405  va_end(ap);
406  return ret;
[1c6c4d3]407}
408
[28ee32b]409
[12c35df]410/* Return the owl color associated with the named color.  Return -1
411 * if the named color is not available
412 */
[e4eebe8]413int owl_util_string_to_color(char *color)
414{
[c2c5c77]415  int c;
[7d4fbcd]416  if (!strcasecmp(color, "black")) {
417    return(OWL_COLOR_BLACK);
418  } else if (!strcasecmp(color, "red")) {
419    return(OWL_COLOR_RED);
420  } else if (!strcasecmp(color, "green")) {
421    return(OWL_COLOR_GREEN);
422  } else if (!strcasecmp(color, "yellow")) {
423    return(OWL_COLOR_YELLOW);
424  } else if (!strcasecmp(color, "blue")) {
425    return(OWL_COLOR_BLUE);
426  } else if (!strcasecmp(color, "magenta")) {
427    return(OWL_COLOR_MAGENTA);
428  } else if (!strcasecmp(color, "cyan")) {
429    return(OWL_COLOR_CYAN);
430  } else if (!strcasecmp(color, "white")) {
431    return(OWL_COLOR_WHITE);
432  } else if (!strcasecmp(color, "default")) {
433    return(OWL_COLOR_DEFAULT);
434  }
[c2c5c77]435  c = atoi(color);
436  if (c >= -1 && c < COLORS) {
437    return(c);
438  }
[601733d]439  return(OWL_COLOR_INVALID);
[7d4fbcd]440}
441
[e4eebe8]442/* Return a string name of the given owl color */
443char *owl_util_color_to_string(int color)
444{
[7d4fbcd]445  if (color==OWL_COLOR_BLACK)   return("black");
446  if (color==OWL_COLOR_RED)     return("red");
447  if (color==OWL_COLOR_GREEN)   return("green");
448  if (color==OWL_COLOR_YELLOW)  return("yellow");
449  if (color==OWL_COLOR_BLUE)    return("blue");
450  if (color==OWL_COLOR_MAGENTA) return("magenta");
451  if (color==OWL_COLOR_CYAN)    return("cyan");
452  if (color==OWL_COLOR_WHITE)   return("white");
453  if (color==OWL_COLOR_DEFAULT) return("default");
454  return("Unknown color");
455}
[e1c4636]456
[e4eebe8]457/* Get the default tty name.  Caller must free the return */
458char *owl_util_get_default_tty()
459{
[5145235]460  char *out, *tmp;
[61e79a9]461
462  if (getenv("DISPLAY")) {
463    out=owl_strdup(getenv("DISPLAY"));
[5145235]464  } else if ((tmp=ttyname(fileno(stdout)))!=NULL) {
465    out=owl_strdup(tmp);
[61e79a9]466    if (!strncmp(out, "/dev/", 5)) {
467      owl_free(out);
[5145235]468      out=owl_strdup(tmp+5);
[61e79a9]469    }
470  } else {
[5145235]471    out=owl_strdup("unknown");
[61e79a9]472  }
473  return(out);
474}
475
476
[e4eebe8]477/* Animation hack */
478void owl_hack_animate()
479{
[4b464a4]480  owl_messagelist *ml;
481  owl_message *m;
482  owl_fmtext *fm;
483  char *text, *ptr;
484  int place;
485
486  /* grab the first message and make sure its id is 0 */
487  ml=owl_global_get_msglist(&g);
488  m=owl_messagelist_get_element(ml, 0);
489  if (!m) return;
490  if (owl_message_get_id(m)!=0) return;
491
492  fm=owl_message_get_fmtext(m);
493  text=owl_fmtext_get_text(fm);
494
495  ptr=strstr(text, "OvO");
496  if (ptr) {
497    place=ptr-text;
498    owl_fmtext_set_char(fm, place, '-');
499    owl_fmtext_set_char(fm, place+2, '-');
500
501    owl_mainwin_redisplay(owl_global_get_mainwin(&g));
[a15a84f]502    if (owl_popwin_is_active(owl_global_get_popwin(&g))) {
503      owl_popwin_refresh(owl_global_get_popwin(&g));
504      /* TODO: this is a broken kludge */
505      if (owl_global_get_viewwin(&g)) {
506        owl_viewwin_redisplay(owl_global_get_viewwin(&g), 0);
507      }
508    }
[4b464a4]509    owl_global_set_needrefresh(&g);
510    return;
511  }
512
513  ptr=strstr(text, "-v-");
514  if (ptr) {
515    place=ptr-text;
516    owl_fmtext_set_char(fm, place, 'O');
517    owl_fmtext_set_char(fm, place+2, 'O');
518
519    owl_mainwin_redisplay(owl_global_get_mainwin(&g));
[a15a84f]520    if (owl_popwin_is_active(owl_global_get_popwin(&g))) {
521      owl_popwin_refresh(owl_global_get_popwin(&g));
522      /* TODO: this is a broken kludge */
523      if (owl_global_get_viewwin(&g)) {
524        owl_viewwin_redisplay(owl_global_get_viewwin(&g), 0);
525      }
526    }
[4b464a4]527    owl_global_set_needrefresh(&g);
528    return;
529  }
530}
[e1c4636]531
[e4eebe8]532/* strip leading and trailing new lines.  Caller must free the
533 * return.
534 */
535char *owl_util_stripnewlines(char *in)
536{
[7e3e00a]537 
538  char  *tmp, *ptr1, *ptr2, *out;
539
540  ptr1=tmp=owl_strdup(in);
541  while (ptr1[0]=='\n') {
542    ptr1++;
543  }
544  ptr2=ptr1+strlen(ptr1)-1;
[1bb1e67]545  while (ptr2>ptr1 && ptr2[0]=='\n') {
[7e3e00a]546    ptr2[0]='\0';
547    ptr2--;
548  }
549
550  out=owl_strdup(ptr1);
551  owl_free(tmp);
552  return(out);
553}
554
[38cf544c]555/* Delete the line matching "line" from the named file.  If no such
556 * line is found the file is left intact.  If backup==1 then create a
557 * backupfile containing the original contents.  This is an
558 * inefficient impelementation which reads the entire file into
559 * memory.
560 */
561void owl_util_file_deleteline(char *filename, char *line, int backup)
562{
563  char buff[LINE], *text;
[e6449bc]564  char *backupfilename="";
565  FILE *file, *backupfile=NULL;
[38cf544c]566  int size, newline;
567
568  /* open the file for reading */
569  file=fopen(filename, "r");
570  if (!file) {
[836ea3a3]571    owl_function_error("Error opening file %s", filename);
[38cf544c]572    return;
573  }
[e6449bc]574
[38cf544c]575  /* open the backup file for writing */
576  if (backup) {
577    backupfilename=owl_sprintf("%s.backup", filename);
578    backupfile=fopen(backupfilename, "w");
579    if (!backupfile) {
[836ea3a3]580      owl_function_error("Error opening file %s for writing", backupfilename);
[378fa14]581      owl_free(backupfilename);
[e97c4a30]582      fclose(file);
[38cf544c]583      return;
584    }
585  }
586
587  /* we'll read the entire file into memory, minus the line we don't want and
588   * and at the same time create the backup file if necessary
589   */
590  text=owl_malloc(LINE);
591  strcpy(text, "");
592  size=LINE;
593  while (fgets(buff, LINE, file)!=NULL) {
594    /* strip the newline */
595    newline=0;
596    if (buff[strlen(buff)-1]=='\n') {
597      buff[strlen(buff)-1]='\0';
598      newline=1;
599    }
600   
601    /* if we don't match the line, add to saved text in memory */
602    if (strcasecmp(buff, line)) {
603      size+=LINE;
604      text=owl_realloc(text, size);
605      strcat(text, buff);
606      if (newline) strcat(text, "\n");
607    }
608
609    /* write to backupfile if necessary */
[6a50af2]610    if (backup) {
611      fputs(buff, backupfile);
612      if (newline) fputs("\n", backupfile);
613    }
[38cf544c]614  }
[65ad073]615  if (backup) fclose(backupfile);
[38cf544c]616  fclose(file);
617
618  /* now rewrite the original file from memory */
619  file=fopen(filename, "w");
620  if (!file) {
[836ea3a3]621    owl_function_error("WARNING: Error opening %s for writing.  Use %s to restore.", filename, backupfilename);
[38cf544c]622    owl_function_beep();
[e97c4a30]623  } else {
624    fputs(text, file);
625    fclose(file);
[38cf544c]626  }
627
[e97c4a30]628  if (backup)
629    owl_free(backupfilename);
630  owl_free(text);
[38cf544c]631}
632
[fe67f1f]633int owl_util_max(int a, int b)
634{
635  if (a>b) return(a);
636  return(b);
637}
638
639int owl_util_min(int a, int b)
640{
641  if (a<b) return(a);
642  return(b);
643}
644
[7a20e4c]645/* Return the base class or instance from a zephyr class, by removing
646   leading `un' or trailing `.d'.
[be5aa09]647   The caller is responsible for freeing the allocated string.
[7a20e4c]648*/
649char * owl_util_baseclass(char * class)
650{
[59916e8]651  char *start, *end;
652
[f166580]653  start = class;
[59916e8]654  while(!strncmp(start, "un", 2)) {
655    start += 2;
[7a20e4c]656  }
[f166580]657
658  start = owl_strdup(start);
[59916e8]659  end = start + strlen(start) - 1;
[04166e9]660  while(end > start && *end == 'd' && *(end-1) == '.') {
[7a20e4c]661    end -= 2;
662  }
663  *(end + 1) = 0;
[59916e8]664
[f166580]665  return start;
[7a20e4c]666}
667
[5376a95]668char * owl_get_datadir()
669{
670  char * datadir = getenv("BARNOWL_DATA_DIR");
671  if(datadir != NULL)
672    return strchr(datadir, '=') + 1;
673  return DATADIR;
674}
675
676/* Strips format characters from a valid utf-8 string. Returns the
677   empty string if 'in' does not validate. */
678char * owl_strip_format_chars(char *in)
679{
680  char *r;
681  if (g_utf8_validate(in, -1, NULL)) {
682    char *s, *p;
683    r = owl_malloc(strlen(in)+1);
684    r[0] = '\0';
685    s = in;
686    p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
687    while(p) {
688      /* If it's a format character, copy up to it, and skip all
689         immediately following format characters. */
[c1522ec]690      if (owl_fmtext_is_format_char(g_utf8_get_char(p))) {
[5376a95]691        strncat(r, s, p-s);
692        p = g_utf8_next_char(p);
[c1522ec]693        while (p && owl_fmtext_is_format_char(g_utf8_get_char(p))) {
[5376a95]694          p = g_utf8_next_char(p);
695        }
696        s = p;
697        p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
698      }
699      else {
700        p = strchr(p+1, OWL_FMTEXT_UC_STARTBYTE_UTF8);
701      }
702    }
703    if (s) strcat(r,s);
704  }
705  else {
706    r = owl_strdup("");
707  }
708  return r;
709}
710
711/* If in is not UTF-8, convert from ISO-8859-1. We may want to allow
712 * the caller to specify an alternative in the future. We also strip
713 * out characters in Unicode Plane 16, as we use that plane internally
714 * for formatting.
715 */
[6201646]716char * owl_validate_or_convert(char *in)
[5376a95]717{
[6201646]718  if (g_utf8_validate(in, -1, NULL)) {
[5376a95]719    return owl_strip_format_chars(in);
720  }
721  else {
[6201646]722    return g_convert(in, -1,
[5376a95]723                     "UTF-8", "ISO-8859-1",
724                     NULL, NULL, NULL);
725  }
[89f5338]726}
[7b1d048]727/* Attempts to convert 'in' to ISO-8859-1. Returns that if possible,
728   else returns UTF-8.
729 */
730char * owl_get_iso_8859_1_if_possible(char *in)
731{
732  char *out;
733  if (g_utf8_validate(in, -1, NULL)) {
734    out = g_convert(in, -1,
735                    "ISO-8859-1", "UTF-8",
736                    NULL, NULL, NULL);
737    if (!out) {
738      out = owl_strdup(in);
739    }
740  }
741  else {
742    out = owl_strdup("");
743  }
744  return out;
745}
[89f5338]746
[84027015]747/* This is based on _extract() and _isCJ() from perl's Text::WrapI18N */
748int owl_util_can_break_after(gunichar c)
749{
750 
751  if (c == ' ') return 1;
752  if (c >= 0x3000 && c <= 0x312f) {
753    /* CJK punctuations, Hiragana, Katakana, Bopomofo */
754    if (c == 0x300a || c == 0x300c || c == 0x300e ||
755        c == 0x3010 || c == 0x3014 || c == 0x3016 ||
756        c == 0x3018 || c == 0x301a)
757      return 0;
758    return 1;
759  }
760  if (c >= 0x31a0 && c <= 0x31bf) {return 1;}  /* Bopomofo */
761  if (c >= 0x31f0 && c <= 0x31ff) {return 1;}  /* Katakana extension */
762  if (c >= 0x3400 && c <= 0x9fff) {return 1;}  /* Han Ideogram */
763  if (c >= 0xf900 && c <= 0xfaff) {return 1;}  /* Han Ideogram */
764  if (c >= 0x20000 && c <= 0x2ffff) {return 1;}  /* Han Ideogram */
765  return 0;
766}
767
[e1c4636]768/**************************************************************************/
769/************************* REGRESSION TESTS *******************************/
770/**************************************************************************/
771
772#ifdef OWL_INCLUDE_REG_TESTS
773
[0138478]774#include "test.h"
[e1c4636]775
[e4eebe8]776int owl_util_regtest(void)
777{
[e1c4636]778  int numfailed=0;
779
[1cf3f8d3]780  printf("# BEGIN testing owl_util\n");
[e1c4636]781
782  FAIL_UNLESS("owl_util_substitute 1",
[e3d9c77]783              !strcmp("foo", owl_text_substitute("foo", "", "Y")));
784  FAIL_UNLESS("owl_text_substitute 2",
785              !strcmp("fYZYZ", owl_text_substitute("foo", "o", "YZ")));
786  FAIL_UNLESS("owl_text_substitute 3",
787              !strcmp("foo", owl_text_substitute("fYZYZ", "YZ", "o")));
788  FAIL_UNLESS("owl_text_substitute 4",
789              !strcmp("/u/foo/meep", owl_text_substitute("~/meep", "~", "/u/foo")));
[e1c4636]790
791  FAIL_UNLESS("skiptokens 1", 
792              !strcmp("bar quux", skiptokens("foo bar quux", 1)));
793  FAIL_UNLESS("skiptokens 2", 
794              !strcmp("meep", skiptokens("foo 'bar quux' meep", 2)));
795
[af1920fd]796  /* if (numfailed) printf("*** WARNING: failures encountered with owl_util\n"); */
[1cf3f8d3]797  printf("# END testing owl_util (%d failures)\n", numfailed);
[e1c4636]798  return(numfailed);
799}
800
801#endif /* OWL_INCLUDE_REG_TESTS */
Note: See TracBrowser for help on using the repository browser.