root/libutil/split.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. split
  2. recover
  3. split_dump
  4. parse_xid
  5. nextstring
  6. nextelement

   1 /*
   2  * Copyright (c) 2002, 2010 Tama Communications Corporation
   3  *
   4  * This file is part of GNU GLOBAL.
   5  *
   6  * This program is free software: you can redistribute it and/or modify
   7  * it under the terms of the GNU General Public License as published by
   8  * the Free Software Foundation, either version 3 of the License, or
   9  * (at your option) any later version.
  10  * 
  11  * This program is distributed in the hope that it will be useful,
  12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14  * GNU General Public License for more details.
  15  * 
  16  * You should have received a copy of the GNU General Public License
  17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18  */
  19 
  20 #ifdef HAVE_CONFIG_H
  21 #include <config.h>
  22 #endif
  23 #include <stdio.h>
  24 #include "split.h"
  25 #include "die.h"
  26 
  27 /** @file
  28  * Substring manager like @NAME{perl}'s @NAME{split}.
  29  *
  30  * @code
  31  * Initial status.
  32  *              +------------------------------------------------------
  33  *         line |main         100    ./main.c        main(argc, argv)\n
  34  * @endcode
  35  *
  36  * The result of @CODE{split(line, 4, &list)}:
  37  *
  38  * @code
  39  *              +------------------------------------------------------
  40  * list    line |main\0       100\0  ./main.c\0      main(argc, argv)\n
  41  * +---------+   ^   ^        ^  ^   ^       ^       ^
  42  * |npart=4  |   |   |        |  |   |       |       |
  43  * +---------+   |   |        |  |   |       |       |
  44  * | start  *----+   |        |  |   |       |       |
  45  * | end    *--------+        |  |   |       |       |
  46  * | save ' '|                |  |   |       |       |
  47  * +---------+                |  |   |       |       |
  48  * | start  *-----------------+  |   |       |       |
  49  * | end    *--------------------+   |       |       |
  50  * | save ' '|                       |       |       |
  51  * +---------+                       |       |       |
  52  * | start  *------------------------+       |       |
  53  * | end    *--------------------------------+       |
  54  * | save ' '|                                       |
  55  * +---------+                                       |
  56  * | start  *----------------------------------------+
  57  * | end    *--+
  58  * | save    | |
  59  * +---------+ =
  60  * @endcode
  61  *
  62  * The result of @CODE{split(line, 2, &list)}:
  63  *
  64  * @code
  65  *              +------------------------------------------------------
  66  * list    line |main\0       100    ./main.c        main(argc, argv)\n
  67  * +---------+   ^   ^        ^
  68  * |npart=2  |   |   |        |
  69  * +---------+   |   |        |
  70  * | start  *----+   |        |
  71  * | end    *--------+        |
  72  * | save ' '|                |
  73  * +---------+                |
  74  * | start  *-----------------+
  75  * | end    *--+
  76  * | save    | |
  77  * +---------+ =
  78  * @endcode
  79  *
  80  * The result of recover().
  81  * @code
  82  *              +------------------------------------------------------
  83  *         line |main         100    ./main.c        main(argc, argv)\n
  84  * @endcode
  85  *
  86  * Recover() recover initial status of line with saved char in @NAME{savec}.
  87  */
  88 
  89 #define isblank(c)      ((c) == ' ' || (c) == '\t')
  90 
  91 /**
  92  * split: split a string into pieces
  93  *
  94  *      @param[in]      line    string
  95  *      @param[in]      npart   parts number
  96  *      @param[in,out]  list    split table
  97  *      @return         part count
  98  */
  99 int
 100 split(const char *line, int npart, SPLIT *list)         /* virtually const */
 101 {
 102         char *s = (char *)line;
 103         struct part *part = &list->part[0];
 104         int count;
 105 
 106         if (npart > NPART)
 107                 npart = NPART;
 108         npart--;
 109         for (count = 0; *s && count < npart; count++) {
 110                 while (*s && isblank(*s))
 111                         s++;
 112                 if (*s == '\0')
 113                         break;
 114                 part->start = s;
 115                 while (*s && !isblank(*s))
 116                         s++;
 117                 part->end = s;
 118                 part->savec = *s;
 119                 part++;
 120         }
 121         if (*s) {
 122                 while (*s && isblank(*s))
 123                         s++;
 124                 part->start = s;
 125                 part->end = (char *)0;
 126                 part->savec = 0;
 127                 count++;
 128                 part++;
 129         }
 130         while (part-- > &list->part[0]) {
 131                 if (part->savec != '\0')
 132                         *part->end = '\0';
 133         }
 134         return list->npart = count;
 135 }
 136 /**
 137  * recover: recover initial status of line.
 138  *
 139  *      @param[in,out]  list    split table
 140  */
 141 void
 142 recover(SPLIT *list)
 143 {
 144         int i, c;
 145         for (i = 0; i < list->npart; i++) {
 146                 if ((c = list->part[i].savec) != '\0')
 147                         *(list->part[i].end) = c;
 148         }
 149 }
 150 /**
 151  * split_dump: dump split structure.
 152  */
 153 void
 154 split_dump(SPLIT *list)
 155 {
 156         int i;
 157         struct part *part;
 158 
 159         fprintf(stderr, "npart: %d\n", list->npart);
 160         
 161         for (i = 0; i < list->npart; i++) {
 162                 part = &list->part[i];
 163                 fprintf(stderr, "string[%d]: |%s|\n", i, part->start);
 164                 fprintf(stderr, "savec[%d] : |%c|\n", i, part->savec);
 165         }
 166 }
 167 /**
 168  * parse_xid: extract fid from @a ctags_xid format record.
 169  *
 170  *      @param[in]      ctags_xid       ctags-xid record
 171  *      @param[out]     s_fid           file id(string) if not @VAR{NULL}
 172  *      @param[out]     n_fid           file id(integer) if not @VAR{NULL}
 173  *      @return                 pointer to the @NAME{ctags_x} part
 174  */
 175 const char *
 176 parse_xid(const char *ctags_xid, char *s_fid, int *n_fid)
 177 {
 178         const char *p;
 179         int i, n;
 180 
 181         i = n = 0;
 182         for (p = ctags_xid; *p && *p >= '0' && *p <= '9'; p++) {
 183                 n = n * 10 + (*p - '0');
 184                 if (s_fid)
 185                         s_fid[i++] = *p;
 186         }
 187         if (*p++ != ' ')
 188                 die("illegal ctags-xid format record. '%s'", ctags_xid);
 189         if (s_fid)
 190                 s_fid[i] = '\0';
 191         if (n_fid != NULL)
 192                 *n_fid = n;
 193         return p;
 194 }
 195 /**
 196  * nextstring: seek to the next string.
 197  *
 198  *      @param[in]      s       original string
 199  *      @return              next string
 200  *
 201  * @code
 202  *  s       v
 203  * "aaaaaa\0bbbbb\0"
 204  * @endcode
 205  */
 206 const char *
 207 nextstring(const char *s)
 208 {
 209         while (*s)
 210                 s++;
 211         return s + 1;
 212 }
 213 /**
 214  * nextelement: seek to the next element
 215  *
 216  *      @param[in]      s       point the current element or the following blanks
 217  *      @return         next element
 218  *
 219  * @code{.txt}
 220  *      s     s   return value
 221  *      v     v   v
 222  *      xxxxx     yyyyy    zzzzzz
 223  *      (current) (next)
 224  * @endcode
 225  */
 226 const char *
 227 nextelement(const char *s)
 228 {
 229         while (*s && !isblank(*s))
 230                 s++;
 231         if (!*s)
 232                 die("nextelement: unexpected end of string(1).");
 233         while (*s && isblank(*s))
 234                 s++;
 235         if (!*s)
 236                 die("nextelement: unexpected end of string(2).");
 237         return s;
 238 }

/* [previous][next][first][last][top][bottom][index][help] */