1 /******************************************************************************
2 * $Id: dbfdump.c,v 1.14 2016-12-05 12:44:05 erouault Exp $
3 *
4 * Project: Shapelib
5 * Purpose: Sample application for dumping .dbf files to the terminal.
6 * Author: Frank Warmerdam, warmerdam@pobox.com
7 *
8 ******************************************************************************
9 * Copyright (c) 1999, Frank Warmerdam
10 *
11 * This software is available under the following "MIT Style" license,
12 * or at the option of the licensee under the LGPL (see COPYING). This
13 * option is discussed in more detail in shapelib.html.
14 *
15 * --
16 *
17 * Permission is hereby granted, free of charge, to any person obtaining a
18 * copy of this software and associated documentation files (the "Software"),
19 * to deal in the Software without restriction, including without limitation
20 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
21 * and/or sell copies of the Software, and to permit persons to whom the
22 * Software is furnished to do so, subject to the following conditions:
23 *
24 * The above copyright notice and this permission notice shall be included
25 * in all copies or substantial portions of the Software.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
28 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
32 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33 * DEALINGS IN THE SOFTWARE.
34 ******************************************************************************
35 *
36 * $Log: dbfdump.c,v $
37 * Revision 1.14 2016-12-05 12:44:05 erouault
38 * * Major overhaul of Makefile build system to use autoconf/automake.
39 *
40 * * Warning fixes in contrib/
41 *
42 * Revision 1.13 2013-11-26 21:52:33 fwarmerdam
43 * report deleted rows in dbfdump
44 *
45 * Revision 1.12 2006-06-17 00:15:08 fwarmerdam
46 * Free panWidth for better memory testing.
47 *
48 * Revision 1.11 2006/02/15 01:11:27 fwarmerdam
49 * added reporting of native type
50 *
51 * Revision 1.10 2004/09/26 20:09:35 fwarmerdam
52 * avoid rcsid warnings
53 *
54 * Revision 1.9 2002/01/15 14:36:07 warmerda
55 * updated email address
56 *
57 * Revision 1.8 2001/05/31 18:15:40 warmerda
58 * Added support for NULL fields in DBF files
59 *
60 * Revision 1.7 2000/09/20 13:13:55 warmerda
61 * added break after default:
62 *
63 * Revision 1.6 2000/07/07 13:39:45 warmerda
64 * removed unused variables, and added system include files
65 *
66 * Revision 1.5 1999/11/05 14:12:04 warmerda
67 * updated license terms
68 *
69 * Revision 1.4 1998/12/31 15:30:13 warmerda
70 * Added -m, -r, and -h commandline options.
71 *
72 * Revision 1.3 1995/10/21 03:15:01 warmerda
73 * Changed to use binary file access.
74 *
75 * Revision 1.2 1995/08/04 03:16:22 warmerda
76 * Added header.
77 *
78 */
79
80 #include <stdlib.h>
81 #include <string.h>
82 #include "shapefil.h"
83
84 SHP_CVSID("$Id: dbfdump.c,v 1.14 2016-12-05 12:44:05 erouault Exp $")
85
main(int argc,char ** argv)86 int main( int argc, char ** argv )
87
88 {
89 DBFHandle hDBF;
90 int *panWidth, i, iRecord;
91 char szFormat[32], *pszFilename = NULL;
92 int nWidth, nDecimals;
93 int bHeader = 0;
94 int bRaw = 0;
95 int bMultiLine = 0;
96 char szTitle[12];
97
98 /* -------------------------------------------------------------------- */
99 /* Handle arguments. */
100 /* -------------------------------------------------------------------- */
101 for( i = 1; i < argc; i++ )
102 {
103 if( strcmp(argv[i],"-h") == 0 )
104 bHeader = 1;
105 else if( strcmp(argv[i],"-r") == 0 )
106 bRaw = 1;
107 else if( strcmp(argv[i],"-m") == 0 )
108 bMultiLine = 1;
109 else
110 pszFilename = argv[i];
111 }
112
113 /* -------------------------------------------------------------------- */
114 /* Display a usage message. */
115 /* -------------------------------------------------------------------- */
116 if( pszFilename == NULL )
117 {
118 printf( "dbfdump [-h] [-r] [-m] xbase_file\n" );
119 printf( " -h: Write header info (field descriptions)\n" );
120 printf( " -r: Write raw field info, numeric values not reformatted\n" );
121 printf( " -m: Multiline, one line per field.\n" );
122 exit( 1 );
123 }
124
125 /* -------------------------------------------------------------------- */
126 /* Open the file. */
127 /* -------------------------------------------------------------------- */
128 hDBF = DBFOpen( pszFilename, "rb" );
129 if( hDBF == NULL )
130 {
131 printf( "DBFOpen(%s,\"r\") failed.\n", argv[1] );
132 exit( 2 );
133 }
134
135 /* -------------------------------------------------------------------- */
136 /* If there is no data in this file let the user know. */
137 /* -------------------------------------------------------------------- */
138 if( DBFGetFieldCount(hDBF) == 0 )
139 {
140 printf( "There are no fields in this table!\n" );
141 exit( 3 );
142 }
143
144 /* -------------------------------------------------------------------- */
145 /* Dump header definitions. */
146 /* -------------------------------------------------------------------- */
147 if( bHeader )
148 {
149 for( i = 0; i < DBFGetFieldCount(hDBF); i++ )
150 {
151 DBFFieldType eType;
152 const char *pszTypeName;
153 char chNativeType;
154
155 chNativeType = DBFGetNativeFieldType( hDBF, i );
156
157 eType = DBFGetFieldInfo( hDBF, i, szTitle, &nWidth, &nDecimals );
158 if( eType == FTString )
159 pszTypeName = "String";
160 else if( eType == FTInteger )
161 pszTypeName = "Integer";
162 else if( eType == FTDouble )
163 pszTypeName = "Double";
164 else if( eType == FTInvalid )
165 pszTypeName = "Invalid";
166
167 printf( "Field %d: Type=%c/%s, Title=`%s', Width=%d, Decimals=%d\n",
168 i, chNativeType, pszTypeName, szTitle, nWidth, nDecimals );
169 }
170 }
171
172 /* -------------------------------------------------------------------- */
173 /* Compute offsets to use when printing each of the field */
174 /* values. We make each field as wide as the field title+1, or */
175 /* the field value + 1. */
176 /* -------------------------------------------------------------------- */
177 panWidth = (int *) malloc( DBFGetFieldCount( hDBF ) * sizeof(int) );
178
179 for( i = 0; i < DBFGetFieldCount(hDBF) && !bMultiLine; i++ )
180 {
181 DBFFieldType eType;
182
183 eType = DBFGetFieldInfo( hDBF, i, szTitle, &nWidth, &nDecimals );
184 if( (int) strlen(szTitle) > nWidth )
185 panWidth[i] = strlen(szTitle);
186 else
187 panWidth[i] = nWidth;
188
189 if( eType == FTString )
190 sprintf( szFormat, "%%-%ds ", panWidth[i] );
191 else
192 sprintf( szFormat, "%%%ds ", panWidth[i] );
193 printf( szFormat, szTitle );
194 }
195 printf( "\n" );
196
197 /* -------------------------------------------------------------------- */
198 /* Read all the records */
199 /* -------------------------------------------------------------------- */
200 for( iRecord = 0; iRecord < DBFGetRecordCount(hDBF); iRecord++ )
201 {
202 if( bMultiLine )
203 printf( "Record: %d\n", iRecord );
204
205 for( i = 0; i < DBFGetFieldCount(hDBF); i++ )
206 {
207 DBFFieldType eType;
208
209 eType = DBFGetFieldInfo( hDBF, i, szTitle, &nWidth, &nDecimals );
210
211 if( bMultiLine )
212 {
213 printf( "%s: ", szTitle );
214 }
215
216 /* -------------------------------------------------------------------- */
217 /* Print the record according to the type and formatting */
218 /* information implicit in the DBF field description. */
219 /* -------------------------------------------------------------------- */
220 if( !bRaw )
221 {
222 if( DBFIsAttributeNULL( hDBF, iRecord, i ) )
223 {
224 if( eType == FTString )
225 sprintf( szFormat, "%%-%ds", nWidth );
226 else
227 sprintf( szFormat, "%%%ds", nWidth );
228
229 printf( szFormat, "(NULL)" );
230 }
231 else
232 {
233 switch( eType )
234 {
235 case FTString:
236 sprintf( szFormat, "%%-%ds", nWidth );
237 printf( szFormat,
238 DBFReadStringAttribute( hDBF, iRecord, i ) );
239 break;
240
241 case FTInteger:
242 sprintf( szFormat, "%%%dd", nWidth );
243 printf( szFormat,
244 DBFReadIntegerAttribute( hDBF, iRecord, i ) );
245 break;
246
247 case FTDouble:
248 sprintf( szFormat, "%%%d.%dlf", nWidth, nDecimals );
249 printf( szFormat,
250 DBFReadDoubleAttribute( hDBF, iRecord, i ) );
251 break;
252
253 default:
254 break;
255 }
256 }
257 }
258
259 /* -------------------------------------------------------------------- */
260 /* Just dump in raw form (as formatted in the file). */
261 /* -------------------------------------------------------------------- */
262 else
263 {
264 sprintf( szFormat, "%%-%ds", nWidth );
265 printf( szFormat,
266 DBFReadStringAttribute( hDBF, iRecord, i ) );
267 }
268
269 /* -------------------------------------------------------------------- */
270 /* Write out any extra spaces required to pad out the field */
271 /* width. */
272 /* -------------------------------------------------------------------- */
273 if( !bMultiLine )
274 {
275 sprintf( szFormat, "%%%ds", panWidth[i] - nWidth + 1 );
276 printf( szFormat, "" );
277 }
278
279 if( bMultiLine )
280 printf( "\n" );
281
282 fflush( stdout );
283 }
284
285 if( DBFIsRecordDeleted(hDBF, iRecord) )
286 printf( "(DELETED)" );
287
288 printf( "\n" );
289 }
290
291 DBFClose( hDBF );
292 free( panWidth );
293
294 return( 0 );
295 }
296