Changeset 12c35df for fmtext.c


Ignore:
Timestamp:
Oct 28, 2003, 7:56:35 PM (18 years ago)
Author:
James M. Kretchmar <kretch@mit.edu>
Branches:
master, barnowl_perlaim, debian, owl, release-1.4, release-1.5, release-1.6, release-1.7, release-1.8, release-1.9
Children:
cee1f25
Parents:
faf71b5
Message:
Fixed replies to loopback messages
Fixed smartnarrow on classes/instances with spaces
Don't allow duplicates in command history
Added the 'loggingdirection' variable
All loopback messages log to 'loopback' now
Print an error message if trying an invalid color for a filter
Fixed bug causing > not to go to end of editwin every time
File:
1 edited

Legend:

Unmodified
Added
Removed
  • fmtext.c

    rbd3f232 r12c35df  
    122122  }
    123123}
     124
     125/* Internal function.  Append text from 'in' between index 'start' and
     126 * 'stop' to the end of 'f'
     127 */
     128void _owl_fmtext_append_fmtext(owl_fmtext *f, owl_fmtext *in, int start, int stop)
     129{
     130  int newlen, i;
     131
     132  newlen=strlen(f->textbuff)+(stop-start+1);
     133  f->textbuff=owl_realloc(f->textbuff, newlen+1);
     134  f->fmbuff=owl_realloc(f->fmbuff, newlen+1);
     135  f->colorbuff=owl_realloc(f->colorbuff, newlen+1);
     136
     137  strncat(f->textbuff, in->textbuff+start, stop-start+1);
     138  f->textbuff[newlen]='\0';
     139  for (i=start; i<=stop; i++) {
     140    f->fmbuff[f->textlen+(i-start)]=in->fmbuff[i];
     141    f->colorbuff[f->textlen+(i-start)]=in->colorbuff[i];
     142  }
     143  f->textlen=newlen;
     144}
     145
     146/* append fmtext 'in' to 'f' */
     147void owl_fmtext_append_fmtext(owl_fmtext *f, owl_fmtext *in)
     148{
     149  _owl_fmtext_append_fmtext(f, in, 0, in->textlen);
     150
     151}
     152
     153/* Append 'nspaces' number of spaces to the end of 'f' */
     154void owl_fmtext_append_spaces(owl_fmtext *f, int nspaces)
     155{
     156  int i;
     157  for (i=0; i<nspaces; i++) {
     158    owl_fmtext_append_normal(f, " ");
     159  }
     160}
     161
     162/* requires that the list values are strings or NULL.
     163 * joins the elements together with join_with.
     164 * If format_fn is specified, passes it the list element value
     165 * and it will return a string which this needs to free. */
     166void owl_fmtext_append_list(owl_fmtext *f, owl_list *l, char *join_with, char *(format_fn)(void*))
     167{
     168  int i, size;
     169  void *elem;
     170  char *text;
     171
     172  size = owl_list_get_size(l);
     173  for (i=0; i<size; i++) {
     174    elem = (char*)owl_list_get_element(l,i);
     175    if (elem && format_fn) {
     176      text = format_fn(elem);
     177      if (text) {
     178        owl_fmtext_append_normal(f, text);
     179        owl_free(text);
     180      }
     181    } else if (elem) {
     182      owl_fmtext_append_normal(f, elem);
     183    }
     184    if ((i < size-1) && join_with) {
     185      owl_fmtext_append_normal(f, join_with);
     186    }
     187  }
     188}
     189
     190/* Return a plain version of the fmtext.  Caller is responsible for
     191 * freeing the return
     192 */
     193char *owl_fmtext_print_plain(owl_fmtext *f)
     194{
     195  return(owl_strdup(f->textbuff));
     196}
     197
     198/* add the formatted text to the curses window 'w'.  The window 'w'
     199 * must already be initiatlized with curses
     200 */
     201void owl_fmtext_curs_waddstr(owl_fmtext *f, WINDOW *w)
     202{
     203  char *tmpbuff;
     204  int position, trans1, trans2, len, lastsame;
     205
     206  if (w==NULL) {
     207    owl_function_debugmsg("Hit a null window in owl_fmtext_curs_waddstr.");
     208    return;
     209  }
     210
     211  tmpbuff=owl_malloc(f->textlen+10);
     212
     213  position=0;
     214  len=f->textlen;
     215  while (position<=len) {
     216    /* find the last char with the current format and color */
     217    trans1=owl_util_find_trans(f->fmbuff+position, len-position);
     218    trans2=owl_util_find_trans(f->colorbuff+position, len-position);
     219
     220    if (trans1<trans2) {
     221      lastsame=position+trans1;
     222    } else {
     223      lastsame=position+trans2;
     224    }
     225
     226    /* set the format */
     227    wattrset(w, A_NORMAL);
     228    if (f->fmbuff[position] & OWL_FMTEXT_ATTR_BOLD) {
     229      wattron(w, A_BOLD);
     230    }
     231    if (f->fmbuff[position] & OWL_FMTEXT_ATTR_REVERSE) {
     232      wattron(w, A_REVERSE);
     233    }
     234    if (f->fmbuff[position] & OWL_FMTEXT_ATTR_UNDERLINE) {
     235      wattron(w, A_UNDERLINE);
     236    }
     237
     238    /* set the color */
     239    /* warning, this is sort of a hack */
     240    if (owl_global_get_hascolors(&g)) {
     241      if (f->colorbuff[position]!=OWL_COLOR_DEFAULT) {
     242        wattron(w, COLOR_PAIR(f->colorbuff[position]));
     243      }
     244    }
     245
     246    /* add the text */
     247    strncpy(tmpbuff, f->textbuff + position, lastsame-position+1);
     248    tmpbuff[lastsame-position+1]='\0';
     249    waddstr(w, tmpbuff);
     250
     251    position=lastsame+1;
     252  }
     253  owl_free(tmpbuff);
     254}
     255
     256
     257/* start with line 'aline' (where the first line is 0) and print
     258 * 'lines' number of lines into 'out'
     259 */
     260int owl_fmtext_truncate_lines(owl_fmtext *in, int aline, int lines, owl_fmtext *out)
     261{
     262  char *ptr1, *ptr2;
     263  int i, offset;
     264 
     265  /* find the starting line */
     266  ptr1=in->textbuff;
     267  if (aline!=0) {
     268    for (i=0; i<aline; i++) {
     269      ptr1=strchr(ptr1, '\n');
     270      if (!ptr1) return(-1);
     271      ptr1++;
     272    }
     273  }
     274  /* ptr1 now holds the starting point */
     275
     276  /* copy in the next 'lines' lines */
     277  if (lines<1) return(-1);
     278
     279  for (i=0; i<lines; i++) {
     280    offset=ptr1-in->textbuff;
     281    ptr2=strchr(ptr1, '\n');
     282    if (!ptr2) {
     283      _owl_fmtext_append_fmtext(out, in, offset, (in->textlen)-1);
     284      return(-1);
     285    }
     286    _owl_fmtext_append_fmtext(out, in, offset, (ptr2-ptr1)+offset);
     287    ptr1=ptr2+1;
     288  }
     289  return(0);
     290}
     291
     292/* Truncate the message so that each line begins at column 'acol' and
     293 * ends at 'bcol' or sooner.  The first column is number 0.  The new
     294 * message is placed in 'out'.  The message is * expected to end in a
     295 * new line for now
     296 */
     297void owl_fmtext_truncate_cols(owl_fmtext *in, int acol, int bcol, owl_fmtext *out)
     298{
     299  char *ptr1, *ptr2, *last;
     300  int len, offset;
     301
     302  last=in->textbuff+in->textlen-1;
     303  ptr1=in->textbuff;
     304  while (ptr1<=last) {
     305    ptr2=strchr(ptr1, '\n');
     306    if (!ptr2) {
     307      /* but this shouldn't happen if we end in a \n */
     308      break;
     309    }
     310   
     311    if (ptr2==ptr1) {
     312      owl_fmtext_append_normal(out, "\n");
     313      ptr1++;
     314      continue;
     315    }
     316
     317    /* we need to check that we won't run over here */
     318    len=bcol-acol;
     319    if (len > (ptr2-(ptr1+acol))) {
     320      /* the whole line fits with room to spare, don't take a full 'len' */
     321      len=ptr2-(ptr1+acol);
     322    }
     323    if (len>last-ptr1) {
     324      /* the whole rest of the text fits with room to spare, adjust for it */
     325      len-=(last-ptr1);
     326    }
     327    if (len<=0) {
     328      /* saftey check */
     329      owl_fmtext_append_normal(out, "\n");
     330      ptr1=ptr2+1;
     331      continue;
     332    }
     333
     334    offset=ptr1-in->textbuff;
     335    _owl_fmtext_append_fmtext(out, in, offset+acol, offset+acol+len);
     336
     337    ptr1=ptr2+1;
     338  }
     339}
     340
     341/* Return the number of lines in 'f' */
     342int owl_fmtext_num_lines(owl_fmtext *f)
     343{
     344  int lines, i;
     345
     346  if (f->textlen==0) return(0);
     347 
     348  lines=0;
     349  for (i=0; i<f->textlen; i++) {
     350    if (f->textbuff[i]=='\n') lines++;
     351  }
     352
     353  /* if the last char wasn't a \n there's one more line */
     354  if (f->textbuff[i-1]!='\n') lines++;
     355
     356  return(lines);
     357}
     358
     359char *owl_fmtext_get_text(owl_fmtext *f)
     360{
     361  return(f->textbuff);
     362}
     363
     364void owl_fmtext_set_char(owl_fmtext *f, int index, int ch)
     365{
     366  /* set the charater at 'index' to be 'char'.  If index is out of
     367   * bounds don't do anything */
     368  if ((index < 0) || (index > f->textlen-1)) return;
     369  f->textbuff[index]=ch;
     370}
     371
     372/* Free all memory allocated by the object */
     373void owl_fmtext_free(owl_fmtext *f)
     374{
     375  if (f->textbuff) owl_free(f->textbuff);
     376  if (f->fmbuff) owl_free(f->fmbuff);
     377  if (f->colorbuff) owl_free(f->colorbuff);
     378}
     379
     380/* Make a copy of the fmtext 'src' into 'dst' */
     381void owl_fmtext_copy(owl_fmtext *dst, owl_fmtext *src)
     382{
     383  int mallocsize;
     384
     385  if (src->textlen==0) {
     386    mallocsize=5;
     387  } else {
     388    mallocsize=src->textlen+2;
     389  }
     390  dst->textlen=src->textlen;
     391  dst->textbuff=owl_malloc(mallocsize);
     392  dst->fmbuff=owl_malloc(mallocsize);
     393  dst->colorbuff=owl_malloc(mallocsize);
     394  memcpy(dst->textbuff, src->textbuff, src->textlen+1);
     395  memcpy(dst->fmbuff, src->fmbuff, src->textlen);
     396  memcpy(dst->colorbuff, src->colorbuff, src->textlen);
     397}
     398
     399/* highlight all instances of "string".  Return the number of
     400 * instances found.  This is a case insensitive search.
     401 */
     402int owl_fmtext_search_and_highlight(owl_fmtext *f, char *string)
     403{
     404
     405  int found, len;
     406  char *ptr1, *ptr2;
     407
     408  len=strlen(string);
     409  found=0;
     410  ptr1=f->textbuff;
     411  while (ptr1-f->textbuff <= f->textlen) {
     412    ptr2=stristr(ptr1, string);
     413    if (!ptr2) return(found);
     414
     415    found++;
     416    _owl_fmtext_add_attr(f, OWL_FMTEXT_ATTR_REVERSE,
     417                         ptr2 - f->textbuff,
     418                         ptr2 - f->textbuff + len - 1);
     419
     420    ptr1=ptr2+len;
     421  }
     422  return(found);
     423}
     424
     425/* return 1 if the string is found, 0 if not.  This is a case
     426 *  insensitive search.
     427 */
     428int owl_fmtext_search(owl_fmtext *f, char *string)
     429{
     430
     431  if (stristr(f->textbuff, string)) return(1);
     432  return(0);
     433}
     434
    124435
    125436/* Append the text 'text' to 'f' and interpret the zephyr style
     
    311622  }
    312623}
    313 
    314 /* Internal function.  Append text from 'in' between index 'start' and
    315  * 'stop' to the end of 'f'
    316  */
    317 void _owl_fmtext_append_fmtext(owl_fmtext *f, owl_fmtext *in, int start, int stop)
    318 {
    319   int newlen, i;
    320 
    321   newlen=strlen(f->textbuff)+(stop-start+1);
    322   f->textbuff=owl_realloc(f->textbuff, newlen+1);
    323   f->fmbuff=owl_realloc(f->fmbuff, newlen+1);
    324   f->colorbuff=owl_realloc(f->colorbuff, newlen+1);
    325 
    326   strncat(f->textbuff, in->textbuff+start, stop-start+1);
    327   f->textbuff[newlen]='\0';
    328   for (i=start; i<=stop; i++) {
    329     f->fmbuff[f->textlen+(i-start)]=in->fmbuff[i];
    330     f->colorbuff[f->textlen+(i-start)]=in->colorbuff[i];
    331   }
    332   f->textlen=newlen;
    333 }
    334 
    335 /* append fmtext 'in' to 'f' */
    336 void owl_fmtext_append_fmtext(owl_fmtext *f, owl_fmtext *in)
    337 {
    338   _owl_fmtext_append_fmtext(f, in, 0, in->textlen);
    339 
    340 }
    341 
    342 /* Append 'nspaces' number of spaces to the end of 'f' */
    343 void owl_fmtext_append_spaces(owl_fmtext *f, int nspaces)
    344 {
    345   int i;
    346   for (i=0; i<nspaces; i++) {
    347     owl_fmtext_append_normal(f, " ");
    348   }
    349 }
    350 
    351 /* requires that the list values are strings or NULL.
    352  * joins the elements together with join_with.
    353  * If format_fn is specified, passes it the list element value
    354  * and it will return a string which this needs to free. */
    355 void owl_fmtext_append_list(owl_fmtext *f, owl_list *l, char *join_with, char *(format_fn)(void*))
    356 {
    357   int i, size;
    358   void *elem;
    359   char *text;
    360 
    361   size = owl_list_get_size(l);
    362   for (i=0; i<size; i++) {
    363     elem = (char*)owl_list_get_element(l,i);
    364     if (elem && format_fn) {
    365       text = format_fn(elem);
    366       if (text) {
    367         owl_fmtext_append_normal(f, text);
    368         owl_free(text);
    369       }
    370     } else if (elem) {
    371       owl_fmtext_append_normal(f, elem);
    372     }
    373     if ((i < size-1) && join_with) {
    374       owl_fmtext_append_normal(f, join_with);
    375     }
    376   }
    377 }
    378 
    379 /* Return a plain version of the fmtext.  Caller is responsible for
    380  * freeing the return
    381  */
    382 char *owl_fmtext_print_plain(owl_fmtext *f)
    383 {
    384   return(owl_strdup(f->textbuff));
    385 }
    386 
    387 /* add the formatted text to the curses window 'w'.  The window 'w'
    388  * must already be initiatlized with curses
    389  */
    390 void owl_fmtext_curs_waddstr(owl_fmtext *f, WINDOW *w)
    391 {
    392   char *tmpbuff;
    393   int position, trans1, trans2, len, lastsame;
    394 
    395   if (w==NULL) {
    396     owl_function_debugmsg("Hit a null window in owl_fmtext_curs_waddstr.");
    397     return;
    398   }
    399 
    400   tmpbuff=owl_malloc(f->textlen+10);
    401 
    402   position=0;
    403   len=f->textlen;
    404   while (position<=len) {
    405     /* find the last char with the current format and color */
    406     trans1=owl_util_find_trans(f->fmbuff+position, len-position);
    407     trans2=owl_util_find_trans(f->colorbuff+position, len-position);
    408 
    409     if (trans1<trans2) {
    410       lastsame=position+trans1;
    411     } else {
    412       lastsame=position+trans2;
    413     }
    414 
    415     /* set the format */
    416     wattrset(w, A_NORMAL);
    417     if (f->fmbuff[position] & OWL_FMTEXT_ATTR_BOLD) {
    418       wattron(w, A_BOLD);
    419     }
    420     if (f->fmbuff[position] & OWL_FMTEXT_ATTR_REVERSE) {
    421       wattron(w, A_REVERSE);
    422     }
    423     if (f->fmbuff[position] & OWL_FMTEXT_ATTR_UNDERLINE) {
    424       wattron(w, A_UNDERLINE);
    425     }
    426 
    427     /* set the color */
    428     /* warning, this is sort of a hack */
    429     if (owl_global_get_hascolors(&g)) {
    430       if (f->colorbuff[position]!=OWL_COLOR_DEFAULT) {
    431         wattron(w, COLOR_PAIR(f->colorbuff[position]));
    432       }
    433     }
    434 
    435     /* add the text */
    436     strncpy(tmpbuff, f->textbuff + position, lastsame-position+1);
    437     tmpbuff[lastsame-position+1]='\0';
    438     waddstr(w, tmpbuff);
    439 
    440     position=lastsame+1;
    441   }
    442   owl_free(tmpbuff);
    443 }
    444 
    445 
    446 /* start with line 'aline' (where the first line is 0) and print
    447  * 'lines' number of lines into 'out'
    448  */
    449 int owl_fmtext_truncate_lines(owl_fmtext *in, int aline, int lines, owl_fmtext *out)
    450 {
    451   char *ptr1, *ptr2;
    452   int i, offset;
    453  
    454   /* find the starting line */
    455   ptr1=in->textbuff;
    456   if (aline!=0) {
    457     for (i=0; i<aline; i++) {
    458       ptr1=strchr(ptr1, '\n');
    459       if (!ptr1) return(-1);
    460       ptr1++;
    461     }
    462   }
    463   /* ptr1 now holds the starting point */
    464 
    465   /* copy in the next 'lines' lines */
    466   if (lines<1) return(-1);
    467 
    468   for (i=0; i<lines; i++) {
    469     offset=ptr1-in->textbuff;
    470     ptr2=strchr(ptr1, '\n');
    471     if (!ptr2) {
    472       _owl_fmtext_append_fmtext(out, in, offset, (in->textlen)-1);
    473       return(-1);
    474     }
    475     _owl_fmtext_append_fmtext(out, in, offset, (ptr2-ptr1)+offset);
    476     ptr1=ptr2+1;
    477   }
    478   return(0);
    479 }
    480 
    481 /* Truncate the message so that each line begins at column 'acol' and
    482  * ends at 'bcol' or sooner.  The first column is number 0.  The new
    483  * message is placed in 'out'.  The message is * expected to end in a
    484  * new line for now
    485  */
    486 void owl_fmtext_truncate_cols(owl_fmtext *in, int acol, int bcol, owl_fmtext *out)
    487 {
    488   char *ptr1, *ptr2, *last;
    489   int len, offset;
    490 
    491   last=in->textbuff+in->textlen-1;
    492   ptr1=in->textbuff;
    493   while (ptr1<=last) {
    494     ptr2=strchr(ptr1, '\n');
    495     if (!ptr2) {
    496       /* but this shouldn't happen if we end in a \n */
    497       break;
    498     }
    499    
    500     if (ptr2==ptr1) {
    501       owl_fmtext_append_normal(out, "\n");
    502       ptr1++;
    503       continue;
    504     }
    505 
    506     /* we need to check that we won't run over here */
    507     len=bcol-acol;
    508     if (len > (ptr2-(ptr1+acol))) {
    509       /* the whole line fits with room to spare, don't take a full 'len' */
    510       len=ptr2-(ptr1+acol);
    511     }
    512     if (len>last-ptr1) {
    513       /* the whole rest of the text fits with room to spare, adjust for it */
    514       len-=(last-ptr1);
    515     }
    516     if (len<=0) {
    517       /* saftey check */
    518       owl_fmtext_append_normal(out, "\n");
    519       ptr1=ptr2+1;
    520       continue;
    521     }
    522 
    523     offset=ptr1-in->textbuff;
    524     _owl_fmtext_append_fmtext(out, in, offset+acol, offset+acol+len);
    525 
    526     ptr1=ptr2+1;
    527   }
    528 }
    529 
    530 /* Return the number of lines in 'f' */
    531 int owl_fmtext_num_lines(owl_fmtext *f)
    532 {
    533   int lines, i;
    534 
    535   if (f->textlen==0) return(0);
    536  
    537   lines=0;
    538   for (i=0; i<f->textlen; i++) {
    539     if (f->textbuff[i]=='\n') lines++;
    540   }
    541 
    542   /* if the last char wasn't a \n there's one more line */
    543   if (f->textbuff[i-1]!='\n') lines++;
    544 
    545   return(lines);
    546 }
    547 
    548 char *owl_fmtext_get_text(owl_fmtext *f)
    549 {
    550   return(f->textbuff);
    551 }
    552 
    553 void owl_fmtext_set_char(owl_fmtext *f, int index, int ch)
    554 {
    555   /* set the charater at 'index' to be 'char'.  If index is out of
    556    * bounds don't do anything */
    557   if ((index < 0) || (index > f->textlen-1)) return;
    558   f->textbuff[index]=ch;
    559 }
    560 
    561 /* Free all memory allocated by the object */
    562 void owl_fmtext_free(owl_fmtext *f)
    563 {
    564   if (f->textbuff) owl_free(f->textbuff);
    565   if (f->fmbuff) owl_free(f->fmbuff);
    566   if (f->colorbuff) owl_free(f->colorbuff);
    567 }
    568 
    569 /* Make a copy of the fmtext 'src' into 'dst' */
    570 void owl_fmtext_copy(owl_fmtext *dst, owl_fmtext *src)
    571 {
    572   int mallocsize;
    573 
    574   if (src->textlen==0) {
    575     mallocsize=5;
    576   } else {
    577     mallocsize=src->textlen+2;
    578   }
    579   dst->textlen=src->textlen;
    580   dst->textbuff=owl_malloc(mallocsize);
    581   dst->fmbuff=owl_malloc(mallocsize);
    582   dst->colorbuff=owl_malloc(mallocsize);
    583   memcpy(dst->textbuff, src->textbuff, src->textlen+1);
    584   memcpy(dst->fmbuff, src->fmbuff, src->textlen);
    585   memcpy(dst->colorbuff, src->colorbuff, src->textlen);
    586 }
    587 
    588 /* highlight all instance of "string".  Return the number of
    589  * instances found.  This is a case insensitive search.
    590  */
    591 int owl_fmtext_search_and_highlight(owl_fmtext *f, char *string)
    592 {
    593 
    594   int found, len;
    595   char *ptr1, *ptr2;
    596 
    597   len=strlen(string);
    598   found=0;
    599   ptr1=f->textbuff;
    600   while (ptr1-f->textbuff <= f->textlen) {
    601     ptr2=stristr(ptr1, string);
    602     if (!ptr2) return(found);
    603 
    604     found++;
    605     _owl_fmtext_add_attr(f, OWL_FMTEXT_ATTR_REVERSE,
    606                          ptr2 - f->textbuff,
    607                          ptr2 - f->textbuff + len - 1);
    608 
    609     ptr1=ptr2+len;
    610   }
    611   return(found);
    612 }
    613 
    614 /* return 1 if the string is found, 0 if not.  This is a case
    615  *  insensitive search.
    616  */
    617 int owl_fmtext_search(owl_fmtext *f, char *string)
    618 {
    619 
    620   if (stristr(f->textbuff, string)) return(1);
    621   return(0);
    622 }
Note: See TracChangeset for help on using the changeset viewer.