LCOV - lcov.info - /usr/include/tagcoll-2.0.11/tagcoll/TextFormat.tcc

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