1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2019 Tobias Kortkamp <tobik@FreeBSD.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 #pragma once 29 30 enum ParserBehavior { 31 PARSER_DEFAULT = 0, 32 PARSER_COLLAPSE_ADJACENT_VARIABLES = 1 << 0, 33 PARSER_DEDUP_TOKENS = 1 << 1, 34 PARSER_FORMAT_TARGET_COMMANDS = 1 << 2, 35 PARSER_OUTPUT_DIFF = 1 << 4, 36 PARSER_OUTPUT_DUMP_TOKENS = 1 << 5, 37 PARSER_OUTPUT_EDITED = 1 << 6, 38 PARSER_OUTPUT_INPLACE = 1 << 7, 39 PARSER_OUTPUT_NO_COLOR = 1 << 8, 40 PARSER_OUTPUT_RAWLINES = 1 << 9, 41 PARSER_OUTPUT_REFORMAT = 1 << 10, 42 PARSER_SANITIZE_APPEND = 1 << 11, 43 PARSER_UNSORTED_VARIABLES = 1 << 12, 44 PARSER_ALLOW_FUZZY_MATCHING = 1 << 13, 45 PARSER_SANITIZE_COMMENTS = 1 << 14, 46 PARSER_ALWAYS_SORT_VARIABLES = 1 << 15, 47 PARSER_CHECK_VARIABLE_REFERENCES = 1 << 16, 48 PARSER_LOAD_LOCAL_INCLUDES = 1 << 17, 49 PARSER_SANITIZE_CMAKE_ARGS = 1 << 18, 50 }; 51 52 const char *ParserBehavior_tostring(enum ParserBehavior); 53 54 enum ParserMergeBehavior { 55 PARSER_MERGE_DEFAULT = 0, 56 PARSER_MERGE_COMMENTS = 1 << 0, 57 PARSER_MERGE_OPTIONAL_LIKE_ASSIGN = 1 << 2, 58 PARSER_MERGE_SHELL_IS_DELETE = 1 << 3, 59 PARSER_MERGE_AFTER_LAST_IN_GROUP = 1 << 4, 60 PARSER_MERGE_IGNORE_VARIABLES_IN_CONDITIONALS = 1 << 5, 61 }; 62 63 const char *ParserMergeBehavior_tostring(enum ParserMergeBehavior); 64 65 enum ParserLookupVariableBehavior { 66 PARSER_LOOKUP_DEFAULT = 0, 67 PARSER_LOOKUP_FIRST = 1 << 0, 68 PARSER_LOOKUP_IGNORE_VARIABLES_IN_CONDITIIONALS = 1 << 1, 69 }; 70 71 const char *ParserLookupVariableBehavior_tostring(enum ParserLookupVariableBehavior); 72 73 enum ParserError { 74 PARSER_ERROR_OK, // human:"no error" 75 PARSER_ERROR_DIFFERENCES_FOUND, // human:"differences found" 76 PARSER_ERROR_EDIT_FAILED, // human:"edit failed" 77 PARSER_ERROR_EXPECTED_CHAR, // human:"expected character" 78 PARSER_ERROR_EXPECTED_INT, // human:"expected integer" 79 PARSER_ERROR_EXPECTED_TOKEN, // human:"expected token" 80 PARSER_ERROR_INVALID_ARGUMENT, // human:"invalid argument" 81 PARSER_ERROR_IO, // human:"IO error" 82 PARSER_ERROR_AST_BUILD_FAILED, // human:"error building AST" 83 PARSER_ERROR_UNSPECIFIED, // human:"parse error" 84 }; 85 86 const char *ParserError_human(enum ParserError); 87 const char *ParserError_tostring(enum ParserError); 88 89 enum ParserMetadata { 90 PARSER_METADATA_CABAL_EXECUTABLES = 0, 91 PARSER_METADATA_FLAVORS, 92 PARSER_METADATA_LICENSES, 93 PARSER_METADATA_MASTERDIR, 94 PARSER_METADATA_SHEBANG_LANGS, 95 PARSER_METADATA_OPTION_DESCRIPTIONS, 96 PARSER_METADATA_OPTION_GROUPS, 97 PARSER_METADATA_OPTIONS, 98 PARSER_METADATA_POST_PLIST_TARGETS, 99 #if PORTFMT_SUBPACKAGES 100 PARSER_METADATA_SUBPACKAGES, 101 #endif 102 // Used as sentinel, keep PARSER_METADATA_USES last 103 PARSER_METADATA_USES, 104 }; 105 106 const char *ParserMetadata_tostring(enum ParserMetadata); 107 108 struct ParserSettings { 109 const char *filename; 110 int portsdir; 111 enum ParserBehavior behavior; 112 uint32_t target_command_format_threshold; 113 size_t diff_context; 114 size_t target_command_format_wrapcol; 115 size_t variable_wrapcol; 116 size_t if_wrapcol; 117 size_t for_wrapcol; 118 uint32_t debug_level; 119 }; 120 121 struct Array; 122 struct AST; 123 struct Mempool; 124 struct Parser; 125 struct Set; 126 struct Token; 127 128 typedef void (*ParserEditFn)(struct Parser *, struct AST *, struct Mempool *, void *); 129 130 #define PARSER_EDIT(name) \ 131 void name(struct Parser *parser, struct AST *root, struct Mempool *extpool, void *userdata) 132 133 struct Parser *parser_new(struct Mempool *, struct ParserSettings *); 134 void parser_init_settings(struct ParserSettings *); 135 enum ParserError parser_read_from_buffer(struct Parser *, const char *, size_t); 136 enum ParserError parser_read_from_file(struct Parser *, FILE *); 137 enum ParserError parser_read_finish(struct Parser *); 138 struct AST *parser_ast(struct Parser *); 139 char *parser_error_tostring(struct Parser *, struct Mempool *); 140 void parser_set_error(struct Parser *, enum ParserError, const char *); 141 void parser_free(struct Parser *); 142 enum ParserError parser_output_write_to_file(struct Parser *, FILE *); 143 enum ParserError parser_edit(struct Parser *, struct Mempool *, ParserEditFn, void *); 144 void parser_enqueue_output(struct Parser *, const char *); 145 struct AST *parser_lookup_target(struct Parser *, const char *); 146 struct AST *parser_lookup_variable(struct Parser *, const char *, enum ParserLookupVariableBehavior, struct Mempool *, struct Array **, struct Array **); 147 struct AST *parser_lookup_variable_str(struct Parser *, const char *, enum ParserLookupVariableBehavior, struct Mempool *, char **, char **); 148 void *parser_metadata(struct Parser *, enum ParserMetadata); 149 enum ParserError parser_merge(struct Parser *, struct Parser *, enum ParserMergeBehavior); 150 struct ParserSettings parser_settings(struct Parser *); 151