/ libpkg / private / pkg_printf.h
pkg_printf.h
  1  /*-
  2   * Copyright (c) 2012-2013 Matthew Seaman <matthew@FreeBSD.org>
  3   * All rights reserved.
  4   * 
  5   * Redistribution and use in source and binary forms, with or without
  6   * modification, are permitted provided that the following conditions
  7   * are met:
  8   * 1. Redistributions of source code must retain the above copyright
  9   *    notice, this list of conditions and the following disclaimer
 10   *    in this position and unchanged.
 11   * 2. 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   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 16   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 17   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 18   * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 19   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 20   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 21   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 22   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 23   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 24   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 25   */
 26  
 27  /* This is a private header file for internal and testing use only */
 28  #ifndef _PKG_PRINTF_H
 29  #define _PKG_PRINTF_H
 30  
 31  #include "bsd_compat.h"
 32  
 33  #include <pkg.h>
 34  
 35  #ifdef TESTING
 36  #define _static	
 37  #else
 38  #define _static	static
 39  #endif
 40  
 41  /* Format code modifiers */
 42  #define PP_ALTERNATE_FORM1	(1U << 0) /* ? */
 43  #define PP_ALTERNATE_FORM2	(1U << 1) /* # */
 44  #define PP_LEFT_ALIGN		(1U << 2) /* - */
 45  #define PP_EXPLICIT_PLUS	(1U << 3) /* + */
 46  #define PP_SPACE_FOR_PLUS	(1U << 4) /* SPACE */
 47  #define PP_ZERO_PAD		(1U << 5) /* 0 */
 48  #define PP_THOUSANDS_SEP	(1U << 6) /* ' (locale dependent) */
 49  
 50  /* Contexts for option parsing */
 51  #define PP_PKG	(1U << 0)	/* Any pkg scalar value */
 52  #define PP_A	(1U << 1)	/* annotations */
 53  #define PP_B	(1U << 2)	/* shlib required */
 54  #define PP_C	(1U << 3)	/* category */
 55  #define PP_D	(1U << 4)	/* directory */
 56  #define PP_F	(1U << 5)	/* file */
 57  #define PP_G	(1U << 6)	/* group */
 58  #define PP_L	(1U << 7)	/* licence */
 59  #define PP_O	(1U << 8)	/* option */
 60  #define PP_U	(1U << 9)	/* user */
 61  #define PP_Y	(1U << 10)	/* required */
 62  #define PP_b	(1U << 11)	/* shlib provided */
 63  #define PP_d	(1U << 12)	/* dependency */
 64  #define PP_r	(1U << 13)	/* requirement */
 65  #define PP_y	(1U << 14)	/* provided */
 66  
 67  #define _PP_last	PP_r
 68  #define PP_ALL	((_PP_last << 1) - 1) /* All contexts */
 69  
 70  /*  %{ %| %} trailer context */
 71  #define PP_TRAILER	(PP_A|PP_B|PP_C|PP_D|PP_F|PP_G|PP_L|PP_O|PP_U|PP_b|PP_d|PP_r)
 72  
 73  /* Licence logic types */
 74  #define PP_LIC_SINGLE	0
 75  #define PP_LIC_OR	1
 76  #define PP_LIC_AND	2
 77  
 78  /* These are in alphabetical order of format code with A-Z sorting
 79   * before a-z */
 80  typedef enum _fmt_code_t {
 81  	PP_PKG_ANNOTATION_NAME = 0,
 82  	PP_PKG_ANNOTATION_VALUE,
 83  	PP_PKG_ANNOTATIONS,
 84  	PP_PKG_SHLIB_REQUIRED_NAME,
 85  	PP_PKG_SHLIBS_REQUIRED,
 86  	PP_PKG_CATEGORY_NAME,
 87  	PP_PKG_CATEGORIES,
 88  	PP_PKG_DIRECTORY_FFLAGS,
 89  	PP_PKG_DIRECTORY_GROUP,
 90  	PP_PKG_DIRECTORY_PATH,
 91  	PP_PKG_DIRECTORY_PERMS,
 92  	PP_PKG_DIRECTORY_USER,
 93  	PP_PKG_DIRECTORIES,
 94  	PP_PKG_FILE_FFLAGS,
 95  	PP_PKG_FILE_GROUP,
 96  	PP_PKG_FILE_MTIME,
 97  	PP_PKG_FILE_PATH,
 98  	PP_PKG_FILE_PERMS,
 99  	PP_PKG_FILE_SHA256,
100  	PP_PKG_FILE_SYMLINK_TARGET,
101  	PP_PKG_FILE_USER,
102  	PP_PKG_FILES,
103  	PP_PKG_GROUP_NAME,
104  	PP_PKG_GROUPS,
105  	PP_ROW_COUNTER,
106  	PP_PKG_LICENSE_NAME,
107  	PP_PKG_LICENSES,
108  	PP_PKG_MESSAGE,
109  	PP_PKG_REPO_IDENT,
110  	PP_PKG_OPTION_NAME,
111  	PP_PKG_OPTION_VALUE,
112  	PP_PKG_OPTION_DEFAULT,
113  	PP_PKG_OPTION_DESCRIPTION,
114  	PP_PKG_OPTIONS,
115  	PP_PKG_ALTABI,
116  	PP_PKG_REPO_PATH,
117  	PP_PKG_CHAR_STRING,
118  	PP_PKG_USER_NAME,
119  	PP_PKG_USERS,
120  	PP_PKG_OLD_VERSION,
121  	PP_PKG_AUTOREMOVE,
122  	PP_PKG_SHLIB_PROVIDED_NAME,
123  	PP_PKG_SHLIBS_PROVIDED,
124  	PP_PKG_COMMENT,
125  	PP_PKG_DEPENDENCY_LOCK,
126  	PP_PKG_DEPENDENCY_NAME,
127  	PP_PKG_DEPENDENCY_ORIGIN,
128  	PP_PKG_DEPENDENCY_VERSION,
129  	PP_PKG_DEPENDENCIES,
130  	PP_PKG_DESCRIPTION,
131  	PP_PKG_LOCK_STATUS,
132  	PP_PKG_LICENSE_LOGIC,
133  	PP_PKG_MAINTAINER,
134  	PP_PKG_NAME,
135  	PP_PKG_ORIGIN,
136  	PP_PKG_PREFIX,
137  	PP_PKG_ARCHITECTURE,
138  	PP_PKG_REQUIREMENT_LOCK,
139  	PP_PKG_REQUIREMENT_NAME,
140  	PP_PKG_REQUIREMENT_ORIGIN,
141  	PP_PKG_REQUIREMENT_VERSION,
142  	PP_PKG_REQUIREMENTS,
143  	PP_PKG_FLATSIZE,
144  	PP_PKG_INSTALL_TIMESTAMP,
145  	PP_PKG_CHECKSUM,
146  	PP_PKG_VERSION,
147  	PP_PKG_HOME_PAGE,
148  	PP_PKG_PKGSIZE,
149  	PP_PKG_REQUIRED,
150  	PP_PKG_REQUIRED_NAME,
151  	PP_PKG_PROVIDED,
152  	PP_PKG_PROVIDED_NAME,
153  	PP_PKG_SHORT_CHECKSUM,
154  	PP_PKG_INT_CHECKSUM,
155  	PP_LAST_FORMAT = PP_PKG_INT_CHECKSUM,
156  	PP_LITERAL_PERCENT,
157  	PP_UNKNOWN,
158  	PP_END_MARKER
159  } fmt_code_t;
160  
161  #define	ITEM_FMT_SET	(0x1U << 0)
162  #define SEP_FMT_SET	(0x1U << 1)
163  
164  struct percent_esc {
165  	unsigned	 flags;
166  	int		 width;
167  	unsigned	 trailer_status;
168  	xstring	*item_fmt;
169  	xstring	*sep_fmt;
170  	fmt_code_t	 fmt_code;
171  };
172  
173  /* Format handler function prototypes */
174  
175  _static xstring *format_annotation_name(xstring *, const void *, struct percent_esc *);
176  _static xstring *format_annotation_value(xstring *, const void *, struct percent_esc *);
177  _static xstring *format_annotations(xstring *, const void *, struct percent_esc *);
178  _static xstring *format_shlibs_required(xstring *, const void *, struct percent_esc *);
179  _static xstring *format_shlib_name(xstring *, const void *, struct percent_esc *);
180  _static xstring *format_categories(xstring *, const void *, struct percent_esc *);
181  _static xstring *format_category_name(xstring *, const void *, struct percent_esc *);
182  _static xstring *format_directories(xstring *, const void *, struct percent_esc *);
183  _static xstring *format_directory_fflags(xstring *, const void *, struct percent_esc *);
184  _static xstring *format_directory_group(xstring *, const void *, struct percent_esc *);
185  _static xstring *format_directory_path(xstring *, const void *, struct percent_esc *);
186  _static xstring *format_directory_perms(xstring *, const void *, struct percent_esc *);
187  _static xstring *format_directory_user(xstring *, const void *, struct percent_esc *);
188  _static xstring *format_files(xstring *, const void *, struct percent_esc *);
189  _static xstring *format_file_mtime(xstring *, const void *, struct percent_esc *);
190  _static xstring *format_file_group(xstring *, const void *, struct percent_esc *);
191  _static xstring *format_file_path(xstring *, const void *, struct percent_esc *);
192  _static xstring *format_file_perms(xstring *, const void *, struct percent_esc *);
193  _static xstring *format_file_sha256(xstring *, const void *, struct percent_esc *);
194  _static xstring *format_file_user(xstring *, const void *, struct percent_esc *);
195  _static xstring *format_file_fflags(xstring *, const void *, struct percent_esc *);
196  _static xstring *format_file_symlink_target(xstring *, const void *, struct percent_esc *);
197  _static xstring *format_groups(xstring *, const void *, struct percent_esc *);
198  _static xstring *format_group_name(xstring *, const void *, struct percent_esc *);
199  _static xstring *format_row_counter(xstring *, const void *, struct percent_esc *);
200  _static xstring *format_licenses(xstring *, const void *, struct percent_esc *);
201  _static xstring *format_license_name(xstring *, const void *, struct percent_esc *);
202  _static xstring *format_message(xstring *, const void *, struct percent_esc *);
203  _static xstring *format_repo_ident(xstring *, const void *, struct percent_esc *);
204  _static xstring *format_options(xstring *, const void *, struct percent_esc *);
205  _static xstring *format_option_name(xstring *, const void *, struct percent_esc *);
206  _static xstring *format_option_value(xstring *, const void *, struct percent_esc *);
207  _static xstring *format_option_default(xstring *, const void *, struct percent_esc *);
208  _static xstring *format_option_description(xstring *, const void *, struct percent_esc *);
209  _static xstring *format_repo_path(xstring *, const void *, struct percent_esc *);
210  _static xstring *format_char_string(xstring *, const void *, struct percent_esc *);
211  _static xstring *format_users(xstring *, const void *, struct percent_esc *);
212  _static xstring *format_user_name(xstring *, const void *, struct percent_esc *);
213  _static xstring *format_old_version(xstring *, const void *, struct percent_esc *);
214  _static xstring *format_autoremove(xstring *, const void *, struct percent_esc *);
215  _static xstring *format_shlibs_provided(xstring *, const void *, struct percent_esc *);
216  _static xstring *format_comment(xstring *, const void *, struct percent_esc *);
217  _static xstring *format_dependencies(xstring *, const void *, struct percent_esc *);
218  _static xstring *format_dependency_lock(xstring *, const void *, struct percent_esc *);
219  _static xstring *format_dependency_name(xstring *, const void *, struct percent_esc *);
220  _static xstring *format_dependency_origin(xstring *, const void *, struct percent_esc *);
221  _static xstring *format_dependency_version(xstring *, const void *, struct percent_esc *);
222  _static xstring *format_description(xstring *, const void *, struct percent_esc *);
223  _static xstring *format_lock_status(xstring *, const void *, struct percent_esc *);
224  _static xstring *format_license_logic(xstring *, const void *, struct percent_esc *);
225  _static xstring *format_maintainer(xstring *, const void *, struct percent_esc *);
226  _static xstring *format_name(xstring *, const void *, struct percent_esc *);
227  _static xstring *format_origin(xstring *, const void *, struct percent_esc *);
228  _static xstring *format_prefix(xstring *, const void *, struct percent_esc *);
229  _static xstring *format_architecture(xstring *, const void *, struct percent_esc *);
230  _static xstring *format_altabi(xstring *, const void *, struct percent_esc *);
231  _static xstring *format_requirements(xstring *, const void *, struct percent_esc *);
232  _static xstring *format_flatsize(xstring *, const void *, struct percent_esc *);
233  _static xstring *format_install_tstamp(xstring *, const void *, struct percent_esc *);
234  _static xstring *format_checksum(xstring *, const void *, struct percent_esc *);
235  _static xstring *format_version(xstring *, const void *, struct percent_esc *);
236  _static xstring *format_home_url(xstring *, const void *, struct percent_esc *);
237  _static xstring *format_pkgsize(xstring *, const void *, struct percent_esc *);
238  _static xstring *format_short_checksum(xstring *, const void *, struct percent_esc *);
239  _static xstring *format_literal_percent(xstring *, __unused const void *, __unused struct percent_esc *);
240  _static xstring *format_unknown(xstring *, __unused const void *, __unused struct percent_esc *);
241  _static xstring *format_provided(xstring *, const void *, struct percent_esc *);
242  _static xstring *format_required(xstring *, const void *, struct percent_esc *);
243  _static xstring *format_provide_name(xstring *, const void *, struct percent_esc *);
244  _static xstring *format_int_checksum(xstring *, const void *, struct percent_esc *);
245  
246  /* Other static function prototypes */
247  
248  _static struct percent_esc *new_percent_esc(void);
249  _static struct percent_esc *clear_percent_esc(struct percent_esc *);
250  _static void free_percent_esc(struct percent_esc *);
251  
252  _static char *gen_format(char *, size_t, unsigned, const char *);
253  
254  _static xstring *human_number(xstring *, int64_t, struct percent_esc *);
255  _static xstring *string_val(xstring *, const char *,
256  			       struct percent_esc *);
257  _static xstring *int_val(xstring *, int64_t, struct percent_esc *);
258  _static xstring *bool_val(xstring *, bool, struct percent_esc *);
259  _static xstring *mode_val(xstring *, mode_t, struct percent_esc *);
260  _static xstring *liclog_val(xstring *, lic_t, struct percent_esc *);
261  _static xstring *list_count(xstring *, int64_t, struct percent_esc *);
262  
263  _static struct percent_esc *set_list_defaults(struct percent_esc *,
264  					      const char *, const char *);
265  
266  _static xstring *iterate_item(xstring *, const struct pkg *,
267  				  const char *, const void *, int, unsigned);
268  
269  _static const char *field_modifier(const char *, struct percent_esc *);
270  _static const char *field_width(const char *, struct percent_esc *);
271  _static const char *format_code(const char *, unsigned , struct percent_esc *);
272  _static const char *format_trailer(const char *, struct percent_esc *);
273  _static const char *parse_format(const char *, unsigned, struct percent_esc *);
274  
275  _static const char *maybe_read_hex_byte(xstring *, const char *);
276  _static const char *read_oct_byte(xstring *, const char *);
277  _static const char *process_escape(xstring *, const char *);
278  
279  _static const char *process_format_trailer(xstring *, struct percent_esc *,
280  					   const char *, const struct pkg *,
281  					   const void *, int, unsigned);
282  _static const char *process_format_main(xstring *, struct percent_esc *,
283  					const char *, const char *, void *);
284  
285  #endif
286  
287  /*
288   * That's All Folks!
289   */