root/libutil/linetable.c(151.html)

/* [<][>][^][v][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

/*
 * Copyright (c) 2002, 2004 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 #ifdef STDC_HEADERS #include <stdlib.h> #endif #ifdef HAVE_STRING_H #include <string.h> #else #include <strings.h> #endif #include <sys/stat.h> #include "die.h" #include "linetable.h" #include "varray.h" #include "strbuf.h" /* File buffer */
#define EXPAND 1024 static STRBUF *ib; static char *filebuf; static int filesize; /* File pointer */
static char *curp; static char *endp; /* Offset table */
static VARRAY *vb; static void linetable_put(int, int); /* * linetable_open: load whole of file into memory. * * i) path path * r) 0: normal * -1: cannot open file. */
int linetable_open(const char *path) { FILE *ip; struct stat sb; int lineno, offset; if (stat(path, &sb) < 0) return -1; ib = strbuf_open(sb.st_size); vb = varray_open(sizeof(int), EXPAND); if ((ip = fopen(path, "r")) == NULL) return -1; lineno = 1; offset = 0; for (offset = 0; (strbuf_fgets(ib, ip, STRBUF_APPEND), offset != strbuf_getlen(ib)); offset = strbuf_getlen(ib)) { linetable_put(offset, lineno++); } fclose(ip); curp = filebuf = strbuf_value(ib); filesize = offset; endp = filebuf + filesize; /* strbuf_close(ib); */
return 0; } /* * linetable_read: read(2) compatible routine for linetable. * * io) buf read buffer * i) size buffer size * r) ==-1: end of file * !=-1: number of bytes actually read */
int linetable_read(char *buf, int size) { int leaved = endp - curp; if (leaved <= 0) return -1; /* EOF */
if (size > leaved) size = leaved; memcpy(buf, curp, size); curp += size; return size; } /* * linetable_put: put a line into table. * * i) offset offset of the line * i) lineno line number of the line (>= 1) */
void linetable_put(int offset, int lineno) { int *entry; if (lineno <= 0) die("linetable_put: line number must >= 1 (lineno = %d)", lineno); entry = varray_assign(vb, lineno - 1, 1); *entry = offset; } /* * linetable_get: get a line from table. * * i) lineno line number of the line (>= 1) * o) offset offset of the line * if offset == NULL, nothing returned. * r) line pointer */
char * linetable_get(int lineno, int *offset) { int addr; if (lineno <= 0) die("linetable_get: line number must >= 1 (lineno = %d)", lineno); addr = *((int *)varray_assign(vb, lineno - 1, 0)); if (offset) *offset = addr; return filebuf + addr; } /* * linetable_close: close line table. */
void linetable_close(void) { varray_close(vb); strbuf_close(ib); } /* * linetable_print: print a line. * * i) op output file pointer * i) lineno line number (>= 1) */
void linetable_print(FILE *op, int lineno) { const char *s, *p; if (lineno <= 0) die("linetable_print: line number must >= 1 (lineno = %d)", lineno); s = linetable_get(lineno, NULL); if (vb->length == lineno) { /* * The last line may not include newline. */
fwrite(s, 1, endp - s, op); if (endp[-1] != '\n') fputc('\n', op); } else { p = linetable_get(lineno + 1, NULL); fwrite(s, 1, p - s, op); } }

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