pmc0903

ci_dbf.c - converter - dbf to tabtxt

Aug 9th, 2025 (edited)
786
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.96 KB | Source Code | 0 0
  1. // Includes
  2.     #include <stdio.h>
  3.     #include <stdlib.h>
  4.     #include <stdbool.h>
  5.     #include <string.h>
  6.     #include "..\x_str.h"
  7. // Global Variables
  8.     char*   gps_output_write = "wb";
  9.     int     gpb_output_append = false;
  10.     int     gpi_match_text = 0;
  11.     int     gpi_match_field = 0;
  12.     int     gpi_project_field = 0;
  13. // Type Defintions
  14.     // DBF Header Format
  15.     typedef struct struct_DBF_HEADER
  16.     {
  17.         char    i_ver;
  18.         char    i_year;
  19.         char    i_mon;
  20.         char    i_day;
  21.         int     i_rec_count;
  22.         short   i_header_size;
  23.         short   i_rec_length;
  24.     } type_DBF_HEADER;
  25.     // DBF Field Defintion Formation
  26.     typedef struct struct_DBF_FIELDS
  27.     {
  28.         char            s_name[11];
  29.         char            s_type;
  30.         unsigned int    i_fda;
  31.         unsigned char   i_field_len;
  32.         unsigned char   i_field_decimal;
  33.         char            s_discard[14];
  34.     } type_DBF_FIELDS;
  35. //----------------------------------------------------------------------------
  36. // Functions
  37. //
  38. long ifn_file_slurp( char* ps_file_name, char** ps_buffer ) {
  39.     FILE* fp = fopen( ps_file_name, "rb" );
  40.     long i_file_len = 0;
  41.     if (fp != NULL) {
  42.         if (fseek(fp, 0L, SEEK_END) == 0) {
  43.             long i_bufsize = ftell(fp);
  44.             if (i_bufsize == -1) { fprintf( stderr, "Error reading file - i_bufsize !" ); }
  45.             if ( *ps_buffer != NULL ) { free(*ps_buffer); }
  46.             *ps_buffer = malloc(sizeof(char) * (i_bufsize + 1));
  47.             if (fseek(fp, 0L, SEEK_SET) != 0) { fputs("Error reading file - SEEK_SET !", stderr ); }
  48.             i_file_len = fread(*ps_buffer, sizeof(char), i_bufsize, fp);
  49.             if (i_file_len == 0) {
  50.                 fprintf( stderr, "Error reading file - i_file_len !" );
  51.             } else {
  52.                 (*ps_buffer)[++i_file_len] = '\0';
  53.             }
  54.         }
  55.         fclose(fp);
  56.     } else {
  57.         fprintf( stderr, "Error finding file - Input file doesn't exist !\n");
  58.     }
  59.     return (i_file_len);
  60. }
  61. //
  62. //----------------------------------------------------------------------------
  63. //
  64. void    fn_help() {
  65.     // ---------
  66.     printf("\nUsage: ci_dbf input_file.DBF output_file.TXT [<options>]\n\n");
  67.     printf("Options:\n");
  68.     printf("\t/m {value}\tOutputs records containing {value}.\n");
  69.     printf("\t/f {field}\tLimit match to {field}.\n");
  70.     printf("\t/app\t\tAppend to output file.  Does not print field names.\n");
  71.     printf("\t/prj {project}\tAdds a PROJECT field. Each record has {project} include in the output.\n");
  72.     printf("\t/fmt\t\tFormat numeric fields - right align ..\n");
  73.     printf("\t/?\t\tThis help text.\n");
  74.     return;
  75. }
  76. //
  77. //----------------------------------------------------------------------------
  78. //
  79. int main(int pi, char **ps ) {
  80.     printf("\nCI_DBF.EXE - v2025.08.09a : Convert DBF to TabTXT\n");
  81.     // Input Checks
  82.         int pi_field_match = -1;
  83.         // Options
  84.         int i = 1;
  85.         while( i < pi ) {
  86.             if (( strncmp("/?"  , ps[i], 2) == 0))  { fn_help(); return(0); }
  87.             if (( strncmp("/app", ps[i], 4) == 0))  { gps_output_write = "ab"; gpb_output_append = true; }
  88.             if (( strncmp("/m"  , ps[i], 2) == 0))  { gpi_match_text = i + 1; }
  89.             if (( strncmp("/f"  , ps[i], 2) == 0))  { gpi_match_field = i + 1; }
  90.             if (( strncmp("/prj", ps[i], 4) == 0))  { gpi_project_field = i + 1; }
  91.             i++;
  92.         }
  93.         if ( gpi_match_text > 0 )   { if ( ps[gpi_match_text] ) { x_fn_str_upper( ps[gpi_match_text] ); }}
  94.         if ( gpi_match_field > 0)   { if ( ps[gpi_match_field] )    { pi_field_match = atoi( ps[gpi_match_field] ); }}
  95.         // Main arguments
  96.         if ( !ps[1] )   { fprintf( stderr, "No input file !\n" ); return( -1 ); }
  97.         if ( !ps[2] )   { fprintf( stderr, "No output file !\n" ); return( -1 ); }
  98.     // Header
  99.         printf( "\nReading .. %s\n", ps[1] );
  100.         char*               s_file              = NULL;
  101.         long                i_file_size_bytes   = ifn_file_slurp( ps[1], &s_file );
  102.         if ( i_file_size_bytes < 1 ) { return( -1 ); }
  103.         type_DBF_HEADER*    xo_dbf_header       = (type_DBF_HEADER*) &s_file[0];
  104.         //xo_dbf_header = (type_DBF_HEADER*) &s_file[0];
  105.         printf( "\nVer:               %d"           , xo_dbf_header->i_ver );
  106.         printf( "\nLast Mod:          %d-%02d-%02d" , (xo_dbf_header->i_year + 1900), xo_dbf_header->i_mon, xo_dbf_header->i_day );
  107.         printf( "\nNumber of Records: %ld"          , xo_dbf_header->i_rec_count );
  108.         printf( "\nHeader Size:       %d"           , xo_dbf_header->i_header_size );
  109.         printf( "\nRecord Length:     %d"           , xo_dbf_header->i_rec_length );
  110.         printf( "\nDBF Size Length:   %d"           , xo_dbf_header->i_header_size + ( xo_dbf_header->i_rec_count * xo_dbf_header->i_rec_length ) );
  111.     // Columns -- Fields
  112.         printf( "\n\nWriting ..%s\n", ps[2] );
  113.         char s_EOL = 13;
  114.         FILE* fp = fopen( ps[2], gps_output_write );
  115.         type_DBF_FIELDS*    xo_dbf_fields[128];
  116.         int i_field = 0;
  117.         long i_file_index = 32;
  118.         long i_buf = 0;
  119.         long i_fda_calc = 1;
  120.         char* s_buf;
  121.         s_buf = malloc( xo_dbf_header->i_rec_length + 50 );
  122.         if ( gpi_project_field == 0 ) {
  123.             i_buf = snprintf ( s_buf, 10, "#\tDEL\t" );
  124.         } else {
  125.             i_buf = snprintf ( s_buf, 60, "#\tPROJECT\tDEL\t" );
  126.         }
  127.         if ( !gpb_output_append ) { fwrite( s_buf, i_buf, 1, fp ); }
  128.         while ( s_file[i_file_index] != 0x0d ) {
  129.             xo_dbf_fields[i_field] = (type_DBF_FIELDS*) &s_file[i_file_index];
  130.             xo_dbf_fields[i_field]->i_fda = i_fda_calc;
  131.             printf ( "\n%d\t%10s\t%c\t%d\t%d\t%d"
  132.                 , i_field
  133.                 , xo_dbf_fields[i_field]->s_name
  134.                 , xo_dbf_fields[i_field]->s_type
  135.                 , xo_dbf_fields[i_field]->i_fda
  136.                 , xo_dbf_fields[i_field]->i_field_len
  137.                 , xo_dbf_fields[i_field]->i_field_decimal
  138.             );
  139.             i_fda_calc += xo_dbf_fields[i_field]->i_field_len;
  140.             i_buf = snprintf ( s_buf, 50, "%s (%c,%d)\t"
  141.                 , xo_dbf_fields[i_field]->s_name
  142.                 , xo_dbf_fields[i_field]->s_type
  143.                 , xo_dbf_fields[i_field]->i_field_len
  144.             );
  145.             if ( !gpb_output_append ) { fwrite( s_buf, i_buf, 1, fp ); }
  146.             i_field++;
  147.             i_file_index += 32;
  148.         }
  149.         if ( !gpb_output_append ) { fwrite( &s_EOL, 1, 1, fp ); }
  150.         int i_field_count = i_field;
  151.         printf( "\n\n%d fields.", i_field_count );
  152.     // Rows -- Records
  153.         char*   s_rec;
  154.         char*   s_rec_upper;
  155.         long    i_rec = 0;
  156.         long    i_match = 0;
  157.         char*   s_match;
  158.         char    s_field[300]; // Each field can be a max of 254 characters
  159.         char*   s_field_upper;
  160.         char*   s_match_field;
  161.         int     i_match_field;
  162.         int     i_space;
  163.         s_rec = malloc( xo_dbf_header->i_rec_length + 1 );
  164.         while ( i_rec < xo_dbf_header->i_rec_count ) {
  165.             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 );
  166.             s_rec[xo_dbf_header->i_rec_length] = '\0';
  167.             s_match = s_rec;
  168.             if ( gpi_match_text > 0 ) {
  169.                 s_rec_upper = x_sfn_str_upper( s_rec );
  170.                 s_match = strstr( s_rec_upper, ps[gpi_match_text] );
  171.                 free( s_rec_upper );
  172.             }
  173.             if ( s_match ) {
  174.                 if ( gpi_project_field == 0 ) {
  175.                     i_buf = snprintf ( s_buf, 10, "%d\t%c\t", (i_rec + 1), s_rec[0] );
  176.                 } else {
  177.                     i_buf = snprintf ( s_buf, 60, "%d\t%s\t%c\t", (i_rec + 1), ps[gpi_project_field], s_rec[0] );
  178.                 }
  179.                 i_field = 0;
  180.                 i_match_field = 0;
  181.                 while ( i_field < i_field_count ) {
  182.                     memcpy( s_field, &s_rec[xo_dbf_fields[i_field]->i_fda], xo_dbf_fields[i_field]->i_field_len );
  183.                     // Trim trailing whitespace
  184.                         i_space = xo_dbf_fields[i_field]->i_field_len;
  185.                         s_field[i_space] = 0x020;
  186.                         while (( s_field[i_space] == 0x020 ) && ( i_space >= 0 )) {
  187.                             i_space--;
  188.                         }
  189.                         s_field[i_space + 1] = '\0';
  190.                     // Check for matching field
  191.                         s_match_field = s_field;
  192.                         if ( pi_field_match == i_field ) {
  193.                             s_field_upper = x_sfn_str_upper( s_field );
  194.                             s_match_field = strstr( s_field_upper, ps[gpi_match_text] );
  195.                             free( s_field_upper );
  196.                         }
  197.                         if ( s_match_field ) { i_match_field++; }
  198.                     // Add field data to output buffer
  199.                         i_buf += snprintf ( &s_buf[i_buf], xo_dbf_header->i_rec_length - i_buf, "%s\t" , s_field );
  200.                         i_field++;
  201.                 }
  202.                 if ( i_match_field == i_field_count ) {
  203.                     i_match++;
  204.                     fwrite( s_buf, i_buf - 1, 1, fp );
  205.                     fwrite( &s_EOL, 1, 1, fp );
  206.                 }
  207.             }
  208.             i_rec++;
  209.         }
  210.         printf( "\n%d matched records.", i_match );
  211.         printf( "\n" );
  212.     // Program End
  213.         fclose( fp );
  214.         free( s_rec );
  215.         free( s_buf );
  216.         free( s_file );
  217.         return( 0 );
  218. }
  219. //
  220. //----------------------------------------------------------------------------
  221.  
Tags: SCADA
Advertisement