X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flibpspp%2Fpool.c;h=7a8a591da58a7e84ebaf6952f784cec17f7571d0;hb=ecef385b0191afa4c27927146ac1f6c5a1852119;hp=01bd8f91114252c1ca04723de7aaed78a38c42e5;hpb=f5c108becd49d78f4898cab11352291f5689d24e;p=pspp diff --git a/src/libpspp/pool.c b/src/libpspp/pool.c index 01bd8f9111..7a8a591da5 100644 --- a/src/libpspp/pool.c +++ b/src/libpspp/pool.c @@ -1,29 +1,32 @@ -/* PSPP - computes sample statistics. - Copyright (C) 2000 Free Software Foundation, Inc. +/* PSPP - a program for statistical analysis. + Copyright (C) 2000, 2010 Free Software Foundation, Inc. - 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 2 of the - License, or (at your option) any later version. + 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. + 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, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. */ + along with this program. If not, see . */ #include -#include "pool.h" + +#include "libpspp/pool.h" + +#include #include -#include "alloc.h" -#include -#include "message.h" -#include "size_max.h" -#include "str.h" + +#include "libpspp/assertion.h" +#include "libpspp/message.h" +#include "libpspp/temp-file.h" +#include "libpspp/str.h" + +#include "gl/xalloc.h" /* Fast, low-overhead memory block suballocator. */ struct pool @@ -46,6 +49,7 @@ enum { POOL_GIZMO_MALLOC, POOL_GIZMO_FILE, + POOL_GIZMO_TEMP_FILE, POOL_GIZMO_SUBPOOL, POOL_GIZMO_REGISTERED, }; @@ -65,7 +69,7 @@ struct pool_gizmo /* Type-dependent info. */ union { - FILE *file; /* POOL_GIZMO_FILE. */ + FILE *file; /* POOL_GIZMO_FILE, POOL_GIZMO_TEMP_FILE. */ struct pool *subpool; /* POOL_GIZMO_SUBPOOL. */ /* POOL_GIZMO_REGISTERED. */ @@ -365,6 +369,19 @@ pool_strdup (struct pool *pool, const char *string) return pool_clone_unaligned (pool, string, strlen (string) + 1); } +/* Duplicates the SIZE bytes of STRING, plus a trailing 0 byte, + and returns a pointer to the duplicate. For use only with + strings, because the returned pointere may not be aligned + properly for other types. */ +char * +pool_strdup0 (struct pool *pool, const char *string, size_t size) +{ + char *new_string = pool_alloc_unaligned (pool, size + 1); + memcpy (new_string, string, size); + new_string[size] = '\0'; + return new_string; +} + /* Formats FORMAT with the given ARGS in memory allocated from POOL and returns the formatted string. */ char * @@ -743,41 +760,78 @@ pool_fclose (struct pool *pool, FILE *file) return fclose (file); } -/* Creates a temporary file with tmpfile() and returns a handle to it - if successful or a null pointer if not. +/* Attaches FILE to POOL. The file will be closed automatically when POOL is destroyed, or it may be closed explicitly in advance using pool_fclose(), or detached from the pool with pool_detach_file(). */ +void +pool_attach_file (struct pool *pool, FILE *file) +{ + struct pool_gizmo *g = pool_alloc (pool, sizeof *g); + g->type = POOL_GIZMO_FILE; + g->p.file = file; + add_gizmo (pool, g); +} + +/* Detaches FILE from POOL. */ +void +pool_detach_file (struct pool *pool, FILE *file) +{ + struct pool_gizmo *g; + + for (g = pool->gizmos; g; g = g->next) + if (g->type == POOL_GIZMO_FILE && g->p.file == file) + { + delete_gizmo (pool, g); + return; + } +} + +/* Creates a temporary file with create_temp_file() and returns a handle to it + if successful or a null pointer if not. + The file will be closed automatically when POOL is destroyed, or it + may be closed explicitly in advance using pool_fclose_temp_file(), or + detached from the pool with pool_detach_temp_file(). */ FILE * -pool_tmpfile (struct pool *pool) +pool_create_temp_file (struct pool *pool) { - FILE *file = tmpfile (); + FILE *file = create_temp_file (); if (file != NULL) - pool_attach_file (pool, file); + pool_attach_temp_file (pool, file); return file; } -/* Attaches FILE to POOL. +/* Closes file FILE managed by POOL. + FILE must have been opened with create_temp_file(). */ +void +pool_fclose_temp_file (struct pool *pool, FILE *file) +{ + assert (pool && file); + pool_detach_temp_file (pool, file); + close_temp_file (file); +} + +/* Attaches FILE, which must have been opened with create_temp_file(), to POOL. The file will be closed automatically when POOL is destroyed, or it - may be closed explicitly in advance using pool_fclose(), or - detached from the pool with pool_detach_file(). */ + may be closed explicitly in advance using pool_fclose_temp_file(), or + detached from the pool with pool_detach_temp_file(). */ void -pool_attach_file (struct pool *pool, FILE *file) +pool_attach_temp_file (struct pool *pool, FILE *file) { struct pool_gizmo *g = pool_alloc (pool, sizeof *g); - g->type = POOL_GIZMO_FILE; + g->type = POOL_GIZMO_TEMP_FILE; g->p.file = file; add_gizmo (pool, g); } -/* Detaches FILE from POOL. */ +/* Detaches FILE that was opened with create_temp_file() from POOL. */ void -pool_detach_file (struct pool *pool, FILE *file) +pool_detach_temp_file (struct pool *pool, FILE *file) { struct pool_gizmo *g; for (g = pool->gizmos; g; g = g->next) - if (g->type == POOL_GIZMO_FILE && g->p.file == file) + if (g->type == POOL_GIZMO_TEMP_FILE && g->p.file == file) { delete_gizmo (pool, g); return; @@ -935,6 +989,9 @@ free_gizmo (struct pool_gizmo *gizmo) case POOL_GIZMO_FILE: fclose (gizmo->p.file); /* Ignore errors. */ break; + case POOL_GIZMO_TEMP_FILE: + close_temp_file (gizmo->p.file); /* Ignore errors. */ + break; case POOL_GIZMO_SUBPOOL: gizmo->p.subpool->parent = NULL; pool_destroy (gizmo->p.subpool);