1 /*!
2    \file lib/vector/Vlib/hist.c
3 
4    \brief Vector library - history manipulation
5 
6    Higher level functions for reading/writing/manipulating vectors.
7 
8    (C) 2001-2009 by the GRASS Development Team
9 
10    This program is free software under the GNU General Public License
11    (>=v2).  Read the file COPYING that comes with GRASS for details.
12 
13    \author Radim Blazek
14  */
15 
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <grass/vector.h>
20 
21 /*!
22    \brief Write command info to history file
23 
24    \param Map pointer to Map_info structure
25 
26    \return 0 on success
27    \return -1 error
28  */
Vect_hist_command(struct Map_info * Map)29 int Vect_hist_command(struct Map_info *Map)
30 {
31     char *cmd, buf[GPATH_MAX];
32 
33     G_debug(3, "Vect_hist_command()");
34 
35     cmd = G_recreate_command();
36 
37     if (0 > Vect_hist_write(Map, "COMMAND: "))
38         return -1;
39     if (0 > Vect_hist_write(Map, cmd))
40         return -1;
41     if (0 > Vect_hist_write(Map, "\n"))
42         return -1;
43 
44     sprintf(buf, "GISDBASE: %s\n", G_gisdbase());	/* Needed ? */
45     if (0 > Vect_hist_write(Map, buf))
46         return -1;
47 
48     sprintf(buf, "LOCATION: %s MAPSET: %s USER: %s DATE: %s\n",
49 	    G_location(), G_mapset(), G_whoami(), G_date());	/* Needed ? */
50     if (0 > Vect_hist_write(Map, buf))
51         return -1;
52 
53     return 0;
54 }
55 
56 /*!
57    \brief Write string to history file
58 
59    \param Map pointer to Map_info structure
60    \param str string to write
61 
62    \return the number of characters printed
63    \return -1 on error
64  */
Vect_hist_write(struct Map_info * Map,const char * str)65 int Vect_hist_write(struct Map_info *Map, const char *str)
66 {
67     int ret;
68 
69     G_debug(5, "Vect_hist_write(): %s", str);
70     ret = 0;
71     if (Map->hist_fp) {
72 	ret = fprintf(Map->hist_fp, "%s", str);
73 	fflush(Map->hist_fp);
74     }
75 
76     return ret;
77 }
78 
79 /*!
80    \brief Reads one line from history file without newline character
81 
82    \param[out] s buffer, allocated space must be size+1
83    \param size maximum number of character
84    \param Map vector map
85 
86    \return return s on success
87    \return NULL on error
88    \return EOF end of file
89  */
Vect_hist_read(char * s,int size,const struct Map_info * Map)90 char *Vect_hist_read(char *s, int size, const struct Map_info *Map)
91 {
92     int ret;
93 
94     G_debug(5, "Vect_hist_read()");
95 
96     if (Map->hist_fp == NULL)
97 	return NULL;		/* OK for shapefile etc. */
98 
99     ret = G_getl2(s, size, Map->hist_fp);
100 
101     if (ret == 1)
102 	return s;
103 
104     return NULL;
105 }
106 
107 /*!
108    \brief Rewind history file
109 
110    \param Map vector map
111 
112    \return void
113  */
Vect_hist_rewind(struct Map_info * Map)114 void Vect_hist_rewind(struct Map_info *Map)
115 {
116     G_debug(3, "Vect_hist_rewind()");
117 
118     if (Map->hist_fp != NULL)
119 	rewind(Map->hist_fp);
120 }
121 
122 /*!
123    \brief Copy history from one map to another
124 
125    \param In input vector map
126    \param[out] Out output vector map
127 
128    \return 0 on success
129    \return -1 on error
130  */
Vect_hist_copy(const struct Map_info * In,struct Map_info * Out)131 int Vect_hist_copy(const struct Map_info *In, struct Map_info *Out)
132 {
133     size_t red, ret;
134     char buf[1000];
135 
136     G_debug(3, "Vect_hist_copy()");
137 
138     if (In->hist_fp == NULL)
139 	return 0;		/* This is correct (old hist doesn't exist) */
140     if (Out->hist_fp == NULL)
141 	return -1;
142 
143     /* skip empty old hist */
144     G_fseek(In->hist_fp, (long)0, SEEK_END);
145     if (G_ftell(In->hist_fp) == 0)
146 	return 0;
147 
148     G_fseek(Out->hist_fp, (long)0, SEEK_END);
149     rewind(In->hist_fp);
150 
151     while ((red = fread(buf, sizeof(char), sizeof(char) * 1000, In->hist_fp))) {
152 	if (!(ret = fwrite(buf, sizeof(char), red, Out->hist_fp))) {
153 	    return (-1);
154 	}
155 	fflush(Out->hist_fp);
156     }
157 
158     /* In ends with \n ? */
159     G_fseek(In->hist_fp, (long)-1, SEEK_END);
160     if (fread(buf, sizeof(char), sizeof(char), In->hist_fp) != 1) {
161 	return -1;
162     }
163 
164     if (buf[0] != '\n') {
165 	Vect_hist_write(Out, "\n");
166     }
167 
168     /* Separator */
169     Vect_hist_write(Out,
170 		    "---------------------------------------------------------------------------------\n");
171     return (0);
172 }
173