(linenum→info "unix/slp.c:2238")

binutils/2.18/gas/sb.c

    1: /* sb.c - string buffer manipulation routines
    2:    Copyright 1994, 1995, 2000, 2003, 2006, 2007
    3:    Free Software Foundation, Inc.
    4: 
    5:    Written by Steve and Judy Chamberlain of Cygnus Support,
    6:       sac@cygnus.com
    7: 
    8:    This file is part of GAS, the GNU Assembler.
    9: 
   10:    GAS is free software; you can redistribute it and/or modify
   11:    it under the terms of the GNU General Public License as published by
   12:    the Free Software Foundation; either version 3, or (at your option)
   13:    any later version.
   14: 
   15:    GAS is distributed in the hope that it will be useful,
   16:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   17:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18:    GNU General Public License for more details.
   19: 
   20:    You should have received a copy of the GNU General Public License
   21:    along with GAS; see the file COPYING.  If not, write to the Free
   22:    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
   23:    02110-1301, USA.  */
   24: 
   25: #include "as.h"
   26: #include "sb.h"
   27: 
   28: /* These routines are about manipulating strings.
   29: 
   30:    They are managed in things called `sb's which is an abbreviation
   31:    for string buffers.  An sb has to be created, things can be glued
   32:    on to it, and at the end of it's life it should be freed.  The
   33:    contents should never be pointed at whilst it is still growing,
   34:    since it could be moved at any time
   35: 
   36:    eg:
   37:    sb_new (&foo);
   38:    sb_grow... (&foo,...);
   39:    use foo->ptr[*];
   40:    sb_kill (&foo);  */
   41: 
   42: static int dsize = 5;
   43: static void sb_check (sb *, int);
   44: 
   45: /* Statistics of sb structures.  */
   46: static int string_count[sb_max_power_two];
   47: 
   48: /* Free list of sb structures.  */
   49: static struct
   50: {
   51:   sb_element *size[sb_max_power_two];
   52: } free_list;
   53: 
   54: /* Initializes an sb.  */
   55: 
   56: static void
   57: sb_build (sb *ptr, int size)
   58: {
   59:   /* See if we can find one to allocate.  */
   60:   sb_element *e;
   61: 
   62:   assert (size < sb_max_power_two);
   63: 
   64:   e = free_list.size[size];
   65:   if (!e)
   66:     {
   67:       /* Nothing there, allocate one and stick into the free list.  */
   68:       e = (sb_element *) xmalloc (sizeof (sb_element) + (1 << size));
   69:       e->next = free_list.size[size];
   70:       e->size = 1 << size;
   71:       free_list.size[size] = e;
   72:       string_count[size]++;
   73:     }
   74: 
   75:   /* Remove from free list.  */
   76:   free_list.size[size] = e->next;
   77: 
   78:   /* Copy into callers world.  */
   79:   ptr->ptr = e->data;
   80:   ptr->pot = size;
   81:   ptr->len = 0;
   82:   ptr->item = e;
   83: }
   84: 
   85: void
   86: sb_new (sb *ptr)
   87: {
   88:   sb_build (ptr, dsize);
   89: }
   90: 
   91: /* Deallocate the sb at ptr.  */
   92: 
   93: void
   94: sb_kill (sb *ptr)
   95: {
   96:   /* Return item to free list.  */
   97:   ptr->item->next = free_list.size[ptr->pot];
   98:   free_list.size[ptr->pot] = ptr->item;
   99: }
  100: 
  101: /* Add the sb at s to the end of the sb at ptr.  */
  102: 
  103: void
  104: sb_add_sb (sb *ptr, sb *s)
  105: {
  106:   sb_check (ptr, s->len);
  107:   memcpy (ptr->ptr + ptr->len, s->ptr, s->len);
  108:   ptr->len += s->len;
  109: }
  110: 
  111: /* Helper for sb_scrub_and_add_sb.  */
  112: 
  113: static sb *sb_to_scrub;
  114: static char *scrub_position;
  115: static int
  116: scrub_from_sb (char *buf, int buflen)
  117: {
  118:   int copy;
  119:   copy = sb_to_scrub->len - (scrub_position - sb_to_scrub->ptr);
  120:   if (copy > buflen)
  121:     copy = buflen;
  122:   memcpy (buf, scrub_position, copy);
  123:   scrub_position += copy;
  124:   return copy;
  125: }
  126: 
  127: /* Run the sb at s through do_scrub_chars and add the result to the sb
  128:    at ptr.  */
  129: 
  130: void
  131: sb_scrub_and_add_sb (sb *ptr, sb *s)
  132: {
  133:   sb_to_scrub = s;
  134:   scrub_position = s->ptr;
  135:   
  136:   sb_check (ptr, s->len);
  137:   ptr->len += do_scrub_chars (scrub_from_sb, ptr->ptr + ptr->len, s->len);
  138: 
  139:   sb_to_scrub = 0;
  140:   scrub_position = 0;
  141: }
  142: 
  143: /* Make sure that the sb at ptr has room for another len characters,
  144:    and grow it if it doesn't.  */
  145: 
  146: static void
  147: sb_check (sb *ptr, int len)
  148: {
  149:   if (ptr->len + len >= 1 << ptr->pot)
  150:     {
  151:       sb tmp;
  152:       int pot = ptr->pot;
  153: 
  154:       while (ptr->len + len >= 1 << pot)
  155:         pot++;
  156:       sb_build (&tmp, pot);
  157:       sb_add_sb (&tmp, ptr);
  158:       sb_kill (ptr);
  159:       *ptr = tmp;
  160:     }
  161: }
  162: 
  163: /* Make the sb at ptr point back to the beginning.  */
  164: 
  165: void
  166: sb_reset (sb *ptr)
  167: {
  168:   ptr->len = 0;
  169: }
  170: 
  171: /* Add character c to the end of the sb at ptr.  */
  172: 
  173: void
  174: sb_add_char (sb *ptr, int c)
  175: {
  176:   sb_check (ptr, 1);
  177:   ptr->ptr[ptr->len++] = c;
  178: }
  179: 
  180: /* Add null terminated string s to the end of sb at ptr.  */
  181: 
  182: void
  183: sb_add_string (sb *ptr, const char *s)
  184: {
  185:   int len = strlen (s);
  186:   sb_check (ptr, len);
  187:   memcpy (ptr->ptr + ptr->len, s, len);
  188:   ptr->len += len;
  189: }
  190: 
  191: /* Add string at s of length len to sb at ptr */
  192: 
  193: void
  194: sb_add_buffer (sb *ptr, const char *s, int len)
  195: {
  196:   sb_check (ptr, len);
  197:   memcpy (ptr->ptr + ptr->len, s, len);
  198:   ptr->len += len;
  199: }
  200: 
  201: /* Like sb_name, but don't include the null byte in the string.  */
  202: 
  203: char *
  204: sb_terminate (sb *in)
  205: {
  206:   sb_add_char (in, 0);
  207:   --in->len;
  208:   return in->ptr;
  209: }
  210: 
  211: /* Start at the index idx into the string in sb at ptr and skip
  212:    whitespace. return the index of the first non whitespace character.  */
  213: 
  214: int
  215: sb_skip_white (int idx, sb *ptr)
  216: {
  217:   while (idx < ptr->len
  218:          && (ptr->ptr[idx] == ' '
  219:              || ptr->ptr[idx] == '\t'))
  220:     idx++;
  221:   return idx;
  222: }
  223: 
  224: /* Start at the index idx into the sb at ptr. skips whitespace,
  225:    a comma and any following whitespace. returns the index of the
  226:    next character.  */
  227: 
  228: int
  229: sb_skip_comma (int idx, sb *ptr)
  230: {
  231:   while (idx < ptr->len
  232:          && (ptr->ptr[idx] == ' '
  233:              || ptr->ptr[idx] == '\t'))
  234:     idx++;
  235: 
  236:   if (idx < ptr->len
  237:       && ptr->ptr[idx] == ',')
  238:     idx++;
  239: 
  240:   while (idx < ptr->len
  241:          && (ptr->ptr[idx] == ' '
  242:              || ptr->ptr[idx] == '\t'))
  243:     idx++;
  244: 
  245:   return idx;
  246: }
Syntax (Markdown)