root/libutil/linetable.c

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

DEFINITIONS

This source file includes following definitions.
  1. linetable_open
  2. linetable_read
  3. linetable_put
  4. linetable_get
  5. linetable_close
  6. linetable_print

   1 /*
   2  * Copyright (c) 2002, 2004 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 #ifdef STDC_HEADERS
  24 #include <stdlib.h>
  25 #endif
  26 #ifdef HAVE_STRING_H
  27 #include <string.h>
  28 #else
  29 #include <strings.h>
  30 #endif
  31 #include <sys/stat.h>
  32 
  33 #include "die.h"
  34 #include "linetable.h"
  35 #include "varray.h"
  36 #include "strbuf.h"
  37 
  38 /** @name File buffer */
  39 /** @{ */
  40 #define EXPAND 1024
  41 static STRBUF *ib;
  42 static char *filebuf;
  43 static int filesize;
  44 /** @} */
  45 
  46 /** @name File pointer */
  47 /** @{ */
  48 static char *curp;
  49 static char *endp;
  50 /** @} */
  51 
  52 /** Offset table */
  53 static VARRAY *vb;
  54 
  55 static void linetable_put(int, int);
  56 /**
  57  * linetable_open: load whole of file into memory.
  58  *
  59  *      @param[in]      path    path
  60  *      @return         0: normal <br>
  61  *                      -1: cannot open file.
  62  */
  63 int
  64 linetable_open(const char *path)
  65 {
  66         FILE *ip;
  67         struct stat sb;
  68         int lineno, offset;
  69 
  70         if (stat(path, &sb) < 0)
  71                 return -1;
  72         ib = strbuf_open(sb.st_size);
  73         vb = varray_open(sizeof(int), EXPAND);
  74         if ((ip = fopen(path, "r")) == NULL)
  75                 return -1;
  76         lineno = 1;
  77         offset = 0;
  78         for (offset = 0;
  79                 (strbuf_fgets(ib, ip, STRBUF_APPEND), offset != strbuf_getlen(ib));
  80                 offset = strbuf_getlen(ib))
  81         {
  82                 linetable_put(offset, lineno++);
  83         }
  84         fclose(ip);
  85         curp = filebuf = strbuf_value(ib);
  86         filesize = offset;
  87         endp = filebuf + filesize;
  88         /* strbuf_close(ib); */
  89 
  90         return 0;
  91 }
  92 /**
  93  * linetable_read: @XREF{read,2} compatible routine for linetable.
  94  *
  95  *      @param[in,out]  buf     read buffer
  96  *      @param[in]      size    buffer size
  97  *      @return         ==-1: end of file <br>
  98  *                      !=-1: number of bytes actually read
  99  */
 100 int
 101 linetable_read(char *buf, int size)
 102 {
 103         int leaved = endp - curp;
 104 
 105         if (leaved <= 0)
 106                 return -1;      /* EOF */
 107         if (size > leaved)
 108                 size = leaved;
 109         memcpy(buf, curp, size);
 110         curp += size;
 111 
 112         return size;
 113 }
 114 /**
 115  * linetable_put: put a line into table.
 116  *
 117  *      @param[in]      offset  offset of the line
 118  *      @param[in]      lineno  line number of the line (\>= 1)
 119  */
 120 void
 121 linetable_put(int offset, int lineno)
 122 {
 123         int *entry;
 124 
 125         if (lineno <= 0)
 126                 die("linetable_put: line number must >= 1 (lineno = %d)", lineno);
 127         entry = varray_assign(vb, lineno - 1, 1);
 128         *entry = offset;
 129 }
 130 /**
 131  * linetable_get: get a line from table.
 132  *
 133  *      @param[in]      lineno  line number of the line (\>= 1)
 134  *      @param[out]     offset  offset of the line <br>
 135  *                      if @CODE{offset == NULL}, nothing returned.
 136  *      @return         line pointer
 137  */
 138 char *
 139 linetable_get(int lineno, int *offset)
 140 {
 141         int addr;
 142 
 143         if (lineno <= 0)
 144                 die("linetable_get: line number must >= 1 (lineno = %d)", lineno);
 145         addr = *((int *)varray_assign(vb, lineno - 1, 0));
 146         if (offset)
 147                 *offset = addr;
 148         return filebuf + addr;
 149 }
 150 /**
 151  * linetable_close: close line table.
 152  */
 153 void
 154 linetable_close(void)
 155 {
 156         varray_close(vb);
 157         strbuf_close(ib);
 158 }
 159 /**
 160  * linetable_print: print a line.
 161  *
 162  *      @param[in]      op      output file pointer
 163  *      @param[in]      lineno  line number (\>= 1)
 164  */
 165 void
 166 linetable_print(FILE *op, int lineno)
 167 {
 168         const char *s, *p;
 169 
 170         if (lineno <= 0)
 171                 die("linetable_print: line number must >= 1 (lineno = %d)", lineno);
 172         s = linetable_get(lineno, NULL);
 173         if (vb->length == lineno) {
 174                 /*
 175                  * The last line may not include newline.
 176                  */
 177                 fwrite(s, 1, endp - s, op);
 178                 if (endp[-1] != '\n')
 179                         fputc('\n', op);
 180         } else {
 181                 p = linetable_get(lineno + 1, NULL);
 182                 fwrite(s, 1, p - s, op);
 183         }
 184 }

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