exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

taler_amount_lib.h (20744B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2014, 2015, 2020 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU General Public License as published by the Free Software
      7   Foundation; either version 3, or (at your option) any later version.
      8 
      9   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     10   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12 
     13   You should have received a copy of the GNU General Public License along with
     14   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @file include/taler/taler_amount_lib.h
     18  * @brief amount-representation utility functions
     19  * @author Sree Harsha Totakura <sreeharsha@totakura.in>
     20  */
     21 #if ! defined (__TALER_UTIL_LIB_H_INSIDE__)
     22 #error "Only <taler_util.h> can be included directly."
     23 #endif
     24 
     25 #ifndef TALER_AMOUNT_LIB_H
     26 #define TALER_AMOUNT_LIB_H
     27 
     28 #include <stdint.h>
     29 #include <gnunet/gnunet_common.h>
     30 
     31 #ifdef __cplusplus
     32 extern "C"
     33 {
     34 #if 0                           /* keep Emacsens' auto-indent happy */
     35 }
     36 #endif
     37 #endif
     38 
     39 
     40 /**
     41  * @brief Number of characters (plus 1 for 0-termination) we use to
     42  * represent currency names (i.e. EUR, USD, etc.).  We use 8+4 for
     43  * alignment in the `struct TALER_Amount`.  The amount is typically an
     44  * ISO 4217 currency code when an alphanumeric 3-digit code is used.
     45  * For regional currencies, the first character should be a "*" followed
     46  * by a region-specific name (i.e. "*BRETAGNEFR").
     47  */
     48 #define TALER_CURRENCY_LEN 12
     49 
     50 /**
     51  * Taler currency length as a string.
     52  */
     53 #define TALER_CURRENCY_LEN_STR "12"
     54 
     55 /**
     56  * @brief The "fraction" value in a `struct TALER_Amount` represents which
     57  * fraction of the "main" value?
     58  *
     59  * Note that we need sub-cent precision here as transaction fees might
     60  * be that low, and as we want to support microdonations.
     61  *
     62  * An actual `struct Amount a` thus represents
     63  * "a.value + (a.fraction / #TALER_AMOUNT_FRAC_BASE)" units of "a.currency".
     64  */
     65 #define TALER_AMOUNT_FRAC_BASE 100000000
     66 
     67 /**
     68  * @brief How many digits behind the comma are required to represent the
     69  * fractional value in human readable decimal format?  Must match
     70  * lg(#TALER_AMOUNT_FRAC_BASE).
     71  */
     72 #define TALER_AMOUNT_FRAC_LEN 8
     73 
     74 /**
     75  * Maximum legal 'value' for an amount, based on IEEE double (for JavaScript compatibility).
     76  */
     77 #define TALER_AMOUNT_MAX_VALUE (1LLU << 52)
     78 
     79 
     80 GNUNET_NETWORK_STRUCT_BEGIN
     81 
     82 
     83 /**
     84  * @brief Amount, encoded for network transmission.
     85  */
     86 struct TALER_AmountNBO
     87 {
     88   /**
     89    * Value in the main currency, in NBO.
     90    */
     91   uint64_t value GNUNET_PACKED;
     92 
     93   /**
     94    * Fraction (integer multiples of #TALER_AMOUNT_FRAC_BASE), in NBO.
     95    */
     96   uint32_t fraction GNUNET_PACKED;
     97 
     98   /**
     99    * Type of the currency being represented.
    100    */
    101   char currency[TALER_CURRENCY_LEN];
    102 };
    103 
    104 GNUNET_NETWORK_STRUCT_END
    105 
    106 
    107 /**
    108  * @brief Representation of monetary value in a given currency.
    109  */
    110 struct TALER_Amount
    111 {
    112   /**
    113    * Value (numerator of fraction)
    114    */
    115   uint64_t value;
    116 
    117   /**
    118    * Fraction (integer multiples of #TALER_AMOUNT_FRAC_BASE).
    119    */
    120   uint32_t fraction;
    121 
    122   /**
    123    * Currency string, left adjusted and padded with zeros.  All zeros
    124    * for "invalid" values.
    125    */
    126   char currency[TALER_CURRENCY_LEN];
    127 };
    128 
    129 
    130 /**
    131  * Check that the currency code in @a str is well-formed.
    132  *
    133  * @param str currency code name to validate
    134  * @return #GNUNET_OK if @a str is a valid currency code
    135  */
    136 enum GNUNET_GenericReturnValue
    137 TALER_check_currency (const char *str);
    138 
    139 
    140 /**
    141  * Parse monetary amount, in the format "T:V.F".
    142  *
    143  * @param str amount string
    144  * @param[out] amount amount to write the result to
    145  * @return #GNUNET_OK if the string is a valid monetary amount specification,
    146  *         #GNUNET_SYSERR if it is invalid.
    147  */
    148 enum GNUNET_GenericReturnValue
    149 TALER_string_to_amount (const char *str,
    150                         struct TALER_Amount *amount);
    151 
    152 
    153 /**
    154  * Parse monetary amount, in the format "T:V.F".
    155  * The result is stored in network byte order (NBO).
    156  *
    157  * @param str amount string
    158  * @param[out] amount_nbo amount to write the result to
    159  * @return #GNUNET_OK if the string is a valid amount specification,
    160  *         #GNUNET_SYSERR if it is invalid.
    161  */
    162 enum GNUNET_GenericReturnValue
    163 TALER_string_to_amount_nbo (const char *str,
    164                             struct TALER_AmountNBO *amount_nbo);
    165 
    166 
    167 /**
    168  * Get the value of "zero" in a particular currency.
    169  *
    170  * @param cur currency description
    171  * @param[out] amount amount to write the result to
    172  * @return #GNUNET_OK if @a cur is a valid currency specification,
    173  *         #GNUNET_SYSERR if it is invalid.
    174  */
    175 enum GNUNET_GenericReturnValue
    176 TALER_amount_set_zero (const char *cur,
    177                        struct TALER_Amount *amount);
    178 
    179 
    180 /**
    181  * Test if the given @a amount is zero.
    182  *
    183  * @param amount amount to compare to zero
    184  * @return true if the amount is zero,
    185  *         false if it is non-zero or invalid
    186  */
    187 bool
    188 TALER_amount_is_zero (const struct TALER_Amount *amount);
    189 
    190 
    191 /**
    192  * Test if the given amount is valid.
    193  *
    194  * @param amount amount to check
    195  * @return #GNUNET_OK if @a amount is valid
    196  */
    197 enum GNUNET_GenericReturnValue
    198 TALER_amount_is_valid (const struct TALER_Amount *amount);
    199 
    200 
    201 /**
    202  * Test if the given amount is in the given currency
    203  *
    204  * @param amount amount to check
    205  * @param currency currency to check for
    206  * @return #GNUNET_OK if @a amount is in @a currency
    207  */
    208 enum GNUNET_GenericReturnValue
    209 TALER_amount_is_currency (const struct TALER_Amount *amount,
    210                           const char *currency);
    211 
    212 
    213 /**
    214  * Convert amount from host to network representation.
    215  *
    216  * @param[out] res where to store amount in network representation
    217  * @param d amount in host representation
    218  */
    219 void
    220 TALER_amount_hton (struct TALER_AmountNBO *res,
    221                    const struct TALER_Amount *d);
    222 
    223 
    224 /**
    225  * Convert amount from network to host representation.
    226  *
    227  * @param[out] res where to store amount in host representation
    228  * @param dn amount in network representation
    229  */
    230 void
    231 TALER_amount_ntoh (struct TALER_Amount *res,
    232                    const struct TALER_AmountNBO *dn);
    233 
    234 
    235 /**
    236  * Compare the value/fraction of two amounts.  Does not compare the currency.
    237  * Comparing amounts of different currencies will cause the program to abort().
    238  * If unsure, check with #TALER_amount_cmp_currency() first to be sure that
    239  * the currencies of the two amounts are identical.
    240  *
    241  * @param a1 first amount
    242  * @param a2 second amount
    243  * @return result of the comparison
    244  *         -1 if `a1 < a2`
    245  *          1 if `a1 > a2`
    246  *          0 if `a1 == a2`.
    247  */
    248 int
    249 TALER_amount_cmp (const struct TALER_Amount *a1,
    250                   const struct TALER_Amount *a2);
    251 
    252 
    253 /**
    254  * Compute maximum of two amounts.
    255  *
    256  * @param[out] ma set to maximum of @a a1 and @a a2
    257  * @param a1 first amount
    258  * @param a2 second amount
    259  * @return #GNUNET_OK on success
    260  */
    261 enum GNUNET_GenericReturnValue
    262 TALER_amount_max (struct TALER_Amount *ma,
    263                   const struct TALER_Amount *a1,
    264                   const struct TALER_Amount *a2);
    265 
    266 
    267 /**
    268  * Compute minimum of two amounts.
    269  *
    270  * @param[out] mi set to minimum of @a a1 and @a a2
    271  * @param a1 first amount
    272  * @param a2 second amount
    273  * @return #GNUNET_OK on success
    274  */
    275 enum GNUNET_GenericReturnValue
    276 TALER_amount_min (struct TALER_Amount *mi,
    277                   const struct TALER_Amount *a1,
    278                   const struct TALER_Amount *a2);
    279 
    280 
    281 /**
    282  * Compare the value/fraction of two amounts.  Does not compare the currency.
    283  * Comparing amounts of different currencies will cause the program to abort().
    284  * If unsure, check with #TALER_amount_cmp_currency() first to be sure that
    285  * the currencies of the two amounts are identical. NBO variant.
    286  *
    287  * @param a1 first amount
    288  * @param a2 second amount
    289  * @return result of the comparison
    290  *         -1 if `a1 < a2`
    291  *          1 if `a1 > a2`
    292  *          0 if `a1 == a2`.
    293  */
    294 int
    295 TALER_amount_cmp_nbo (const struct TALER_AmountNBO *a1,
    296                       const struct TALER_AmountNBO *a2);
    297 
    298 
    299 /**
    300  * Test if @a a1 and @a a2 are the same currency.
    301  *
    302  * @param a1 amount to test
    303  * @param a2 amount to test
    304  * @return #GNUNET_YES if @a a1 and @a a2 are the same currency
    305  *         #GNUNET_NO if the currencies are different
    306  *         #GNUNET_SYSERR if either amount is invalid
    307  */
    308 enum GNUNET_GenericReturnValue
    309 TALER_amount_cmp_currency (const struct TALER_Amount *a1,
    310                            const struct TALER_Amount *a2);
    311 
    312 
    313 /**
    314  * Test if @a a1 and @a a2 are the same currency, NBO variant.
    315  *
    316  * @param a1 amount to test
    317  * @param a2 amount to test
    318  * @return #GNUNET_YES if @a a1 and @a a2 are the same currency
    319  *         #GNUNET_NO if the currencies are different
    320  *         #GNUNET_SYSERR if either amount is invalid
    321  */
    322 enum GNUNET_GenericReturnValue
    323 TALER_amount_cmp_currency_nbo (const struct TALER_AmountNBO *a1,
    324                                const struct TALER_AmountNBO *a2);
    325 
    326 
    327 /**
    328  * Possible results from calling #TALER_amount_subtract() and
    329  * possibly other arithmetic operations. Negative values
    330  * indicate that the operation did not generate a result.
    331  */
    332 enum TALER_AmountArithmeticResult
    333 {
    334 
    335   /**
    336    * Operation succeeded, result is positive.
    337    */
    338   TALER_AAR_RESULT_POSITIVE = 1,
    339 
    340   /**
    341    * Operation succeeded, result is exactly zero.
    342    */
    343   TALER_AAR_RESULT_ZERO = 0,
    344 
    345   /**
    346    * Operation failed, the result would have been negative.
    347    */
    348   TALER_AAR_INVALID_NEGATIVE_RESULT = -1,
    349 
    350   /**
    351    * Operation failed, result outside of the representable range.
    352    */
    353   TALER_AAR_INVALID_RESULT_OVERFLOW = -2,
    354 
    355   /**
    356    * Operation failed, inputs could not be normalized.
    357    */
    358   TALER_AAR_INVALID_NORMALIZATION_FAILED = -3,
    359 
    360   /**
    361    * Operation failed, input currencies were not identical.
    362    */
    363   TALER_AAR_INVALID_CURRENCIES_INCOMPATIBLE = -4
    364 
    365 };
    366 
    367 /**
    368  * Perform saturating subtraction of amounts.
    369  *
    370  * @param[out] diff where to store (@a a1 - @a a2), or invalid if @a a2 > @a a1
    371  * @param a1 amount to subtract from
    372  * @param a2 amount to subtract
    373  * @return operation status, negative on failures
    374  */
    375 enum TALER_AmountArithmeticResult
    376 TALER_amount_subtract (struct TALER_Amount *diff,
    377                        const struct TALER_Amount *a1,
    378                        const struct TALER_Amount *a2);
    379 
    380 
    381 /**
    382  * Perform addition of amounts.
    383  *
    384  * @param[out] sum where to store @a a1 + @a a2, set to "invalid" on overflow
    385  * @param a1 first amount to add
    386  * @param a2 second amount to add
    387  * @return operation status, negative on failures
    388  */
    389 enum TALER_AmountArithmeticResult
    390 TALER_amount_add (struct TALER_Amount *sum,
    391                   const struct TALER_Amount *a1,
    392                   const struct TALER_Amount *a2);
    393 
    394 
    395 /**
    396  * Divide an amount by a @ divisor.  Note that this function
    397  * may introduce a rounding error!
    398  *
    399  * @param[out] result where to store @a dividend / @a divisor
    400  * @param dividend amount to divide
    401  * @param divisor by what to divide, must be positive
    402  */
    403 void
    404 TALER_amount_divide (struct TALER_Amount *result,
    405                      const struct TALER_Amount *dividend,
    406                      uint32_t divisor);
    407 
    408 /**
    409  * Divide one amount by another.  Note that this function
    410  * may introduce a rounding error. It rounds down.
    411  *
    412  * @param dividend amount to divide
    413  * @param divisor by what to divide, must be positive
    414  * @return @a dividend / @a divisor, rounded down. -1 on currency mismatch,
    415  *         INT_MAX for division by zero
    416  */
    417 int
    418 TALER_amount_divide2 (const struct TALER_Amount *dividend,
    419                       const struct TALER_Amount *divisor);
    420 
    421 
    422 /**
    423  * Multiply an @a amount by a @ factor.
    424  *
    425  * @param[out] result where to store @a amount * @a factor
    426  * @param amount amount to multiply
    427  * @param factor factor by which to multiply
    428  */
    429 enum TALER_AmountArithmeticResult
    430 TALER_amount_multiply (struct TALER_Amount *result,
    431                        const struct TALER_Amount *amount,
    432                        uint32_t factor);
    433 
    434 
    435 /**
    436  * Normalize the given amount.
    437  *
    438  * @param[in,out] amount amount to normalize
    439  * @return #GNUNET_OK if normalization worked
    440  *         #GNUNET_NO if value was already normalized
    441  *         #GNUNET_SYSERR if value was invalid or could not be normalized
    442  */
    443 enum GNUNET_GenericReturnValue
    444 TALER_amount_normalize (struct TALER_Amount *amount);
    445 
    446 
    447 /**
    448  * Convert amount to string.
    449  *
    450  * @param amount amount to convert to string
    451  * @return freshly allocated string representation,
    452  *         NULL if the @a amount was invalid
    453  */
    454 char *
    455 TALER_amount_to_string (const struct TALER_Amount *amount);
    456 
    457 
    458 /**
    459  * Convert amount to string.
    460  *
    461  * @param amount amount to convert to string
    462  * @return statically allocated buffer with string representation,
    463  *         NULL if the @a amount was invalid
    464  */
    465 const char *
    466 TALER_amount2s (const struct TALER_Amount *amount);
    467 
    468 
    469 /**
    470  * Round the amount to something that can be transferred on the wire.
    471  * The rounding mode is specified via the smallest transferable unit,
    472  * which must only have a fractional part *or* only a value (either
    473  * of the two must be zero!).
    474  *
    475  * @param[in,out] amount amount to round down
    476  * @param[in] round_unit unit that should be rounded down to, and
    477  *            either value part or the faction must be zero (but not both)
    478  * @return #GNUNET_OK on success, #GNUNET_NO if rounding was unnecessary,
    479  *         #GNUNET_SYSERR if the amount or currency or @a round_unit was invalid
    480  */
    481 enum GNUNET_GenericReturnValue
    482 TALER_amount_round_down (struct TALER_Amount *amount,
    483                          const struct TALER_Amount *round_unit);
    484 
    485 
    486 /**
    487  * Represents a set of amounts in different currencies.
    488  * Useful when adding up various amounts in different
    489  * currencies.
    490  */
    491 struct TALER_AmountSet
    492 {
    493   /**
    494    * Array of amounts. Each currency should have at most one entry.
    495    */
    496   struct TALER_Amount *taa;
    497 
    498   /**
    499    * Length of the @e taa array.
    500    */
    501   unsigned int taa_size;
    502 
    503 };
    504 
    505 
    506 /**
    507  * Free memory allocated within @a as, but not @a as itself.
    508  * Effectively sets the total amount in @a as also back to zero.
    509  *
    510  * @param[in,out] as set to free (turned into an empty set)
    511  */
    512 void
    513 TALER_amount_set_free (struct TALER_AmountSet *as);
    514 
    515 
    516 /**
    517  * Add amount @a a to the total amount represented by @a as.
    518  *
    519  * @param[in,out] as set of amounts to update by adding @a a
    520  * @param val amount to add
    521  * @param cap cap for the sums to enforce, can be NULL;
    522  *   if given, then #TALER_AAR_INVALID_RESULT_OVERFLOW is impossible
    523  *   as we will use @a cap as a maximum value for this currency
    524  * @return operation status, negative on failures;
    525  *  #TALER_AAR_INVALID_CURRENCIES_INCOMPATIBLE is impossible,
    526  *  except if @a cap does not match @a val
    527  */
    528 enum TALER_AmountArithmeticResult
    529 TALER_amount_set_add (struct TALER_AmountSet *as,
    530                       const struct TALER_Amount *val,
    531                       const struct TALER_Amount *cap);
    532 
    533 
    534 /**
    535  * Test if the amount @a b is available in @a as, that is if
    536  * the total amount added to @a as in the currency of @a b
    537  * is not below @a b. In other words, returns true if
    538  * the available amount in @a as would suffice to pay for @a b.
    539  *
    540  * @param as set to compare
    541  * @param b amount to check if it falls into the range
    542  * @return true if b <= as(b.currency)
    543  */
    544 bool
    545 TALER_amount_set_test_above (const struct TALER_AmountSet *as,
    546                              const struct TALER_Amount *b);
    547 
    548 
    549 /**
    550  * Find amount by @a currency in @a as. If @a as is not
    551  * found, an amount of zero is returned in @a currency.
    552  * This function is not reentrant, repeated calls may
    553  * overwrite previously returned results.
    554  *
    555  * @param currency currency to search for
    556  * @param as set to search
    557  * @return NULL if @a currency is not a valid currency string
    558  */
    559 const struct TALER_Amount *
    560 TALER_amount_set_find (const char *currency,
    561                        const struct TALER_AmountSet *as);
    562 
    563 
    564 /**
    565  * A list of amounts in distinct currencies, all denoting the
    566  * same thing priced differently --- a price list.
    567  *
    568  * Do not confuse this with a `struct TALER_AmountSet`, which has the
    569  * same memory layout but the opposite invariants: a set is an
    570  * accumulator, a list is a price list.  In particular, a currency
    571  * that is absent from a list is *not offered*, which is distinct
    572  * from being offered at zero, and #TALER_amount_list_find() thus
    573  * returns NULL for it instead of synthesizing a zero amount.
    574  *
    575  * Each currency occurs at most once.  The order is significant:
    576  * the first entry is the primary currency.
    577  */
    578 struct TALER_AmountList
    579 {
    580   /**
    581    * Array of amounts, at most one per currency.
    582    */
    583   struct TALER_Amount *tal;
    584 
    585   /**
    586    * Length of the @e tal array.
    587    */
    588   unsigned int tal_len;
    589 
    590 };
    591 
    592 
    593 /**
    594  * Free memory allocated within @a al, but not @a al itself.
    595  *
    596  * @param[in,out] al list to free (turned into an empty list)
    597  */
    598 void
    599 TALER_amount_list_free (struct TALER_AmountList *al);
    600 
    601 
    602 /**
    603  * Parse a price list of the form "EUR:1.1;CHF:1;USD:2".
    604  *
    605  * Fails if any component is empty or not a valid amount, or if a
    606  * currency is given more than once.  The empty string parses into
    607  * the empty list, which is the canonical way to say "free".
    608  *
    609  * @param str string to parse
    610  * @param[out] al list to initialize, only modified on success;
    611  *             the caller must eventually free it using
    612  *             #TALER_amount_list_free()
    613  * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
    614  */
    615 enum GNUNET_GenericReturnValue
    616 TALER_string_to_amount_list (const char *str,
    617                              struct TALER_AmountList *al);
    618 
    619 
    620 /**
    621  * Convert the price list @a al to a string, the inverse of
    622  * #TALER_string_to_amount_list().  This function is not reentrant,
    623  * repeated calls may overwrite previously returned results.
    624  *
    625  * @param al list to convert
    626  * @return statically allocated buffer with the string representation,
    627  *         NULL if any amount in @a al was invalid
    628  */
    629 const char *
    630 TALER_amount_list2s (const struct TALER_AmountList *al);
    631 
    632 
    633 /**
    634  * Find the price in @a currency in the price list @a al.
    635  *
    636  * Deliberately unlike #TALER_amount_set_find(), a currency that
    637  * @a al does not offer yields NULL and not a zero amount: for a
    638  * price list, "not offered" and "free" are different answers, and
    639  * confusing them would make an unpriced currency look free.
    640  *
    641  * @param al list to search
    642  * @param currency currency to search for
    643  * @return NULL if @a al does not offer @a currency
    644  */
    645 const struct TALER_Amount *
    646 TALER_amount_list_find (const struct TALER_AmountList *al,
    647                         const char *currency);
    648 
    649 
    650 /**
    651  * Check that @a al prices uniformly, that is that it does not
    652  * offer the same thing for free in one currency and for money in
    653  * another.
    654  *
    655  * @param al list to check
    656  * @return #GNUNET_OK if every entry is non-zero (a real price),
    657  *         #GNUNET_NO if every entry is zero or @a al is empty (free),
    658  *         #GNUNET_SYSERR if some entries are zero and others are not
    659  */
    660 enum GNUNET_GenericReturnValue
    661 TALER_amount_list_check_uniform (const struct TALER_AmountList *al);
    662 
    663 
    664 /**
    665  * Check that @a al prices in exactly the @a currencies_len
    666  * currencies given in @a currencies, no more and no fewer.
    667  *
    668  * @param al list to check
    669  * @param currencies array of currency names that must be covered
    670  * @param currencies_len length of the @a currencies array
    671  * @return true if @a al holds exactly one entry per currency
    672  *         in @a currencies and no others
    673  */
    674 bool
    675 TALER_amount_list_covers (const struct TALER_AmountList *al,
    676                           const char *const *currencies,
    677                           unsigned int currencies_len);
    678 
    679 
    680 /**
    681  * Multiply every price in @a al by @a n, for example to turn a
    682  * per-year price into the price of @a n years.
    683  *
    684  * Either all currencies are updated or none is: an overflow in any
    685  * one of them fails the entire call and leaves @a al untouched.
    686  *
    687  * @param[in,out] al list to multiply in place
    688  * @param n factor to multiply by, must not be zero (zero would turn
    689  *          a priced list into a free one, which is never intended)
    690  * @return #GNUNET_OK on success,
    691  *         #GNUNET_SYSERR on overflow or if @a n is zero
    692  */
    693 enum GNUNET_GenericReturnValue
    694 TALER_amount_list_multiply (struct TALER_AmountList *al,
    695                             uint32_t n);
    696 
    697 
    698 /**
    699  * Make a deep copy of the price list @a src.
    700  *
    701  * @param[out] dst list to initialize, must not hold anything yet;
    702  *             the caller must eventually free it using
    703  *             #TALER_amount_list_free()
    704  * @param src list to copy
    705  */
    706 void
    707 TALER_amount_list_copy (struct TALER_AmountList *dst,
    708                         const struct TALER_AmountList *src);
    709 
    710 
    711 #if 0                           /* keep Emacsens' auto-indent happy */
    712 {
    713 #endif
    714 #ifdef __cplusplus
    715 }
    716 #endif
    717 
    718 
    719 #endif