1 /* 2 * Copyright (c) 2003-2019, John Wiegley. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * - Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * - Neither the name of New Artisans LLC nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /** 33 * @defgroup data Data representation 34 */ 35 36 /** 37 * @file item.h 38 * @author John Wiegley 39 * 40 * @ingroup data 41 */ 42 #ifndef _ITEM_H 43 #define _ITEM_H 44 45 #include "scope.h" 46 47 namespace ledger { 48 49 struct position_t 50 { 51 path pathname; 52 std::istream::pos_type beg_pos; 53 std::size_t beg_line; 54 std::istream::pos_type end_pos; 55 std::size_t end_line; 56 std::size_t sequence; 57 position_tposition_t58 position_t() 59 : beg_pos(0), beg_line(0), end_pos(0), end_line(0), sequence(0) { 60 TRACE_CTOR(position_t, ""); 61 } position_tposition_t62 position_t(const position_t& pos) { 63 *this = pos; 64 TRACE_CTOR(position_t, "copy"); 65 } throwposition_t66 ~position_t() throw() { 67 TRACE_DTOR(position_t); 68 } 69 70 position_t& operator=(const position_t& pos) { 71 if (this != &pos) { 72 pathname = pos.pathname; 73 beg_pos = pos.beg_pos; 74 beg_line = pos.beg_line; 75 end_pos = pos.end_pos; 76 end_line = pos.end_line; 77 sequence = pos.sequence; 78 } 79 return *this; 80 } 81 }; 82 83 class item_t : public supports_flags<uint_least16_t>, public scope_t 84 { 85 public: 86 #define ITEM_NORMAL 0x00 // no flags at all, a basic posting 87 #define ITEM_GENERATED 0x01 // posting was not found in a journal 88 #define ITEM_TEMP 0x02 // posting is a managed temporary 89 #define ITEM_NOTE_ON_NEXT_LINE 0x04 // did we see a note on the next line? 90 91 enum state_t { UNCLEARED = 0, CLEARED, PENDING }; 92 93 typedef std::pair<optional<value_t>, bool> tag_data_t; 94 typedef std::map<string, tag_data_t, 95 std::function<bool(string, string)> > string_map; 96 97 state_t _state; 98 optional<date_t> _date; 99 optional<date_t> _date_aux; 100 optional<string> note; 101 optional<position_t> pos; 102 optional<string_map> metadata; 103 104 item_t(flags_t _flags = ITEM_NORMAL, const optional<string>& _note = none) 105 : supports_flags<uint_least16_t>(_flags), _state(UNCLEARED), note(_note) 106 { 107 TRACE_CTOR(item_t, "flags_t, const string&"); 108 } item_t(const item_t & item)109 item_t(const item_t& item) : supports_flags<uint_least16_t>(), scope_t() 110 { 111 copy_details(item); 112 TRACE_CTOR(item_t, "copy"); 113 } ~item_t()114 virtual ~item_t() { 115 TRACE_DTOR(item_t); 116 } 117 copy_details(const item_t & item)118 virtual void copy_details(const item_t& item) 119 { 120 set_flags(item.flags()); 121 set_state(item.state()); 122 123 _date = item._date; 124 _date_aux = item._date_aux; 125 note = item.note; 126 pos = item.pos; 127 metadata = item.metadata; 128 } 129 130 virtual bool operator==(const item_t& xact) { 131 return this == &xact; 132 } 133 virtual bool operator!=(const item_t& xact) { 134 return ! (*this == xact); 135 } 136 id()137 string id() const { 138 if (optional<value_t> ref = get_tag(_("UUID"))) { 139 return ref->to_string(); 140 } else { 141 std::ostringstream buf; 142 buf << seq(); 143 return buf.str(); 144 } 145 } seq()146 std::size_t seq() const { 147 return pos ? pos->sequence : 0L; 148 } 149 150 virtual bool has_tag(const string& tag, 151 bool inherit = true) const; 152 virtual bool has_tag(const mask_t& tag_mask, 153 const optional<mask_t>& value_mask = none, 154 bool inherit = true) const; 155 156 virtual optional<value_t> get_tag(const string& tag, 157 bool inherit = true) const; 158 virtual optional<value_t> get_tag(const mask_t& tag_mask, 159 const optional<mask_t>& value_mask = none, 160 bool inherit = true) const; 161 162 virtual string_map::iterator 163 set_tag(const string& tag, 164 const optional<value_t>& value = none, 165 const bool overwrite_existing = true); 166 167 virtual void parse_tags(const char * p, 168 scope_t& scope, 169 bool overwrite_existing = true); 170 virtual void append_note(const char * p, 171 scope_t& scope, 172 bool overwrite_existing = true); 173 174 static bool use_aux_date; 175 has_date()176 virtual bool has_date() const { 177 return static_cast<bool>(_date); 178 } 179 date()180 virtual date_t date() const { 181 assert(_date); 182 if (use_aux_date) 183 if (optional<date_t> aux = aux_date()) 184 return *aux; 185 return *_date; 186 } primary_date()187 virtual date_t primary_date() const { 188 assert(_date); 189 return *_date; 190 } aux_date()191 virtual optional<date_t> aux_date() const { 192 return _date_aux; 193 } 194 set_state(state_t new_state)195 void set_state(state_t new_state) { 196 _state = new_state; 197 } state()198 virtual state_t state() const { 199 return _state; 200 } 201 202 virtual void define(const symbol_t::kind_t, const string&, 203 expr_t::ptr_op_t); 204 virtual expr_t::ptr_op_t lookup(const symbol_t::kind_t kind, 205 const string& name); 206 207 bool valid() const; 208 }; 209 210 value_t get_comment(item_t& item); 211 void print_item(std::ostream& out, const item_t& item, 212 const string& prefix = ""); 213 string item_context(const item_t& item, const string& desc); 214 void put_metadata(property_tree::ptree& pt, const item_t::string_map& metadata); 215 216 } // namespace ledger 217 218 #endif // _ITEM_H 219