/usr/include/obs/util/cf-lexer.h is in libobs-dev 21.0.2+dfsg1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | /*
* Copyright (c) 2013 Hugh Bailey <obs.jim@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "lexer.h"
#ifdef __cplusplus
extern "C" {
#endif
EXPORT char *cf_literal_to_str(const char *literal, size_t count);
/* ------------------------------------------------------------------------- */
/*
* A C-family lexer token is defined as:
* 1.) A generic 'name' token. (abc123_def456)
* 2.) A numeric sequence (usually starting with a number)
* 3.) A sequence of generic whitespace defined as spaces and tabs
* 4.) A newline
* 5.) A string or character sequence (surrounded by single or double quotes)
* 6.) A single character of a type not specified above
*/
enum cf_token_type {
CFTOKEN_NONE,
CFTOKEN_NAME,
CFTOKEN_NUM,
CFTOKEN_SPACETAB,
CFTOKEN_NEWLINE,
CFTOKEN_STRING,
CFTOKEN_OTHER
};
struct cf_token {
const struct cf_lexer *lex;
struct strref str;
struct strref unmerged_str;
enum cf_token_type type;
};
static inline void cf_token_clear(struct cf_token *t)
{
memset(t, 0, sizeof(struct cf_token));
}
static inline void cf_token_copy(struct cf_token *dst,
const struct cf_token *src)
{
memcpy(dst, src, sizeof(struct cf_token));
}
static inline void cf_token_add(struct cf_token *dst,
const struct cf_token *add)
{
strref_add(&dst->str, &add->str);
strref_add(&dst->unmerged_str, &add->unmerged_str);
}
/* ------------------------------------------------------------------------- */
/*
* The c-family lexer is a base lexer for generating a list of string
* reference tokens to be used with c-style languages.
*
* This base lexer is meant to be used as a stepping stone for an actual
* language lexer/parser.
*
* It reformats the text in the two following ways:
* 1.) Spliced lines (escaped newlines) are merged
* 2.) All comments are converted to a single space
*/
struct cf_lexer {
char *file;
struct lexer base_lexer;
char *reformatted, *write_offset;
DARRAY(struct cf_token) tokens;
bool unexpected_eof; /* unexpected multi-line comment eof */
};
EXPORT void cf_lexer_init(struct cf_lexer *lex);
EXPORT void cf_lexer_free(struct cf_lexer *lex);
static inline struct cf_token *cf_lexer_get_tokens(struct cf_lexer *lex)
{
return lex->tokens.array;
}
EXPORT bool cf_lexer_lex(struct cf_lexer *lex, const char *str,
const char *file);
/* ------------------------------------------------------------------------- */
/* c-family preprocessor definition */
struct cf_def {
struct cf_token name;
DARRAY(struct cf_token) params;
DARRAY(struct cf_token) tokens;
bool macro;
};
static inline void cf_def_init(struct cf_def *cfd)
{
cf_token_clear(&cfd->name);
da_init(cfd->params);
da_init(cfd->tokens);
cfd->macro = false;
}
static inline void cf_def_addparam(struct cf_def *cfd, struct cf_token *param)
{
da_push_back(cfd->params, param);
}
static inline void cf_def_addtoken(struct cf_def *cfd, struct cf_token *token)
{
da_push_back(cfd->tokens, token);
}
static inline struct cf_token *cf_def_getparam(const struct cf_def *cfd,
size_t idx)
{
return cfd->params.array+idx;
}
static inline void cf_def_free(struct cf_def *cfd)
{
cf_token_clear(&cfd->name);
da_free(cfd->params);
da_free(cfd->tokens);
}
/* ------------------------------------------------------------------------- */
/*
* C-family preprocessor
*
* This preprocessor allows for standard c-style preprocessor directives
* to be applied to source text, such as:
*
* + #include
* + #define/#undef
* + #ifdef/#ifndef/#if/#elif/#else/#endif
*
* Still left to implement (TODO):
* + #if/#elif
* + "defined" preprocessor keyword
* + system includes
* + variadic macros
* + custom callbacks (for things like pragma)
* + option to exclude features such as #import, variadic macros, and other
* features for certain language implementations
* + macro parameter string operator #
* + macro parameter token concatenation operator ##
* + predefined macros
* + restricted macros
*/
struct cf_preprocessor {
struct cf_lexer *lex;
struct error_data *ed;
DARRAY(struct cf_def) defines;
DARRAY(char*) sys_include_dirs;
DARRAY(struct cf_lexer) dependencies;
DARRAY(struct cf_token) tokens;
bool ignore_state;
};
EXPORT void cf_preprocessor_init(struct cf_preprocessor *pp);
EXPORT void cf_preprocessor_free(struct cf_preprocessor *pp);
EXPORT bool cf_preprocess(struct cf_preprocessor *pp, struct cf_lexer *lex,
struct error_data *ed);
static inline void cf_preprocessor_add_sys_include_dir(
struct cf_preprocessor *pp, const char *include_dir)
{
if (include_dir)
da_push_back(pp->sys_include_dirs, bstrdup(include_dir));
}
EXPORT void cf_preprocessor_add_def(struct cf_preprocessor *pp,
struct cf_def *def);
EXPORT void cf_preprocessor_remove_def(struct cf_preprocessor *pp,
const char *def_name);
static inline struct cf_token *cf_preprocessor_get_tokens(
struct cf_preprocessor *pp)
{
return pp->tokens.array;
}
#ifdef __cplusplus
}
#endif
|