mcabber/src/hbuf.c
changeset 942 c6bd42119c31
parent 932 fc6aaa223650
child 943 9ac0d166a85b
equal deleted inserted replaced
941:518e7c17a79e 942:c6bd42119c31
    52 // Note 2: width does not include the ending \0.
    52 // Note 2: width does not include the ending \0.
    53 void hbuf_add_line(GList **p_hbuf, const char *text, time_t timestamp,
    53 void hbuf_add_line(GList **p_hbuf, const char *text, time_t timestamp,
    54         guint prefix_flags, guint width)
    54         guint prefix_flags, guint width)
    55 {
    55 {
    56   GList *hbuf = *p_hbuf;
    56   GList *hbuf = *p_hbuf;
    57   char *line, *cr, *end;
    57   GList *curr_elt;
    58   hbuf_block *hbuf_block_elt;
    58   char *line, *end;
       
    59   hbuf_block *hbuf_block_elt, *hbuf_b_curr;
    59 
    60 
    60   if (!text) return;
    61   if (!text) return;
    61 
    62 
    62   hbuf_block_elt = g_new0(hbuf_block, 1);
    63   hbuf_block_elt = g_new0(hbuf_block, 1);
    63   hbuf_block_elt->prefix.timestamp  = timestamp;
    64   hbuf_block_elt->prefix.timestamp  = timestamp;
    95   // Ok, now we can copy the text..
    96   // Ok, now we can copy the text..
    96   strcpy(line, text);
    97   strcpy(line, text);
    97   hbuf_block_elt->ptr_end = line + strlen(line) + 1;
    98   hbuf_block_elt->ptr_end = line + strlen(line) + 1;
    98   end = hbuf_block_elt->ptr_end;
    99   end = hbuf_block_elt->ptr_end;
    99 
   100 
       
   101   curr_elt = g_list_last(hbuf);
       
   102 
   100   // Let's add non-persistent blocs if necessary
   103   // Let's add non-persistent blocs if necessary
   101   // - If there are '\n' in the string
   104   // - If there are '\n' in the string
   102   // - If length > width (and width != 0)
   105   // - If length > width (and width != 0)
   103   cr = strchr(line, '\n');
   106   while (curr_elt) {
   104   while (cr || (width && strlen(line) > width)) {
   107     hbuf_block *hbuf_b_prev;
   105     hbuf_block *hbuf_b_prev = hbuf_block_elt;
   108     char *c, *end;
   106 
   109     char *br = NULL; // break pointer
   107     if (!width || (cr && (cr - line <= (int)width))) {
   110     char *cr = NULL; // CR pointer
   108       // Carriage return
   111     unsigned int cur_w = 0;
   109       *cr = 0;
   112 
   110       hbuf_block_elt->ptr_end = cr;
   113     // We want to break where we can find a space char or a CR
   111       // Create another persistent block
   114 
   112       hbuf_block_elt = g_new0(hbuf_block, 1);
   115     hbuf_b_curr = (hbuf_block*)(curr_elt->data);
   113       hbuf_block_elt->ptr      = hbuf_b_prev->ptr_end + 1; // == cr+1
   116     hbuf_b_prev = hbuf_b_curr;
   114       hbuf_block_elt->ptr_end  = end;
   117     c = hbuf_b_curr->ptr;
   115       hbuf_block_elt->flags    = HBB_FLAG_PERSISTENT;
   118 
   116       hbuf_block_elt->ptr_end_alloc = hbuf_b_prev->ptr_end_alloc;
   119     while (*c && (!width || cur_w <= width)) {
   117       *p_hbuf = g_list_append(*p_hbuf, hbuf_block_elt);
   120       if (*c == '\n') {
   118       line = hbuf_block_elt->ptr;
   121         br = cr = c;
   119     } else {
   122         *c = 0;
   120       // We need to break where we can find a space char
   123         break;
   121       char *br; // break pointer
   124       }
   122       for (br = line + width; br > line && *br != 32 && *br != 9; br--)
   125       if (iswblank(get_char(c)))
   123         ;
   126         br = c;
   124       if (br <= line)
   127       cur_w += get_char_width(c);
   125         br = line + width;
   128       c = next_char(c);
       
   129     }
       
   130 
       
   131     if (cr || (*c && cur_w > width)) {
       
   132       if (!br || br == hbuf_b_curr->ptr)
       
   133         br = c;
   126       else
   134       else
   127         br++;
   135         br = next_char(br);
   128       hbuf_block_elt->ptr_end = br;
   136       end = hbuf_b_curr->ptr_end;
   129       // Create another block, non-persistent
   137       hbuf_b_curr->ptr_end = br;
   130       hbuf_block_elt = g_new0(hbuf_block, 1);
   138       // Create another block
   131       hbuf_block_elt->ptr      = hbuf_b_prev->ptr_end; // == br
   139       hbuf_b_curr = g_new0(hbuf_block, 1);
   132       hbuf_block_elt->ptr_end  = end;
   140       // The block must be persistent after a CR
   133       hbuf_block_elt->flags    = 0;
   141       if (cr) {
   134       hbuf_block_elt->ptr_end_alloc = hbuf_b_prev->ptr_end_alloc;
   142         hbuf_b_curr->ptr    = hbuf_b_prev->ptr_end + 1; // == cr+1
   135       *p_hbuf = g_list_append(*p_hbuf, hbuf_block_elt);
   143         hbuf_b_curr->flags  = HBB_FLAG_PERSISTENT;
   136       line = hbuf_block_elt->ptr;
   144       } else {
   137     }
   145         hbuf_b_curr->ptr    = hbuf_b_prev->ptr_end; // == br
   138     cr = strchr(line, '\n');
   146         hbuf_b_curr->flags    = 0;
       
   147       }
       
   148       hbuf_b_curr->ptr_end  = end;
       
   149       hbuf_b_curr->ptr_end_alloc = hbuf_b_prev->ptr_end_alloc;
       
   150       // This is OK because insert_before(NULL) == append():
       
   151       *p_hbuf = g_list_insert_before(*p_hbuf, curr_elt->next, hbuf_b_curr);
       
   152     }
       
   153     curr_elt = g_list_next(curr_elt);
   139   }
   154   }
   140 }
   155 }
   141 
   156 
   142 //  hbuf_free()
   157 //  hbuf_free()
   143 // Destroys all hbuf list.
   158 // Destroys all hbuf list.