LTP GCOV extension - code coverage report
Current view: directory - usr/include/tagcoll-2.0.11/tagcoll - TextFormat.tcc
Test: lcov.info
Date: 2008-08-14 Instrumented lines: 79
Code covered: 54.4 % Executed lines: 43

       1                 : /*
       2                 :  * Serialize a tagged collection to a text file
       3                 :  *
       4                 :  * Copyright (C) 2003--2008  Enrico Zini <enrico@debian.org>
       5                 :  *
       6                 :  * This library is free software; you can redistribute it and/or
       7                 :  * modify it under the terms of the GNU Lesser General Public
       8                 :  * License as published by the Free Software Foundation; either
       9                 :  * version 2.1 of the License, or (at your option) any later version.
      10                 :  *
      11                 :  * This library is distributed in the hope that it will be useful,
      12                 :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13                 :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14                 :  * Lesser General Public License for more details.
      15                 :  *
      16                 :  * You should have received a copy of the GNU Lesser General Public
      17                 :  * License along with this library; if not, write to the Free Software
      18                 :  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
      19                 :  */
      20                 : 
      21                 : #ifndef TAGCOLL_TEXTFORMAT_TCC
      22                 : #define TAGCOLL_TEXTFORMAT_TCC
      23                 : 
      24                 : #include <tagcoll/TextFormat.h>
      25                 : #include <tagcoll/patch.h>
      26                 : 
      27                 : #include <wibble/exception.h>
      28                 : #include <wibble/empty.h>
      29                 : #include <wibble/operators.h>
      30                 : 
      31                 : #include <ostream>
      32                 : 
      33                 : using namespace std;
      34                 : using namespace wibble;
      35                 : using namespace wibble::operators;
      36                 : 
      37               0 : static void printTagset(const std::set<string>& ts, FILE* out)
      38                 : {
      39               0 :         for (std::set<string>::const_iterator i = ts.begin();
      40                 :                         i != ts.end(); i++)
      41               0 :                 if (i == ts.begin())
      42                 :                 {
      43               0 :                         if (fprintf(out, "%s", i->c_str()) < 0)
      44               0 :                                 throw wibble::exception::System("writing tagset");
      45                 :                 }
      46                 :                 else
      47                 :                 {
      48               0 :                         if (fprintf(out, ", %s", i->c_str()) < 0)
      49               0 :                                 throw wibble::exception::System("writing tagset");
      50                 :                 }
      51               0 : }
      52                 : 
      53                 : namespace tagcoll {
      54                 : namespace textformat {
      55                 : 
      56          126871 : inline static void outString(const std::string& str, FILE* out, const char* what)
      57                 : {
      58          126871 :         if (fwrite(str.data(), str.size(), 1, out) != 1)
      59               0 :                 throw wibble::exception::System(string("writing ") + what);
      60          126871 : }
      61                 : 
      62                 : template<typename Items, typename Tags>
      63           21145 : StdioWriter& StdioWriter::operator=(const std::pair<Items, Tags>& data)
      64                 : {
      65           42290 :         for (typename Items::const_iterator i = data.first.begin();
      66                 :                         i != data.first.end(); ++i)
      67                 :         {
      68           21145 :                 if (i != data.first.begin())
      69               0 :                         if (fputs(", ", out) == EOF)
      70               0 :                                 throw wibble::exception::System("writing comma after item");
      71           21145 :                 outString(*i, out, "item");
      72                 :         }
      73           21145 :         if (data.second.begin() != data.second.end())
      74                 :         {
      75           21145 :                 if (fputs(": ", out) == EOF)
      76               0 :                         throw wibble::exception::System("writing colon after items");
      77          126871 :                 for (typename Tags::const_iterator i = data.second.begin();
      78                 :                                 i != data.second.end(); ++i)
      79                 :                 {
      80          105726 :                         if (i != data.second.begin())
      81           84581 :                                 if (fputs(", ", out) == EOF)
      82               0 :                                         throw wibble::exception::System("writing comma after tag");
      83          105726 :                         outString(*i, out, "tag");
      84                 :                 }
      85                 :         }
      86           21145 :         if (fputc('\n', out) == EOF)
      87               0 :                 throw wibble::exception::System("writing newline after tagset");
      88           21145 :         return *this;
      89                 : }
      90                 : 
      91                 : template<typename Items, typename Tags>
      92                 : OstreamWriter& OstreamWriter::operator=(const std::pair<Items, Tags>& data)
      93                 : {
      94                 :         for (typename Items::const_iterator i = data.first.begin();
      95                 :                         i != data.first.end(); ++i)
      96                 :         {
      97                 :                 if (i != data.first.begin())
      98                 :                         out << ", ";
      99                 :                 out << *i;
     100                 :         }
     101                 :         if (data.second.begin() != data.second.end())
     102                 :         {
     103                 :                 out << ": ";
     104                 :                 for (typename Tags::const_iterator i = data.second.begin();
     105                 :                                 i != data.second.end(); ++i)
     106                 :                 {
     107                 :                         if (i != data.second.begin())
     108                 :                                 out << ", ";
     109                 :                         out << *i;
     110                 :                 }
     111                 :         }
     112                 :         out << endl;
     113                 :         return *this;
     114                 : }
     115                 : 
     116                 : 
     117                 : 
     118                 : // item1, item2, item3: tag1, tag2, tag3
     119                 : 
     120                 : //#define TRACE_PARSE
     121                 : template<typename OUT>
     122               2 : void parse(input::Input& in, OUT out)
     123                 : {
     124               2 :         string item;
     125                 : 
     126               2 :         std::set<string> itemset;
     127               2 :         std::set<string> tagset;
     128                 :         int sep;
     129               2 :         enum {ITEMS, TAGS} state = ITEMS;
     130               2 :         int line = 1;
     131          253744 :         do
     132                 :         {
     133                 :                 try {
     134          253744 :                         sep = parseElement(in, item);
     135               0 :                 } catch (tagcoll::exception::Parser& e) {
     136                 :                         // Add the line number and propagate
     137               0 :                         e.line(line);
     138               0 :                         throw e;
     139                 :                 }
     140                 :                 
     141          507488 :                 if (item.size() != 0)
     142                 :                 {
     143          253742 :                         if (state == ITEMS)
     144           42290 :                                 itemset |= item;
     145                 :                         else
     146          211452 :                                 tagset |= item;
     147                 :                 }
     148                 :                 
     149          253744 :                 switch (sep)
     150                 :                 {
     151                 :                         case '\n':
     152           42290 :                                 line++;
     153                 :                         case input::Input::Eof:
     154           42292 :                                 if (!(itemset.empty() && tagset.empty()))
     155                 :                                 {
     156           42290 :                                         if (itemset.empty())
     157               0 :                                                 throw tagcoll::exception::Input(line, "no elements before `:' separator");
     158           42290 :                                         if (tagset.empty())
     159               0 :                                                 *out = make_pair(itemset, wibble::Empty<std::string>());
     160                 :                                         else
     161           42290 :                                                 *out = make_pair(itemset, tagset);
     162           42290 :                                         ++out;
     163                 :                                 }
     164           42292 :                                 itemset.clear();
     165           42292 :                                 tagset.clear();
     166           42292 :                                 state = ITEMS;
     167           42292 :                                 break;
     168                 :                         case ':':
     169           42290 :                                 if (state == TAGS)
     170               0 :                                         throw tagcoll::exception::Input(line, "separator `:' appears twice");
     171           42290 :                                 state = TAGS;
     172                 :                                 break;
     173                 :                         default:
     174               2 :                                 break;
     175                 :                 }
     176                 :         } while (sep != input::Input::Eof);
     177               2 : }
     178                 : 
     179                 : template<typename OUT> template<typename ITEMS, typename TAGS>
     180               0 : PatchAssembler<OUT>& PatchAssembler<OUT>::operator=(const std::pair<ITEMS, TAGS>& data)
     181                 : {
     182               0 :         std::set<std::string> added;
     183               0 :         std::set<std::string> removed;
     184                 : 
     185               0 :         for (typename TAGS::const_iterator i = data.second.begin();
     186                 :                         i != data.second.end(); ++i)
     187                 :         {
     188               0 :                 std::string tag = i->substr(1);
     189               0 :                 if (!tag.empty())
     190                 :                 {
     191               0 :                         if ((*i)[0] == '-')
     192               0 :                                 removed.insert(tag);
     193               0 :                         else if ((*i)[0] == '+')
     194               0 :                                 added.insert(tag);
     195                 :                 }
     196                 :         }
     197                 : 
     198               0 :         for (typename ITEMS::const_iterator i = data.first.begin();
     199                 :                         i != data.first.end(); ++i)
     200                 :         {
     201               0 :                 std::string it = *i;
     202               0 :                 if (!it.empty())
     203                 :                 {
     204               0 :                         *out = Patch<std::string, std::string>(it, added, removed);
     205               0 :                         ++out;
     206                 :                 }
     207                 :         }
     208               0 :         return *this;
     209                 : }
     210                 : 
     211                 : 
     212                 : 
     213                 : template<typename ITEM, typename TAG, typename ITEMSER, typename TAGSER>
     214                 : void outputPatch(
     215                 :                 ITEMSER& itemconv,
     216                 :                 TAGSER& tagconv,
     217                 :                 const PatchList<ITEM, TAG>& patch,
     218                 :                 FILE* out)
     219                 : {
     220                 :         for (typename PatchList<ITEM, TAG>::const_iterator i = patch.begin();
     221                 :                         i != patch.end(); i++)
     222                 :         {
     223                 :                 string sitem = itemconv(i->first);
     224                 :                 if (fprintf(out, "%s: ", sitem.c_str()) < 0)
     225                 :                         throw wibble::exception::System("writing item");
     226                 : 
     227                 :                 std::set<string> stags;
     228                 :                 for (typename std::set<TAG>::const_iterator j = i->second.added.begin();
     229                 :                                 j != i->second.added.end(); j++)
     230                 :                         stags |= "+"+tagconv(*j);
     231                 :                 for (typename std::set<TAG>::const_iterator j = i->second.removed.begin();
     232                 :                                 j != i->second.removed.end(); j++)
     233                 :                         stags |= "-"+tagconv(*j);
     234                 : 
     235                 :                 printTagset(stags, out);
     236                 :                 if (fprintf(out, "\n") < 0)
     237                 :                         throw wibble::exception::System("writing newline after tagset");
     238                 :         }
     239                 : }
     240                 : 
     241                 : template<typename ITEM, typename TAG, typename ITEMSER, typename TAGSER>
     242                 : template<typename ITEMS, typename TAGS>
     243                 : PatchBuilder<ITEM, TAG, ITEMSER, TAGSER>& PatchBuilder<ITEM, TAG, ITEMSER, TAGSER>::operator=(const std::pair<ITEMS, TAGS>& data)
     244                 : {
     245                 :         std::set<TAG> added;
     246                 :         std::set<TAG> removed;
     247                 : 
     248                 :         for (typename TAGS::const_iterator i = data.second.begin();
     249                 :                         i != data.second.end(); ++i)
     250                 :         {
     251                 :                 TAG tag = tagconv(i->substr(1));
     252                 :                 if (tag != TAG())
     253                 :                 {
     254                 :                         if ((*i)[0] == '-')
     255                 :                                 removed.insert(tag);
     256                 :                         else if ((*i)[0] == '+')
     257                 :                                 added.insert(tag);
     258                 :                 }
     259                 :         }
     260                 : 
     261                 :         for (typename ITEMS::const_iterator i = data.first.begin();
     262                 :                         i != data.first.end(); ++i)
     263                 :         {
     264                 :                 ITEM it = itemconv(*i);
     265                 :                 if (it != ITEM())
     266                 :                         patch.addPatch(Patch<ITEM, TAG>(it, added, removed));
     267                 :         }
     268                 :         return *this;
     269                 : }
     270                 : 
     271                 : 
     272                 : template<typename ITEM, typename TAG, typename ITEMSER, typename TAGSER>
     273                 : PatchList<ITEM, TAG> parsePatch(
     274                 :                 ITEMSER& itemconv,
     275                 :                 TAGSER& tagconv,
     276                 :                 input::Input& in)
     277                 : {
     278                 :         PatchList<ITEM, TAG> patch;
     279                 :         parse(in, patchBuilder(patch, itemconv, tagconv));
     280                 :         return patch;
     281                 : }
     282                 : 
     283                 : }
     284               6 : }
     285                 : 
     286                 : #include <tagcoll/patch.tcc>
     287                 : 
     288                 : #endif
     289                 : 
     290                 : // vim:set ts=4 sw=4:

Generated by: LTP GCOV extension version 1.6