Skip to content

Commit

Permalink
lib: add xbps_fmt_* formatted printing functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Duncaen committed Feb 21, 2023
1 parent 48c3a82 commit 976132d
Show file tree
Hide file tree
Showing 3 changed files with 643 additions and 1 deletion.
172 changes: 172 additions & 0 deletions include/xbps.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -2365,6 +2365,178 @@ xbps_plist_dictionary_from_file(const char *path);

/**@}*/

/** @addtogroup format */
/**@{*/

/**
* @struct xbps_fmt xbps.h "xbps.h"
* @brief Structure of parsed format string.
*/
struct xbps_fmt;

/**
* @struct xbps_fmt xbps.h "xbps.h"
* @brief Structure of parsed format specifier.
*/
struct xbps_fmt_spec {
/**
* @var fill
* @brief Character to pad the output with.
*/
char fill;
/**
* @var align
* @brief Alignment modifier, can be `<`, `>` or `=`.
*
* Possible values are:
* - `<`: left align.
* - `>`: right align.
* - `=`: place padding after the sign.
*/
char align;
/**
* @var sign
* @brief Sign modifier can be `+`, `-` or a space.
*
* Possible values are:
* - `-`: sign negative numbers.
* - `+`: sign both negative and positive numbers.
* - space: sign negative numbers and add space before positive numbers.
*/
char sign;
/**
* @var width
* @brief Alignment width to pad the output to.
*/
unsigned int width;
/**
* @var prec
* @brief Precision of the output, usually for numbers.
*/
unsigned int prec;
/**
* @var type
* @brief Type specifier usually to change the output format type.
*
* Can contain any character, xbps_fmt_number() uses the following:
* - `u`: Unsigned decimal.
* - `d`: Decimal.
* - `x`: Hex with lowercase letters.
* - `X`: hex with uppercase letters.
* - `h`: Human readable using humanize_number(3).
*/
char type;
};

/**
* @brief Format callback, called for each variable in the format string.
*
* A callback function should write data associated with \a var to \a fp and use
* \a w as alignment specifier.
*
* @param[in] fp The file to print to.
* @param[in] spec The format specifier.
* @param[in] var The format string variable name.
* @param[in] data Userdata passed to the xbps_fmt() function.
*/
typedef int (xbps_fmt_cb)(FILE *fp, const struct xbps_fmt_spec *spec, const char *var, void *data);

/**
* @brief Parses the format string \a format.
*
* @param[in] format The format string.
*
* @return The parsed format structure, or NULL on error.
* The returned buffer must be freed with xbps_fmt_free().
* @retval EINVAL Invalid format string.
* @retval ERANGE Invalid alignment specifier.
* @retval ENOMEM Memory allocation failure.
*/
struct xbps_fmt *xbps_fmt_parse(const char *format);

/**
* @brief Releases memory associated with \a fmt.
*
* @param[in] fmt The format string.
*/
void xbps_fmt_free(struct xbps_fmt *fmt);

/**
* @brief Print formatted text to \a fp.
*
* @param[in] fmt Format returned by struct xbps_fmt_parse().
* @param[in] cb Callback function called for each variable in the format.
* @param[in] data Userdata passed to the callback \a cb.
* @param[in] fp File to print to.
*
* @return 0 on success or a negative errno.
* @retval 0 Success
*/
int xbps_fmt(const struct xbps_fmt *fmt, xbps_fmt_cb *cb, void *data, FILE *fp);

/**
* @brief Print formatted dictionary values to \a fp.
*
* Prints formatted dictionary values as specified by the parsed \a fmt
* format string to \a fp.
*
* @param[in] fmt Format returned by struct xbps_fmt_parse().
* @param[in] dict Dictionary to print values from.
* @param[in] fp File to print to.
*
* @return 0 on success or value returned by \a cb.
* @retval 0 Success
*/
int xbps_fmt_dictionary(const struct xbps_fmt *fmt, xbps_dictionary_t dict, FILE *fp);

/**
* @brief Print formatted dictionary to \a fp.
*
* Print the formatted dictionary according to the \a format format string
* to \a fp.
*
* @param[in] format Format string.
* @param[in] cb Callback function called for each variable in the format.
* @param[in] data Userdata passed to the callback \a cb.
* @param[in] fp File to print to.
*
* @return 0 on success.
* @retval 0 Success.
* @retval -EINVAL Invalid format string.
* @retval -ERANGE Invalid alignment specifier.
* @retval -ENOMEM Memory allocation failure.
*/
int xbps_fmts(const char *format, xbps_fmt_cb *cb, void *data, FILE *fp);

/**
* @brief Print formatted number to \a fp.
*
* Prints the number \d to \a fp according to the specification \a spec.
*
* @param[in] spec Format specification.
* @param[in] num Number to print.
* @param[in] fp File to print to.
*
* @return Returns 0 on success.
*/
int xbps_fmt_number(const struct xbps_fmt_spec *spec, int64_t num, FILE *fp);

/**
* @brief Print formatted string to \a fp.
*
* Prints the string \a str to \a fp according to the specification \a spec.
*
* @param[in] spec Format specification.
* @param[in] str String to print.
* @param[in] len Length of the string or 0.
* @param[in] fp File to print to.
*
* @return Returns 0 on success.
*/
int xbps_fmt_string(const struct xbps_fmt_spec *spec, const char *str, size_t len, FILE *fp);

/**@}*/

#ifdef __cplusplus
}
#endif
Expand Down
2 changes: 1 addition & 1 deletion lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ OBJS += plist_remove.o plist_fetch.o util.o util_path.o util_hash.o
OBJS += repo.o repo_sync.o
OBJS += rpool.o cb_util.o proplib_wrapper.o
OBJS += package_alternatives.o
OBJS += conf.o log.o
OBJS += conf.o log.o format.o
OBJS += $(EXTOBJS) $(COMPAT_OBJS)
# unnecessary unless pkgdb format changes
# OBJS += pkgdb_conversion.o
Expand Down
Loading

0 comments on commit 976132d

Please sign in to comment.