source: util.c @ 8590774

release-1.10release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 8590774 was 0697f09, checked in by Alejandro R. Sedeño <asedeno@mit.edu>, 15 years ago
Drop owl_animate_hack.
  • Property mode set to 100644
File size: 17.6 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>
[435001d]7#include <sys/stat.h>
8#include <sys/types.h>
[7d4fbcd]9
[e19eb97]10void sepbar(const char *in)
[e4eebe8]11{
[7d4fbcd]12  char buff[1024];
13  WINDOW *sepwin;
[3eb599d]14  const owl_messagelist *ml;
[9e5c9f3]15  const owl_view *v;
[7d4fbcd]16  int x, y, i;
[e19eb97]17  const char *foo, *appendtosepbar;
[7d4fbcd]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
[e19eb97]129char **atokenize(const char *buffer, const char *sep, int *i)
[e4eebe8]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;
[4d86e06]143      foo=strtok(workbuff, sep);
[7d4fbcd]144    } else {
[4d86e06]145      foo=strtok(NULL, sep);
[7d4fbcd]146    }
147    if (foo==NULL) {
148      done=1;
149    } else {
[4d86e06]150      args=owl_realloc(args, sizeof(char *) * (count+1));
[36486be]151      args[count] = owl_strdup(foo);
[7d4fbcd]152      count++;
153    }
154  }
155  *i=count;
156  owl_free(workbuff);
157  return(args);
158}
159
[e19eb97]160const char *skiptokens(const char *buff, int n) {
[e30ed92]161  /* skips n tokens and returns where that would be. */
162  char quote = 0;
[7d4fbcd]163  while (*buff && n>0) {
164      while (*buff == ' ') buff++;
[e30ed92]165      while (*buff && (quote || *buff != ' ')) {
166        if(quote) {
167          if(*buff == quote) quote = 0;
168        } else if(*buff == '"' || *buff == '\'') {
169          quote = *buff;
170        }
171        buff++;
[7d4fbcd]172      }
173      while (*buff == ' ') buff++;
174      n--;
175  }
176  return buff;
177}
178
[f36222f]179/* Return a "nice" version of the path.  Tilde expansion is done, and
180 * duplicate slashes are removed.  Caller must free the return.
181 */
[e19eb97]182char *owl_util_makepath(const char *in)
[f36222f]183{
184  int i, j, x;
185  char *out, user[MAXPATHLEN];
186  struct passwd *pw;
187
188  out=owl_malloc(MAXPATHLEN+1);
189  out[0]='\0';
190  j=strlen(in);
191  x=0;
192  for (i=0; i<j; i++) {
193    if (in[i]=='~') {
194      if ( (i==(j-1)) ||          /* last character */
195           (in[i+1]=='/') ) {     /* ~/ */
196        /* use my homedir */
197        pw=getpwuid(getuid());
198        if (!pw) {
199          out[x]=in[i];
200        } else {
201          out[x]='\0';
202          strcat(out, pw->pw_dir);
203          x+=strlen(pw->pw_dir);
204        }
205      } else {
206        /* another user homedir */
207        int a, b;
208        b=0;
209        for (a=i+1; i<j; a++) {
210          if (in[a]==' ' || in[a]=='/') {
211            break;
212          } else {
213            user[b]=in[a];
214            i++;
215            b++;
216          }
217        }
218        user[b]='\0';
219        pw=getpwnam(user);
220        if (!pw) {
[8766d44]221          out[x]=in[i];
[f36222f]222        } else {
223          out[x]='\0';
224          strcat(out, pw->pw_dir);
225          x+=strlen(pw->pw_dir);
226        }
227      }
228    } else if (in[i]=='/') {
229      /* check for a double / */
230      if (i<(j-1) && (in[i+1]=='/')) {
231        /* do nothing */
232      } else {
233        out[x]=in[i];
234        x++;
235      }
236    } else {
237      out[x]=in[i];
238      x++;
239    }
240  }
241  out[x]='\0';
242  return(out);
243}
244
[e4eebe8]245void atokenize_free(char **tok, int nels)
246{
[7d4fbcd]247  int i;
248  for (i=0; i<nels; i++) {
249    owl_free(tok[i]);
250  }
251  owl_free(tok);
252}
253
254
[e4eebe8]255void owl_parsefree(char **argv, int argc)
256{
[7d4fbcd]257  int i;
258
259  if (!argv) return;
260 
261  for (i=0; i<argc; i++) {
262    if (argv[i]) owl_free(argv[i]);
263  }
264  owl_free(argv);
265}
266
[e19eb97]267char **owl_parseline(const char *line, int *argc)
[e4eebe8]268{
[7d4fbcd]269  /* break a command line up into argv, argc.  The caller must free
270     the returned values.  If there is an error argc will be set to
271     -1, argv will be NULL and the caller does not need to free
272     anything */
273
274  char **argv;
275  int i, len, between=1;
276  char *curarg;
277  char quote;
278
279  argv=owl_malloc(sizeof(char *));
280  len=strlen(line);
281  curarg=owl_malloc(len+10);
282  strcpy(curarg, "");
283  quote='\0';
284  *argc=0;
285  for (i=0; i<len+1; i++) {
286    /* find the first real character */
287    if (between) {
288      if (line[i]==' ' || line[i]=='\t' || line[i]=='\0') {
289        continue;
290      } else {
291        between=0;
292        i--;
293        continue;
294      }
295    }
296
297    /* deal with a quote character */
298    if (line[i]=='"' || line[i]=="'"[0]) {
299      /* if this type of quote is open, close it */
300      if (quote==line[i]) {
301        quote='\0';
302        continue;
303      }
304
305      /* if no quoting is open then open with this */
306      if (quote=='\0') {
307        quote=line[i];
308        continue;
309      }
310
311      /* if another type of quote is open then treat this as a literal */
312      curarg[strlen(curarg)+1]='\0';
313      curarg[strlen(curarg)]=line[i];
314      continue;
315    }
316
317    /* if it's not a space or end of command, then use it */
318    if (line[i]!=' ' && line[i]!='\t' && line[i]!='\n' && line[i]!='\0') {
319      curarg[strlen(curarg)+1]='\0';
320      curarg[strlen(curarg)]=line[i];
321      continue;
322    }
323
324    /* otherwise, if we're not in quotes, add the whole argument */
325    if (quote=='\0') {
326      /* add the argument */
327      argv=owl_realloc(argv, sizeof(char *)*((*argc)+1));
[36486be]328      argv[*argc] = owl_strdup(curarg);
[7d4fbcd]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 */
[e19eb97]413int owl_util_string_to_color(const char *color)
[e4eebe8]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 */
[e19eb97]443const char *owl_util_color_to_string(int color)
[e4eebe8]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 */
[c79a047]458char *owl_util_get_default_tty(void)
[e4eebe8]459{
[e19eb97]460  const char *tmp;
[65b2173]461  char *out;
[61e79a9]462
463  if (getenv("DISPLAY")) {
464    out=owl_strdup(getenv("DISPLAY"));
[5145235]465  } else if ((tmp=ttyname(fileno(stdout)))!=NULL) {
466    out=owl_strdup(tmp);
[61e79a9]467    if (!strncmp(out, "/dev/", 5)) {
468      owl_free(out);
[5145235]469      out=owl_strdup(tmp+5);
[61e79a9]470    }
471  } else {
[5145235]472    out=owl_strdup("unknown");
[61e79a9]473  }
474  return(out);
475}
476
[e4eebe8]477/* strip leading and trailing new lines.  Caller must free the
478 * return.
479 */
[e19eb97]480char *owl_util_stripnewlines(const char *in)
[e4eebe8]481{
[7e3e00a]482 
483  char  *tmp, *ptr1, *ptr2, *out;
484
485  ptr1=tmp=owl_strdup(in);
486  while (ptr1[0]=='\n') {
487    ptr1++;
488  }
489  ptr2=ptr1+strlen(ptr1)-1;
[1bb1e67]490  while (ptr2>ptr1 && ptr2[0]=='\n') {
[7e3e00a]491    ptr2[0]='\0';
492    ptr2--;
493  }
494
495  out=owl_strdup(ptr1);
496  owl_free(tmp);
497  return(out);
498}
499
[946058b]500/* Delete all lines matching "line" from the named file.  If no such
501 * line is found the file is left intact.  If backup==1 then leave a
502 * backup file containing the original contents.  The match is
503 * case-insensitive.
[da60ba9]504 *
505 * Returns the number of lines removed
[38cf544c]506 */
[da60ba9]507int owl_util_file_deleteline(const char *filename, const char *line, int backup)
[38cf544c]508{
[946058b]509  char *backupfile, *newfile, *buf = NULL;
510  FILE *old, *new;
511  struct stat st;
[da60ba9]512  int numremoved = 0;
[38cf544c]513
[946058b]514  if ((old = fopen(filename, "r")) == NULL) {
515    owl_function_error("Cannot open %s (for reading): %s",
516                       filename, strerror(errno));
[da60ba9]517    return 0;
[38cf544c]518  }
[e6449bc]519
[946058b]520  if (fstat(fileno(old), &st) != 0) {
521    owl_function_error("Cannot stat %s: %s", filename, strerror(errno));
522    return 0;
[38cf544c]523  }
524
[946058b]525  newfile = owl_sprintf("%s.new", filename);
526  if ((new = fopen(newfile, "w")) == NULL) {
527    owl_function_error("Cannot open %s (for writing): %s",
528                       filename, strerror(errno));
529    free(newfile);
530    fclose(old);
531    return 0;
532  }
533
534  if (fchmod(fileno(new), st.st_mode & 0777) != 0) {
535    owl_function_error("Cannot set permissions on %s: %s",
536                       filename, strerror(errno));
537    unlink(newfile);
538    fclose(new);
539    free(newfile);
540    fclose(old);
541    return 0;
542  }
543
544  while (owl_getline_chomp(&buf, old))
545    if (strcasecmp(buf, line) != 0)
546      fprintf(new, "%s\n", buf);
547    else
[da60ba9]548      numremoved++;
[38cf544c]549
[946058b]550  fclose(new);
551  fclose(old);
552
553  if (backup) {
554    backupfile = owl_sprintf("%s.backup", filename);
555    unlink(backupfile);
556    if (link(filename, backupfile) != 0) {
557      owl_function_error("Cannot link %s: %s", backupfile, strerror(errno));
558      owl_free(backupfile);
559      unlink(newfile);
560      owl_free(newfile);
561      return 0;
[6a50af2]562    }
[946058b]563    owl_free(backupfile);
[38cf544c]564  }
565
[946058b]566  if (rename(newfile, filename) != 0) {
567    owl_function_error("Cannot move %s to %s: %s",
568                       newfile, filename, strerror(errno));
569    numremoved = 0;
[38cf544c]570  }
571
[946058b]572  unlink(newfile);
573  owl_free(newfile);
[da60ba9]574
575  return numremoved;
[38cf544c]576}
577
[fe67f1f]578int owl_util_max(int a, int b)
579{
580  if (a>b) return(a);
581  return(b);
582}
583
584int owl_util_min(int a, int b)
585{
586  if (a<b) return(a);
587  return(b);
588}
589
[7a20e4c]590/* Return the base class or instance from a zephyr class, by removing
591   leading `un' or trailing `.d'.
[be5aa09]592   The caller is responsible for freeing the allocated string.
[7a20e4c]593*/
[e19eb97]594char * owl_util_baseclass(const char * class)
[7a20e4c]595{
[59916e8]596  char *start, *end;
597
[fa4562c]598  while(!strncmp(class, "un", 2)) {
599    class += 2;
[7a20e4c]600  }
[f166580]601
[fa4562c]602  start = owl_strdup(class);
[59916e8]603  end = start + strlen(start) - 1;
[04166e9]604  while(end > start && *end == 'd' && *(end-1) == '.') {
[7a20e4c]605    end -= 2;
606  }
607  *(end + 1) = 0;
[59916e8]608
[f166580]609  return start;
[7a20e4c]610}
611
[c79a047]612const char * owl_get_datadir(void)
[5376a95]613{
[e19eb97]614  const char * datadir = getenv("BARNOWL_DATA_DIR");
[5376a95]615  if(datadir != NULL)
[7bf51d5]616    return datadir;
[5376a95]617  return DATADIR;
618}
619
620/* Strips format characters from a valid utf-8 string. Returns the
621   empty string if 'in' does not validate. */
[7f6a8a2]622char * owl_strip_format_chars(const char *in)
[5376a95]623{
624  char *r;
625  if (g_utf8_validate(in, -1, NULL)) {
[7f6a8a2]626    const char *s, *p;
[5376a95]627    r = owl_malloc(strlen(in)+1);
628    r[0] = '\0';
629    s = in;
630    p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
631    while(p) {
632      /* If it's a format character, copy up to it, and skip all
633         immediately following format characters. */
[c1522ec]634      if (owl_fmtext_is_format_char(g_utf8_get_char(p))) {
[5376a95]635        strncat(r, s, p-s);
636        p = g_utf8_next_char(p);
[f119757]637        while (owl_fmtext_is_format_char(g_utf8_get_char(p))) {
[5376a95]638          p = g_utf8_next_char(p);
639        }
640        s = p;
641        p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
642      }
643      else {
644        p = strchr(p+1, OWL_FMTEXT_UC_STARTBYTE_UTF8);
645      }
646    }
647    if (s) strcat(r,s);
648  }
649  else {
650    r = owl_strdup("");
651  }
652  return r;
653}
654
655/* If in is not UTF-8, convert from ISO-8859-1. We may want to allow
656 * the caller to specify an alternative in the future. We also strip
657 * out characters in Unicode Plane 16, as we use that plane internally
658 * for formatting.
659 */
[7f6a8a2]660char * owl_validate_or_convert(const char *in)
[5376a95]661{
[6201646]662  if (g_utf8_validate(in, -1, NULL)) {
[5376a95]663    return owl_strip_format_chars(in);
664  }
665  else {
[6201646]666    return g_convert(in, -1,
[5376a95]667                     "UTF-8", "ISO-8859-1",
668                     NULL, NULL, NULL);
669  }
[89f5338]670}
[4b17a6c]671/*
672 * Validate 'in' as UTF-8, and either return a copy of it, or an empty
673 * string if it is invalid utf-8.
[7b1d048]674 */
[7f6a8a2]675char * owl_validate_utf8(const char *in)
[7b1d048]676{
677  char *out;
678  if (g_utf8_validate(in, -1, NULL)) {
[4b17a6c]679    out = owl_strdup(in);
680  } else {
[7b1d048]681    out = owl_strdup("");
682  }
683  return out;
684}
[89f5338]685
[84027015]686/* This is based on _extract() and _isCJ() from perl's Text::WrapI18N */
687int owl_util_can_break_after(gunichar c)
688{
689 
690  if (c == ' ') return 1;
691  if (c >= 0x3000 && c <= 0x312f) {
692    /* CJK punctuations, Hiragana, Katakana, Bopomofo */
693    if (c == 0x300a || c == 0x300c || c == 0x300e ||
694        c == 0x3010 || c == 0x3014 || c == 0x3016 ||
695        c == 0x3018 || c == 0x301a)
696      return 0;
697    return 1;
698  }
699  if (c >= 0x31a0 && c <= 0x31bf) {return 1;}  /* Bopomofo */
700  if (c >= 0x31f0 && c <= 0x31ff) {return 1;}  /* Katakana extension */
701  if (c >= 0x3400 && c <= 0x9fff) {return 1;}  /* Han Ideogram */
702  if (c >= 0xf900 && c <= 0xfaff) {return 1;}  /* Han Ideogram */
703  if (c >= 0x20000 && c <= 0x2ffff) {return 1;}  /* Han Ideogram */
704  return 0;
705}
[eea72a13]706
707char *owl_escape_highbit(const char *str)
708{
709  GString *out = g_string_new("");
710  unsigned char c;
711  while((c = (*str++))) {
712    if(c == '\\') {
713      g_string_append(out, "\\\\");
714    } else if(c & 0x80) {
715      g_string_append_printf(out, "\\x%02x", (int)c);
716    } else {
717      g_string_append_c(out, c);
718    }
719  }
720  return g_string_free(out, 0);
721}
[6ace255]722
723/* innards of owl_getline{,_chomp} below */
724static int owl_getline_internal(char **s, FILE *fp, int newline)
725{
726  int size = 0;
727  int target = 0;
728  int count = 0;
729  int c;
730
731  while (1) {
732    c = getc(fp);
733    if ((target + 1) > size) {
734      size += BUFSIZ;
735      *s = owl_realloc(*s, size);
736    }
737    if (c == EOF)
738      break;
739    count++;
740    if (c != '\n' || newline)
741        (*s)[target++] = c;
742    if (c == '\n')
743      break;
744  }
745  (*s)[target] = 0;
746
747  return count;
748}
749
750/* Read a line from fp, allocating memory to hold it, returning the number of
751 * byte read.  *s should either be NULL or a pointer to memory allocated with
752 * owl_malloc; it will be owl_realloc'd as appropriate.  The caller must
753 * eventually free it.  (This is roughly the interface of getline in the gnu
754 * libc).
755 *
756 * The final newline will be included if it's there.
757 */
758int owl_getline(char **s, FILE *fp)
759{
760  return owl_getline_internal(s, fp, 1);
761}
762
763/* As above, but omitting the final newline */
764int owl_getline_chomp(char **s, FILE *fp)
765{
766  return owl_getline_internal(s, fp, 0);
767}
768
769/* Read the rest of the input available in fp into a string. */
770char *owl_slurp(FILE *fp)
771{
772  char *buf = NULL;
773  char *p;
774  int size = 0;
775  int count;
776
777  while (1) {
778    buf = owl_realloc(buf, size + BUFSIZ);
779    p = &buf[size];
780    size += BUFSIZ;
781
782    if ((count = fread(p, 1, BUFSIZ, fp)) < BUFSIZ)
783      break;
784  }
785  p[count] = 0;
786
787  return buf;
788}
Note: See TracBrowser for help on using the repository browser.