1 /*--------------------------------------------------------------------
2 *
3 * Copyright (c) 1991-2021 by the GMT Team (https://www.generic-mapping-tools.org/team.html)
4 * See LICENSE.TXT file for copying and redistribution conditions.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; version 3 or any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * Contact info: www.generic-mapping-tools.org
16 *--------------------------------------------------------------------*/
17 /*
18 * Demonstrate how to use the table i/o machinery on a record-by-record
19 * basis, including the various checks for gaps, headers, etc.
20 *
21 * Version: 5
22 * Created: 19-Mar-2010
23 *
24 */
25
26 #include "gmt_dev.h"
27
28 #define THIS_MODULE_OPTIONS "->Vghi"
29
main(int argc,char * argv[])30 int main (int argc, char *argv[]) {
31 int n_fields = 0, mode = 0, error = 0;
32 struct GMT_RECORD *In = NULL;
33 struct GMT_OPTION *options = NULL; /* Linked list of options */
34 struct GMTAPI_CTRL *API = NULL; /* GMT API control structure */
35 struct GMT_CTRL *GMT = NULL;
36
37 /* 1. Initializing new GMT session */
38 if ((API = GMT_Create_Session ("TEST", GMT_PAD_DEFAULT, GMT_SESSION_NORMAL, NULL)) == NULL) exit (EXIT_FAILURE);
39 GMT = API->GMT;
40
41 /* 2. Convert command line arguments to local linked option list */
42 if ((options = GMT_Create_Options (API, argc-1, (argv+1))) == NULL) exit (EXIT_FAILURE);
43
44 /* 3. Parse the common GMT options (e.g., -h -V) */
45 if (GMT_Parse_Common (API, THIS_MODULE_OPTIONS, options)) exit (EXIT_FAILURE);
46
47 /* 4. Initializing data input via stdin */
48
49 if ((error = GMT_Set_Columns (API, GMT_IN, 0, GMT_COL_FIX)) != GMT_NOERROR) exit (EXIT_FAILURE);
50 if (GMT_Init_IO (API, GMT_IS_DATASET, GMT_IS_POINT, GMT_IN, GMT_ADD_DEFAULT, 0, options) != GMT_NOERROR) exit (EXIT_FAILURE); /* Establishes data input */
51 if (GMT_Init_IO (API, GMT_IS_DATASET, GMT_IS_POINT, GMT_OUT, GMT_ADD_DEFAULT, 0, options) != GMT_NOERROR) exit (EXIT_FAILURE); /* Establishes data output */
52
53 /* 5. Read individual records until end of data set */
54 /* The GMT_READ_FILEBREAK in GMT_Get_Record means we will return a special EOF marker at the end of each
55 * data table when there are more tables to process. The end of the last file yields the actual EOF.
56 * This lets us do special processing after a file has been fully read. */
57
58 /* Initialize the i/o for doing record-by-record reading/writing */
59 if ((error = GMT_Begin_IO (API, GMT_IS_DATASET, GMT_IN, GMT_HEADER_ON)) != GMT_NOERROR) exit (error); /* Enables data input and sets access mode */
60 if ((error = GMT_Begin_IO (API, GMT_IS_DATASET, GMT_OUT, GMT_HEADER_ON)) != GMT_NOERROR) exit (error); /* Enables data output and sets access mode */
61
62 do { /* Keep returning records until we reach EOF */
63 mode = GMT_WRITE_DATA; /* Normally we treat data as double precision values */
64 if ((In = GMT_Get_Record (API, GMT_READ_DATA | GMT_READ_FILEBREAK, &n_fields)) == NULL) { /* Read next record, get NULL if special case */
65 if (gmt_M_rec_is_error (GMT)) { /* This check kicks in if the data has bad formatting, text etc */
66 GMT_Report (API, GMT_MSG_WARNING, "Error found in record %" PRIu64 "\n", GMT->current.io.rec_no);
67 API->print_func (stdout, "E: ");
68 mode = GMT_WRITE_TEXT; /* Switch to text so we can see the bad record as is */
69 }
70 if (gmt_M_rec_is_file_break (GMT)) { /* End of a file but not end of all files */
71 GMT_Report (API, GMT_MSG_WARNING, "End of intermediate data file after record %" PRIu64 "\n", GMT->current.io.rec_no);
72 API->print_func (stdout, "B: --- End of File except last one ---\n");
73 continue; /* Since no actual data record was returned, just the intermediate "EOF" signal */
74 }
75 if (gmt_M_rec_is_table_header (GMT)) { /* Found a table header */
76 GMT_Report (API, GMT_MSG_WARNING, "Table header found in record %" PRIu64 "\n", GMT->current.io.rec_no);
77 API->print_func (stdout, "H: ");
78 mode = GMT_WRITE_TABLE_HEADER; /* Special flag to report the table header */
79 }
80 if (gmt_M_rec_is_segment_header (GMT)) { /* Found segment header */
81 GMT_Report (API, GMT_MSG_WARNING, "Segment header found in record %" PRIu64 "\n", GMT->current.io.rec_no);
82 API->print_func (stdout, "S: ");
83 mode = GMT_WRITE_SEGMENT_HEADER; /* Special flag to report the segment header */
84 }
85 if (gmt_M_rec_is_nan (GMT)) { /* Found NaN record */
86 GMT_Report (API, GMT_MSG_WARNING, "NaN data found in record %" PRIu64 "\n", GMT->current.io.rec_no);
87 API->print_func (stdout, "N: ");
88 mode = GMT_WRITE_TEXT; /* Switch to text so we can see the nan record as is */
89 }
90 if (gmt_M_rec_is_gap (GMT)) { /* Found a gap */
91 GMT_Report (API, GMT_MSG_WARNING, "A gap found in record %" PRIu64 "\n", GMT->current.io.rec_no);
92 API->print_func (stdout, "G: ");
93 }
94 assert (false); /* Should never get here */
95 }
96 if (gmt_M_rec_is_data (GMT)) { /* Found a data record */
97 if ((error = GMT_Set_Columns (API, GMT_OUT, n_fields, gmt_M_colmode (In->text))) != GMT_NOERROR) exit (EXIT_FAILURE);
98 GMT_Report (API, GMT_MSG_WARNING, "Data found in record %" PRIu64 "\n", GMT->current.io.rec_no);
99 API->print_func (stdout, "D: ");
100 }
101 GMT_Put_Record (API, mode, In);
102 } while (true);
103
104 API->print_func (stdout, "B: --- End of All Files ---\n");
105 if ((error = GMT_End_IO (API, GMT_IN, 0)) != GMT_NOERROR) exit (error); /* Disables further data input */
106 if ((error = GMT_End_IO (API, GMT_OUT, 0)) != GMT_NOERROR) exit (error); /* Disables further data output */
107
108 /* 5. Destroy local linked option list */
109 if (GMT_Destroy_Options (API, &options)) exit (EXIT_FAILURE);
110
111 /* 6. Destroy GMT session */
112 if (GMT_Destroy_Session (API)) exit (EXIT_FAILURE);
113
114 exit (GMT_NOERROR); /* Return the status from this program */
115 }
116