"Fossies" - the Fresh Open Source Software Archive

Member "detox-1.4.5/src/parse_table.c" (15 Aug 2021, 3994 Bytes) of package /linux/privat/detox-1.4.5.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "parse_table.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.4.2_vs_1.4.3.

    1 /**
    2  * This file is part of the Detox package.
    3  *
    4  * Copyright (c) Doug Harple <detox.dharple@gmail.com>
    5  *
    6  * For the full copyright and license information, please view the LICENSE
    7  * file that was distributed with this source code.
    8  */
    9 
   10 #include "config.h"
   11 
   12 #include <sys/types.h>
   13 #include <sys/stat.h>
   14 #include <stdio.h>
   15 #include <stdlib.h>
   16 #include <string.h>
   17 #include <ctype.h>
   18 #include <errno.h>
   19 #include <locale.h>
   20 
   21 #include "table.h"
   22 
   23 #define LINE_LENGTH 6
   24 
   25 enum {
   26     BASE_STATE,
   27     INSIDE_STATE
   28 };
   29 
   30 struct translation_table *parse_table(char *filename)
   31 {
   32     FILE *ttable_file;
   33     char *work;
   34     int code;
   35     int offset;
   36     char *parsed;
   37     int err;
   38     int size;
   39     int max_data_length;
   40     int ret;
   41     int state;
   42     char *system_ctype;
   43 
   44     struct translation_table *table;
   45 
   46     struct stat ttable_stat;
   47 
   48     err = stat(filename, &ttable_stat);
   49     if (err == -1) {
   50         return NULL;
   51     }
   52 
   53     system_ctype = setlocale(LC_CTYPE, "");
   54     if (system_ctype == NULL) {
   55         system_ctype = "";  // I don't think we can free the return from setlocale()
   56     }
   57 
   58     size = 0;
   59 
   60     if (ttable_stat.st_size > 0) {
   61         size = ttable_stat.st_size / LINE_LENGTH;
   62     }
   63 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
   64     else {
   65         size = (512 * ttable_stat.st_blocks) / LINE_LENGTH;
   66     }
   67 #endif
   68 
   69     if (size < 500) {
   70         size = 500;
   71     }
   72 
   73     table = table_init(size);
   74     if (table == NULL) {
   75         return NULL;
   76     }
   77 
   78     ttable_file = fopen(filename, "r");
   79     if (ttable_file == NULL) {
   80         fprintf(stderr, "Unable to open translation table: %s\n", strerror(errno));
   81         return NULL;
   82     }
   83 
   84     work = malloc(1024);
   85     if (work == NULL) {
   86         fprintf(stderr, "Unable to allocate memory: %s\n", strerror(errno));
   87         return NULL;
   88     }
   89 
   90     parsed = malloc(1024);
   91     if (parsed == NULL) {
   92         fprintf(stderr, "Unable to allocate memory: %s\n", strerror(errno));
   93         return NULL;
   94     }
   95 
   96     max_data_length = 1;
   97     state = BASE_STATE;
   98 
   99     while (fgets(work, 1024, ttable_file) != NULL) {
  100         if (*work == '#') {
  101 
  102             /*
  103              * Don't even bother
  104              */
  105             continue;
  106         }
  107 
  108         parsed[0] = '\0';
  109 
  110         if (state == BASE_STATE) {
  111             ret = sscanf(work, " %s %n", parsed, &offset);
  112 
  113             if (ret == 0) {
  114                 continue;
  115             }
  116 
  117             if (strncasecmp(parsed, "start", 5) == 0) {
  118                 if (work[offset] == '\0') {
  119                     // All languages
  120                     state = INSIDE_STATE;
  121                     continue;
  122                 }
  123 
  124                 if (work[offset] == '"') {
  125                     sscanf(work + offset + 1, "%[^\"]", parsed);
  126                 }
  127                 else if (work[offset] == '\'') {
  128                     sscanf(work + offset + 1, "%[^']", parsed);
  129                 }
  130                 else {
  131                     sscanf(work + offset, "%s", parsed);
  132                 }
  133 
  134                 if (strncasecmp(parsed, system_ctype, strlen(parsed)) == 0) {
  135                     state = INSIDE_STATE;
  136                 }
  137                 // else ignore this start/end block
  138 
  139                 continue;
  140             }
  141 
  142             if (strncasecmp(parsed, "default", 7) == 0) {
  143 
  144                 if (work[offset] == '\0') {
  145                     table->default_translation = NULL;
  146                     continue;
  147                 }
  148 
  149                 if (work[offset] == '"') {
  150                     sscanf(work + offset + 1, "%[^\"]", parsed);
  151                 }
  152                 else if (work[offset] == '\'') {
  153                     sscanf(work + offset + 1, "%[^']", parsed);
  154                 }
  155                 else {
  156                     sscanf(work + offset, "%s", parsed);
  157                 }
  158 
  159                 table->default_translation = strdup(parsed);
  160 
  161                 if (strlen(parsed) > max_data_length) {
  162                     max_data_length = strlen(parsed);
  163                 }
  164 
  165                 continue;
  166             }
  167 
  168             continue;
  169         }
  170 
  171         /*
  172          * Inside state
  173          */
  174 
  175         code = -1;
  176 
  177         ret = sscanf(work, "%i %n", &code, &offset);
  178 
  179         if (ret == 0 || code < 0 || offset < 0) {
  180 
  181             /*
  182              * Check for end
  183              */
  184             ret = sscanf(work, " %s %n", parsed, &offset);
  185 
  186             if (ret > 0 && strncasecmp(parsed, "end", 5) == 0) {
  187                 state = BASE_STATE;
  188             }
  189 
  190             continue;
  191         }
  192 
  193         if (work[offset] == '\0') {
  194             continue;
  195         }
  196 
  197         if (work[offset] == '"') {
  198             sscanf(work + offset + 1, "%[^\"]", parsed);
  199         }
  200         else if (work[offset] == '\'') {
  201             sscanf(work + offset + 1, "%[^']", parsed);
  202         }
  203         else {
  204             sscanf(work + offset, "%s", parsed);
  205         }
  206 
  207         table_put(table, code, parsed);
  208 
  209         if (strlen(parsed) > max_data_length) {
  210             max_data_length = strlen(parsed);
  211         }
  212 
  213     }
  214 
  215     table->max_data_length = max_data_length;
  216 
  217     free(work);
  218     free(parsed);
  219     fclose(ttable_file);
  220 
  221     return table;
  222 }