"Fossies" - the Fresh Open Source Software Archive

Member "ffe-0.3.9/src/level.c" (6 Sep 2015, 6044 Bytes) of package /linux/privat/ffe-0.3.9.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 "level.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  *    ffe - flat file extractor
    3  *
    4  *    Copyright (C) 2006 Timo Savinen
    5  *    This file is part of ffe.
    6  * 
    7  *    ffe is free software; you can redistribute it and/or modify
    8  *    it under the terms of the GNU General Public License as published by
    9  *    the Free Software Foundation; either version 2 of the License, or
   10  *    (at your option) any later version.
   11  *
   12  *    ffe is distributed in the hope that it will be useful,
   13  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
   14  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15  *    GNU General Public License for more details.
   16  *
   17  *    You should have received a copy of the GNU General Public License
   18  *    along with ffe; if not, write to the Free Software
   19  *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   20  *
   21  */
   22 
   23 /* $Id: level.c,v 1.8 2010-09-24 11:45:16 timo Exp $ */
   24 
   25 #include "ffe.h"
   26 #include <string.h>
   27 
   28 static struct level *levels[MAXLEVEL + 1];
   29 static int last_level = 0;
   30 static int max_level = 0;
   31 
   32 void
   33 reset_levels(int start, int stop)
   34 {
   35     while(start <= stop) levels[start++] = NULL;
   36 }
   37 
   38 static void
   39 print_level_text(struct level *l,uint8_t *buffer)
   40 {
   41     register uint8_t *text = buffer;
   42 
   43     if(!buffer) return;
   44     start_write();
   45     while(*text)
   46     {
   47         if(*text == '%' && text[1])
   48         {
   49             text++;
   50             switch(*text)
   51             {
   52                 case 'g':
   53                     if(l) writes(l->group_name);
   54                     break;
   55                 case 'm':
   56                     if(l) writes(l->element_name);
   57                     break;
   58                 case '%':
   59                     writec('%');
   60                     break;
   61                 default:
   62                     writec('%');
   63                     writec(*text);
   64                     break;
   65             }
   66         } else
   67         {
   68             writec(*text);
   69         }
   70         text++;
   71     }
   72     flush_write();
   73 }
   74 
   75 
   76 
   77 static 
   78 void print_level(struct level *l, uint8_t *buffer, uint8_t *indent, int indent_level)
   79 {
   80     if(!l) return;
   81 
   82     if(indent) print_indent(indent,indent_level);
   83 
   84     print_level_text(l,buffer);
   85 }
   86 
   87 int
   88 get_indent_depth(int level_count)
   89 {
   90     register int i,depth = 1;
   91 
   92     for(i = 1;i <= level_count;i++) depth += (levels[i] != NULL ? levels[i]->indent_count : 0);
   93 
   94     return depth;
   95 }
   96 
   97 /* Print group and element level headers/trailers BEFORE an element is printed
   98 */
   99 void
  100 print_level_before(struct record *prev_record, struct record *curr_record)
  101 {
  102     int pl = 0,i;
  103 
  104     if(!curr_record->level)
  105     {
  106         if(prev_record && prev_record->level && prev_record->level->element_name)
  107             print_level(prev_record->level,prev_record->o->element_trailer,prev_record->o->indent,get_indent_depth(prev_record->level->level) -  1);
  108         return;
  109     }
  110 
  111     if(curr_record->level->level > max_level) max_level = curr_record->level->level;
  112     last_level = curr_record->level->level;
  113 
  114     if(prev_record && prev_record->level) pl = prev_record->level->level;
  115 
  116     if(last_level == pl) // in the same level
  117     {
  118         if(prev_record->level->element_name)
  119             print_level(prev_record->level,prev_record->o->element_trailer,prev_record->o->indent,get_indent_depth(pl) -  1);
  120 
  121         if((prev_record->level->group_name && curr_record->level->group_name &&
  122             strcmp(prev_record->level->group_name,curr_record->level->group_name) != 0) ||
  123            (!prev_record->level->group_name || !curr_record->level->group_name))
  124         {
  125             if(prev_record->level->group_name) 
  126                 print_level(prev_record->level,prev_record->o->group_trailer,prev_record->o->indent,get_indent_depth(pl - 1));
  127             if(curr_record->level->group_name) 
  128                 print_level(curr_record->level,curr_record->o->group_header,curr_record->o->indent,get_indent_depth(last_level - 1)); 
  129         }
  130     } else if(last_level > pl) // current record is deeper in as previous
  131     {
  132         if(curr_record->level->group_name)
  133             print_level(curr_record->level,curr_record->o->group_header,curr_record->o->indent,get_indent_depth(pl));
  134     } else if(last_level < pl) // current record is higher as previous, print trailers for elements between current and previous
  135     {
  136         i = pl;
  137         while(i >= last_level)
  138         {
  139             if(levels[i] && levels[i]->element_name)
  140                 print_level(levels[i],curr_record->o->element_trailer,curr_record->o->indent,get_indent_depth(i) - 1);
  141             if(i > last_level && levels[i] && levels[i]->group_name)
  142                 print_level(levels[i],curr_record->o->group_trailer,curr_record->o->indent,get_indent_depth(i - 1));
  143             i--;
  144         }
  145 
  146         i++;
  147 
  148         if(levels[i] && ((levels[i]->group_name && curr_record->level->group_name && strcmp(levels[i]->group_name,curr_record->level->group_name) != 0) ||
  149            (!levels[i]->group_name || !curr_record->level->group_name)))
  150         {
  151             if(levels[i]->group_name) 
  152                 print_level(levels[i],curr_record->o->group_trailer,curr_record->o->indent,get_indent_depth(i - 1));
  153             if(curr_record->level->group_name) 
  154                 print_level(curr_record->level,curr_record->o->group_header,curr_record->o->indent,get_indent_depth(last_level - 1)); 
  155         }
  156 
  157         reset_levels(last_level + 1,max_level);
  158     }
  159     
  160     levels[last_level] = curr_record->level;
  161 
  162     if(curr_record->level->element_name)
  163         print_level(curr_record->level,curr_record->o->element_header,curr_record->o->indent,get_indent_depth(last_level) - 1);
  164 }
  165 
  166 /* print pending trailers after all data has been read
  167  */
  168 void
  169 print_level_end(struct record *last)
  170 {
  171         int i = last_level;
  172 
  173         while(levels[i] && i >= 1)
  174         {
  175             if(levels[i]->element_name)
  176                 print_level(levels[i],last->o->element_trailer,last->o->indent,get_indent_depth(i) - 1);
  177             if(levels[i]->group_name)
  178                 print_level(levels[i],last->o->group_trailer,last->o->indent,get_indent_depth(i - 1));
  179             i--;
  180         }
  181 }