/[dtapublic]/projs/dtats/trunk/projs/2018/20180112_ifsfscan/c_main.c
ViewVC logotype

Diff of /projs/dtats/trunk/projs/2018/20180112_ifsfscan/c_main.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 193 by dashley, Sat Jul 14 21:20:02 2018 UTC revision 197 by dashley, Sun Jul 15 01:26:18 2018 UTC
# Line 1  Line 1 
1  //$Header$  //$Header$
2    //{f0d952cc-7499-4d5c-9f46-d0b509c5701c}
3  //-------------------------------------------------------------------------------------------------  //-------------------------------------------------------------------------------------------------
4  //Copyright (c) 2018, David T. Ashley  //Copyright (c) 2018, David T. Ashley
5  //  //
# Line 29  Line 30 
30  #include <stdio.h>  #include <stdio.h>
31  #include <stdlib.h>  #include <stdlib.h>
32  #include <string.h>  #include <string.h>
33    #include <tchar.h>
34  #include <time.h>  #include <time.h>
35    #include <windows.h>
36    
37    
38  #define FCMIOF_HORIZONTAL_BAR_SEP_CHAR    ('-')  #define FCMIOF_HORIZONTAL_BAR_SEP_CHAR    ('-')
39  #define FCMIOF_LINE_LEN                   (78)  #define FCMIOF_LINE_LEN                   (78)
# Line 335  const char *STRING_vcinfo(size_t which) Line 339  const char *STRING_vcinfo(size_t which)
339  {  {
340     static const char * const vcinfo[] =     static const char * const vcinfo[] =
341     {     {
342        "$Header$",        "$HeadURL$",
343        "$Date$",        "$Date$",
344        "$Revision$",        "$Revision$",
345        "$Author$",        "$Author$",
346        "$HeadURL$",        "Project GUID:       {f7d7586a-557c-43cb-bec5-b49765d96a5d}",
347        "$Id"        "c_main.c GUID:      {f0d952cc-7499-4d5c-9f46-d0b509c5701c}",
348          "ifsfscan.cpp GUID:  {2abd4437-101c-49eb-99ac-c1174f55b626}",
349     };     };
350    
351       if (which < (sizeof(vcinfo) / sizeof(vcinfo[0])))
352          return(vcinfo[which]);
353       else
354          return(NULL);
355  }  }
356    
357  //--------------------------------------------------------------------------------  //--------------------------------------------------------------------------------
# Line 491  void FCMIOF_time_stream(FILE *s, time_t Line 500  void FCMIOF_time_stream(FILE *s, time_t
500          }          }
501  }  }
502    
503    int is_legal_non_eol_character(char c)
504    {
505       if ((c >= 32) && (c <= 126))
506          return(1);
507       else
508          return(0);
509    }
510    
511    int is_illegal_non_eol_character(char c)
512    {
513       if (((c < 32) || (c > 126)) && (c != 13) && (c != 10))
514          return(1);
515       else
516          return(0);
517    }
518    
519    int is_tab(char c)
520    {
521       if (c == 9)
522          return(1);
523       else
524          return(0);
525    }
526    
527    int is_cr(char c)
528    {
529       if (c == 13)
530          return(1);
531       else
532          return(0);
533    }
534    
535    int is_lf(char c)
536    {
537       if (c == 10)
538          return(1);
539       else
540          return(0);
541    }
542    
543    void emit_human_friendly_llu(unsigned long long arg)
544    {
545       printf("%llu", arg);
546    }
547    
548    void emit_file_pos_3tuple(unsigned long long line, unsigned long long col, unsigned long long offset)
549    {
550       printf("      Line: ");
551       emit_human_friendly_llu(line);
552       printf(", Col: ");
553       emit_human_friendly_llu(col);
554       printf(", Offset: ");
555       emit_human_friendly_llu(offset);
556       printf("\n");
557    }
558    
559    void process_opened_handle(FILE *f)
560    {
561       unsigned long long char_no;
562       unsigned long long line_no;
563       unsigned long long col_no;
564       enum {PST_LINE, PST_CR_FOUND, PST_LF_FOUND} state = PST_LINE;
565       int exit_flag = 0;
566       char in_c, prev_c;
567       unsigned char in_uc;
568       int in_i;
569      
570       in_i = fgetc(f);
571    
572       if (in_i == EOF)
573       {
574          //Zero-length file or error.  Because this tool isn't critical, no need to figure out which, exactly.
575          printf("      Zero-length file.\n");
576          return;
577       }
578    
579       prev_c = ' ';
580       char_no = 0;
581       line_no = 1;
582       col_no  = 1;
583       in_c    = in_i & 0xFF;
584       in_uc   = in_i & 0xFF;
585    
586       do
587       {
588          //Illegal characters always get flagged.
589          if (is_illegal_non_eol_character(in_c))
590          {
591             emit_file_pos_3tuple(line_no, col_no, char_no);
592             printf("         Illegal character: 0x%02x.\n", ((unsigned)in_uc));
593          }
594    
595          //Run through the state machine, which would look for bad EOL sequences.
596          switch (state)
597          {
598          case PST_LINE:
599             if (is_lf(in_c))
600             {
601                //Line feeds not allowed without preceding carriage return.
602                emit_file_pos_3tuple(line_no, col_no, char_no);
603                printf("         Out of sequence line feed character (0x0a)\n");
604                line_no++;
605                col_no = 1;
606                state = PST_LF_FOUND;
607             }
608             else if (is_cr(in_c))
609             {
610                //Legal
611                state = PST_CR_FOUND;
612             }
613             else
614             {
615                //Ordinary character.
616                col_no++;
617             }
618             break;
619          case PST_CR_FOUND:
620             if (is_lf(in_c))
621             {
622                //Legal
623                line_no++;
624                col_no = 1;
625                state = PST_LF_FOUND;
626             }
627             else if (is_cr(in_c))
628             {
629                //Back-to-back carriage returns not allowed.
630                emit_file_pos_3tuple(line_no, col_no, char_no);
631                printf("         Out of sequence carriage return character (0x0D)\n");
632                col_no++;
633             }
634             else
635             {
636                //Ordinary character.  Illegal, because LF must follow CR.
637                emit_file_pos_3tuple(line_no, col_no, char_no);
638                printf("         Carriage return followed by 0x%02x rather than LF.\n", (unsigned)in_uc);
639                col_no++;
640             }
641             break;
642          case PST_LF_FOUND:
643             if (is_lf(in_c))
644             {
645                //Illegal.  Back-to-back line feeds not allowed.
646                emit_file_pos_3tuple(line_no, col_no, char_no);
647                printf("         Out of sequence line feed character (0x0A).\n");
648                line_no++;
649                col_no = 1;
650             }
651             else if (is_cr(in_c))
652             {
653                //Legal.  Blank lines are fine.
654                col_no++;
655                state = PST_LF_FOUND;
656             }
657             else
658             {
659                //Ordinary character.  Legal.
660                col_no++;
661                state = PST_LINE;
662             }
663             break;
664          default:
665             USERASSERT_assert(0, __FILE__, __LINE__);
666             break;
667          }
668    
669    
670          in_i = fgetc(f);
671          char_no++;
672          if (in_i == EOF)
673             exit_flag = 1;
674          in_c = in_i & 0xff;
675          in_uc = in_i & 0xff;
676    
677       } while (!exit_flag);
678    
679    }
680    
681    void process_file_by_name(const char *s)
682    {
683       FILE *f;
684    
685       printf("   %s\n", s);
686    
687       f = fopen(s, "rb");
688    
689       if (!f)
690       {
691          printf("      fopen() failed.\n");
692       }
693       else
694       {
695          process_opened_handle(f);
696    
697          if (fclose(f))
698          {
699             printf("      fclose() failed.\n");
700          }
701       }
702    }
703    
704  void process_filename_or_wildcard(const char *fname_or_wildcard)  void process_filename_or_wildcard(const char *fname_or_wildcard)
705  {  {
706       HANDLE hFind;
707       WIN32_FIND_DATA FindFileData;
708    
709     //Incoming pointer is worthy of an assertion.  The OS should not every deliver     //Incoming pointer is worthy of an assertion.  The OS should not every deliver
710     //a NULL pointer or empty string to us.     //a NULL pointer or empty string to us.
711     USERASSERT_assert(fname_or_wildcard != NULL,     __FILE__, __LINE__);     USERASSERT_assert(fname_or_wildcard != NULL, __FILE__, __LINE__);
712     USERASSERT_assert(strlen(fname_or_wildcard) > 0, __FILE__, __LINE__);     USERASSERT_assert(strlen(fname_or_wildcard) > 0, __FILE__, __LINE__);
713    
714       printf("%s\n", fname_or_wildcard);
715    
716       if (STRING_is_longer_than_maxpath(fname_or_wildcard))
717       {
718          printf("   Specified filename or wildcard too long--cannot process.\n");
719       }
720       else if (STRING_contains_terminating_backslash(fname_or_wildcard))
721       {
722          printf("   Specified filename or wildcard contains terminating \"\\\"--cannot process.\n");
723       }
724       else if (STRING_contains_wildcard(fname_or_wildcard))
725       {
726          hFind = FindFirstFile((TCHAR *)fname_or_wildcard, &FindFileData);
727    
728          if (hFind == INVALID_HANDLE_VALUE)
729          {
730             printf("   Wildcard does not match existing files or is invalid.\n");
731          }
732          else
733          {
734             char path_drive[_MAX_PATH + 5];
735             char path_dir[_MAX_PATH + 5];
736             char path_fname[_MAX_PATH + 5];
737             char path_ext[_MAX_PATH + 5];
738             char path_full[_MAX_PATH + 5];
739    
740             if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
741             {
742                _splitpath(fname_or_wildcard, path_drive, path_dir, path_fname, path_ext);
743    
744                strcpy(path_full, path_drive);
745                strcat(path_full, path_dir);
746                strcat(path_full, FindFileData.cFileName);
747    
748                process_file_by_name(path_full);
749             }
750    
751             while (FindNextFile(hFind, &FindFileData) != 0)
752             {
753                if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
754                {
755                   _splitpath(fname_or_wildcard, path_drive, path_dir, path_fname, path_ext);
756    
757                   strcpy(path_full, path_drive);
758                   strcat(path_full, path_dir);
759                   strcat(path_full, FindFileData.cFileName);
760    
761                   process_file_by_name(path_full);
762                }
763             }
764          }
765    
766          if (hFind != INVALID_HANDLE_VALUE)
767          {
768             FindClose(hFind);
769          }
770       }
771       else
772       {
773          process_file_by_name(fname_or_wildcard);
774       }
775  }  }
776    
777  void emit_no_par_documentation(void)  void emit_no_par_documentation(void)
# Line 514  void emit_no_par_documentation(void) Line 788  void emit_no_par_documentation(void)
788     for (i = 0; i < (sizeof(license_text) / sizeof(license_text[0])); i++)     for (i = 0; i < (sizeof(license_text) / sizeof(license_text[0])); i++)
789        printf("%s\n", license_text[i]);        printf("%s\n", license_text[i]);
790     FCMIOF_stream_hline(stdout);     FCMIOF_stream_hline(stdout);
791       printf("Program built on %s at %s.\n", __DATE__, __TIME__);
792       i = 0;
793       while (STRING_vcinfo(i))
794       {
795          printf("%s\n", STRING_vcinfo(i));
796          i++;
797       }
798       FCMIOF_stream_hline(stdout);
799     for (i = 0; i < (sizeof(prog_help_text) / sizeof(prog_help_text[0])); i++)     for (i = 0; i < (sizeof(prog_help_text) / sizeof(prog_help_text[0])); i++)
800        printf("%s\n", prog_help_text[i]);        printf("%s\n", prog_help_text[i]);
801     FCMIOF_stream_hline(stdout);     FCMIOF_stream_hline(stdout);

Legend:
Removed from v.193  
changed lines
  Added in v.197

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25