## root/libutil/split.c

/* [<][>][^][v][top][bottom][index][help] */

## DEFINITIONS

This source file includes following definitions.

1. split
2. recover
3. split_dump

    /*
     * Copyright (c) 2002 Tama Communications Corporation
     *
     * This file is part of GNU GLOBAL.
     *
     * This program is free software: you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation, either version 3 of the License, or
     * (at your option) any later version.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License
     * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     */

    #ifdef HAVE_CONFIG_H
    #include <config.h>
    #endif
    #include <stdio.h>
    #include "split.h"

    /*
     * Substring manager like perl's split.
     *
     * Initial status.
     *              +------------------------------------------------------
     *         line |main         100    ./main.c        main(argc, argv)\n
     *
     * The result of split(line, 4, &list):
     *
     *              +------------------------------------------------------
     * list    line |main\0       100\0  ./main.c\0      main(argc, argv)\n
     * +---------+   ^   ^        ^  ^   ^       ^       ^
     * |npart=4  |   |   |        |  |   |       |       |
     * +---------+   |   |        |  |   |       |       |
     * | start  *----+   |        |  |   |       |       |
     * | end    *--------+        |  |   |       |       |
     * | save ' '|                |  |   |       |       |
     * +---------+                |  |   |       |       |
     * | start  *-----------------+  |   |       |       |
     * | end    *--------------------+   |       |       |
     * | save ' '|                       |       |       |
     * +---------+                       |       |       |
     * | start  *------------------------+       |       |
     * | end    *--------------------------------+       |
     * | save ' '|                                       |
     * +---------+                                       |
     * | start  *----------------------------------------+
     * | end    *--+
     * | save    | |
     * +---------+ =
     *
     * The result of split(line, 2, &list):
     *
     *              +------------------------------------------------------
     * list    line |main\0       100    ./main.c        main(argc, argv)\n
     * +---------+   ^   ^        ^
     * |npart=2  |   |   |        |
     * +---------+   |   |        |
     * | start  *----+   |        |
     * | end    *--------+        |
     * | save ' '|                |
     * +---------+                |
     * | start  *-----------------+
     * | end    *--+
     * | save    | |
     * +---------+ =
     *
     * The result of recover().
     *              +------------------------------------------------------
     *         line |main         100    ./main.c        main(argc, argv)\n
     *
     * Recover() recover initial status of line with saved char in savec.
     */

    #define isblank(c)      ((c) == ' ' || (c) == '\t')

    /*
     * split: split a string into pieces
     *
     *      i)      line    string
     *      i)      npart   parts number
     *      io)     list    split table
     *      r)              part count
     */
    int
    split(char *line, int npart, SPLIT *list)
    {
            char *s = line;
            struct part *part = &list->part[0];
            int count;

            if (npart > NPART)
                    npart = NPART;
            npart--;
            for (count = 0; *s && count < npart; count++) {
                    while (*s && isblank(*s))
                            s++;
                    if (*s == '\0')
                            break;
                    part->start = s;
                    while (*s && !isblank(*s))
                            s++;
                    part->end = s;
                    part->savec = *s;
                    part++;
            }
            if (*s) {
                    while (*s && isblank(*s))
                            s++;
                    part->start = s;
                    part->end = (char *)0;
                    part->savec = 0;
                    count++;
                    part++;
            }
            while (part-- > &list->part[0]) {
                    if (part->savec != '\0')
                            *part->end = '\0';
            }
            return list->npart = count;
    }
    /*
     * recover: recover initial status of line.
     *
     *      io)     list    split table
     */
    void
    recover(SPLIT *list)
    {
            int i, c;
            for (i = 0; i < list->npart; i++) {
                    if ((c = list->part[i].savec) != '\0')
                            *(list->part[i].end) = c;
            }
    }
    /*
     * split_dump: dump split structure.
     */
    void
    split_dump(SPLIT *list)
    {
            int i;
            struct part *part;

            fprintf(stderr, "npart: %d\n", list->npart);

            for (i = 0; i < list->npart; i++) {
                    part = &list->part[i];
                    fprintf(stderr, "string[%d]: |%s|\n", i, part->start);
                    fprintf(stderr, "savec[%d] : |%c|\n", i, part->savec);
            }
    }

/* [<][>][^][v][top][bottom][index][help] */