Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Includes
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdbool.h>
- #include <string.h>
- #include "..\x_str.h"
- // Global Variables
- char* gps_output_write = "wb";
- int gpb_output_append = false;
- int gpi_match_text = 0;
- int gpi_match_field = 0;
- int gpi_project_field = 0;
- // Type Defintions
- // DBF Header Format
- typedef struct struct_DBF_HEADER
- {
- char i_ver;
- char i_year;
- char i_mon;
- char i_day;
- int i_rec_count;
- short i_header_size;
- short i_rec_length;
- } type_DBF_HEADER;
- // DBF Field Defintion Formation
- typedef struct struct_DBF_FIELDS
- {
- char s_name[11];
- char s_type;
- unsigned int i_fda;
- unsigned char i_field_len;
- unsigned char i_field_decimal;
- char s_discard[14];
- } type_DBF_FIELDS;
- //----------------------------------------------------------------------------
- // Functions
- //
- long ifn_file_slurp( char* ps_file_name, char** ps_buffer ) {
- FILE* fp = fopen( ps_file_name, "rb" );
- long i_file_len = 0;
- if (fp != NULL) {
- if (fseek(fp, 0L, SEEK_END) == 0) {
- long i_bufsize = ftell(fp);
- if (i_bufsize == -1) { fprintf( stderr, "Error reading file - i_bufsize !" ); }
- if ( *ps_buffer != NULL ) { free(*ps_buffer); }
- *ps_buffer = malloc(sizeof(char) * (i_bufsize + 1));
- if (fseek(fp, 0L, SEEK_SET) != 0) { fputs("Error reading file - SEEK_SET !", stderr ); }
- i_file_len = fread(*ps_buffer, sizeof(char), i_bufsize, fp);
- if (i_file_len == 0) {
- fprintf( stderr, "Error reading file - i_file_len !" );
- } else {
- (*ps_buffer)[++i_file_len] = '\0';
- }
- }
- fclose(fp);
- } else {
- fprintf( stderr, "Error finding file - Input file doesn't exist !\n");
- }
- return (i_file_len);
- }
- //
- //----------------------------------------------------------------------------
- //
- void fn_help() {
- // ---------
- printf("\nUsage: ci_dbf input_file.DBF output_file.TXT [<options>]\n\n");
- printf("Options:\n");
- printf("\t/m {value}\tOutputs records containing {value}.\n");
- printf("\t/f {field}\tLimit match to {field}.\n");
- printf("\t/app\t\tAppend to output file. Does not print field names.\n");
- printf("\t/prj {project}\tAdds a PROJECT field. Each record has {project} include in the output.\n");
- printf("\t/fmt\t\tFormat numeric fields - right align ..\n");
- printf("\t/?\t\tThis help text.\n");
- return;
- }
- //
- //----------------------------------------------------------------------------
- //
- int main(int pi, char **ps ) {
- printf("\nCI_DBF.EXE - v2025.08.09a : Convert DBF to TabTXT\n");
- // Input Checks
- int pi_field_match = -1;
- // Options
- int i = 1;
- while( i < pi ) {
- if (( strncmp("/?" , ps[i], 2) == 0)) { fn_help(); return(0); }
- if (( strncmp("/app", ps[i], 4) == 0)) { gps_output_write = "ab"; gpb_output_append = true; }
- if (( strncmp("/m" , ps[i], 2) == 0)) { gpi_match_text = i + 1; }
- if (( strncmp("/f" , ps[i], 2) == 0)) { gpi_match_field = i + 1; }
- if (( strncmp("/prj", ps[i], 4) == 0)) { gpi_project_field = i + 1; }
- i++;
- }
- if ( gpi_match_text > 0 ) { if ( ps[gpi_match_text] ) { x_fn_str_upper( ps[gpi_match_text] ); }}
- if ( gpi_match_field > 0) { if ( ps[gpi_match_field] ) { pi_field_match = atoi( ps[gpi_match_field] ); }}
- // Main arguments
- if ( !ps[1] ) { fprintf( stderr, "No input file !\n" ); return( -1 ); }
- if ( !ps[2] ) { fprintf( stderr, "No output file !\n" ); return( -1 ); }
- // Header
- printf( "\nReading .. %s\n", ps[1] );
- char* s_file = NULL;
- long i_file_size_bytes = ifn_file_slurp( ps[1], &s_file );
- if ( i_file_size_bytes < 1 ) { return( -1 ); }
- type_DBF_HEADER* xo_dbf_header = (type_DBF_HEADER*) &s_file[0];
- //xo_dbf_header = (type_DBF_HEADER*) &s_file[0];
- printf( "\nVer: %d" , xo_dbf_header->i_ver );
- printf( "\nLast Mod: %d-%02d-%02d" , (xo_dbf_header->i_year + 1900), xo_dbf_header->i_mon, xo_dbf_header->i_day );
- printf( "\nNumber of Records: %ld" , xo_dbf_header->i_rec_count );
- printf( "\nHeader Size: %d" , xo_dbf_header->i_header_size );
- printf( "\nRecord Length: %d" , xo_dbf_header->i_rec_length );
- printf( "\nDBF Size Length: %d" , xo_dbf_header->i_header_size + ( xo_dbf_header->i_rec_count * xo_dbf_header->i_rec_length ) );
- // Columns -- Fields
- printf( "\n\nWriting ..%s\n", ps[2] );
- char s_EOL = 13;
- FILE* fp = fopen( ps[2], gps_output_write );
- type_DBF_FIELDS* xo_dbf_fields[128];
- int i_field = 0;
- long i_file_index = 32;
- long i_buf = 0;
- long i_fda_calc = 1;
- char* s_buf;
- s_buf = malloc( xo_dbf_header->i_rec_length + 50 );
- if ( gpi_project_field == 0 ) {
- i_buf = snprintf ( s_buf, 10, "#\tDEL\t" );
- } else {
- i_buf = snprintf ( s_buf, 60, "#\tPROJECT\tDEL\t" );
- }
- if ( !gpb_output_append ) { fwrite( s_buf, i_buf, 1, fp ); }
- while ( s_file[i_file_index] != 0x0d ) {
- xo_dbf_fields[i_field] = (type_DBF_FIELDS*) &s_file[i_file_index];
- xo_dbf_fields[i_field]->i_fda = i_fda_calc;
- printf ( "\n%d\t%10s\t%c\t%d\t%d\t%d"
- , i_field
- , xo_dbf_fields[i_field]->s_name
- , xo_dbf_fields[i_field]->s_type
- , xo_dbf_fields[i_field]->i_fda
- , xo_dbf_fields[i_field]->i_field_len
- , xo_dbf_fields[i_field]->i_field_decimal
- );
- i_fda_calc += xo_dbf_fields[i_field]->i_field_len;
- i_buf = snprintf ( s_buf, 50, "%s (%c,%d)\t"
- , xo_dbf_fields[i_field]->s_name
- , xo_dbf_fields[i_field]->s_type
- , xo_dbf_fields[i_field]->i_field_len
- );
- if ( !gpb_output_append ) { fwrite( s_buf, i_buf, 1, fp ); }
- i_field++;
- i_file_index += 32;
- }
- if ( !gpb_output_append ) { fwrite( &s_EOL, 1, 1, fp ); }
- int i_field_count = i_field;
- printf( "\n\n%d fields.", i_field_count );
- // Rows -- Records
- char* s_rec;
- char* s_rec_upper;
- long i_rec = 0;
- long i_match = 0;
- char* s_match;
- char s_field[300]; // Each field can be a max of 254 characters
- char* s_field_upper;
- char* s_match_field;
- int i_match_field;
- int i_space;
- s_rec = malloc( xo_dbf_header->i_rec_length + 1 );
- while ( i_rec < xo_dbf_header->i_rec_count ) {
- memcpy( s_rec, &s_file[xo_dbf_header->i_header_size + ( i_rec * xo_dbf_header->i_rec_length ) ], xo_dbf_header->i_rec_length );
- s_rec[xo_dbf_header->i_rec_length] = '\0';
- s_match = s_rec;
- if ( gpi_match_text > 0 ) {
- s_rec_upper = x_sfn_str_upper( s_rec );
- s_match = strstr( s_rec_upper, ps[gpi_match_text] );
- free( s_rec_upper );
- }
- if ( s_match ) {
- if ( gpi_project_field == 0 ) {
- i_buf = snprintf ( s_buf, 10, "%d\t%c\t", (i_rec + 1), s_rec[0] );
- } else {
- i_buf = snprintf ( s_buf, 60, "%d\t%s\t%c\t", (i_rec + 1), ps[gpi_project_field], s_rec[0] );
- }
- i_field = 0;
- i_match_field = 0;
- while ( i_field < i_field_count ) {
- memcpy( s_field, &s_rec[xo_dbf_fields[i_field]->i_fda], xo_dbf_fields[i_field]->i_field_len );
- // Trim trailing whitespace
- i_space = xo_dbf_fields[i_field]->i_field_len;
- s_field[i_space] = 0x020;
- while (( s_field[i_space] == 0x020 ) && ( i_space >= 0 )) {
- i_space--;
- }
- s_field[i_space + 1] = '\0';
- // Check for matching field
- s_match_field = s_field;
- if ( pi_field_match == i_field ) {
- s_field_upper = x_sfn_str_upper( s_field );
- s_match_field = strstr( s_field_upper, ps[gpi_match_text] );
- free( s_field_upper );
- }
- if ( s_match_field ) { i_match_field++; }
- // Add field data to output buffer
- i_buf += snprintf ( &s_buf[i_buf], xo_dbf_header->i_rec_length - i_buf, "%s\t" , s_field );
- i_field++;
- }
- if ( i_match_field == i_field_count ) {
- i_match++;
- fwrite( s_buf, i_buf - 1, 1, fp );
- fwrite( &s_EOL, 1, 1, fp );
- }
- }
- i_rec++;
- }
- printf( "\n%d matched records.", i_match );
- printf( "\n" );
- // Program End
- fclose( fp );
- free( s_rec );
- free( s_buf );
- free( s_file );
- return( 0 );
- }
- //
- //----------------------------------------------------------------------------
Advertisement