This file is indexed.

/usr/include/fcml/fcml_parser.hpp is in libfcml-dev 1.1.1-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
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
/*
 * FCML - Free Code Manipulation Library.
 * Copyright (C) 2010-2015 Slawomir Wojtasiak
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

/** @file fcml_parser.hpp
 * C++ wrapper for instruction parser.
 *
 * @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
 * This project is released under the GNU Lesser General Public License.
 */

#ifndef FCML_PARSER_HPP_
#define FCML_PARSER_HPP_

#include "fcml_common.hpp"
#include "fcml_symbols.hpp"
#include "fcml_errors.hpp"
#include "fcml_dialect.hpp"

#include "fcml_parser.h"

namespace fcml {

/**
 * Something failed while parsing.
 * @since 1.1.0
 */
class ParsingFailedException: public ErrorContainerAwareException {
public:
    ParsingFailedException( const fcml_cstring msg, ErrorContainer &errorContainer, fcml_ceh_error error = FCML_CEH_GEC_NO_ERROR ) :
        ErrorContainerAwareException( msg, errorContainer, error ){
    }
};

/** Parser configuration.
 * @since 1.1.0
 */
class ParserConfig {
public:

    /**
     * Default constructor.
     * @since 1.1.0
     */
    ParserConfig() :
        _throwExceptionOnError(true),
        _ignoreUndefinedSymbols(false),
        _disableSymbolsDeclaration(true),
        _overrideLabels(false),
        _allocSymbolTableIfNeeded(false),
        _enableErrorMessages(true) {
    }

    /** @since 1.1.0 */
    bool isAllocSymbolTableIfNeeded() const {
        return _allocSymbolTableIfNeeded;
    }

    /** @since 1.1.0 */
    void setAllocSymbolTableIfNeeded(bool allocSymbolTableIfNeeded) {
        _allocSymbolTableIfNeeded = allocSymbolTableIfNeeded;
    }

    /** @since 1.1.0 */
    bool isDisableSymbolsDeclaration() const {
        return _disableSymbolsDeclaration;
    }

    /** @since 1.1.0 */
    void setDisableSymbolsDeclaration(bool disableSymbolsDeclaration) {
        _disableSymbolsDeclaration = disableSymbolsDeclaration;
    }

    /** @since 1.1.0 */
    bool isEnableErrorMessages() const {
        return _enableErrorMessages;
    }

    /** @since 1.1.0 */
    void setEnableErrorMessages(bool enableErrorMessages) {
        _enableErrorMessages = enableErrorMessages;
    }

    /** @since 1.1.0 */
    bool isIgnoreUndefinedSymbols() const {
        return _ignoreUndefinedSymbols;
    }

    /** @since 1.1.0 */
    void setIgnoreUndefinedSymbols(bool ignoreUndefinedSymbols) {
        _ignoreUndefinedSymbols = ignoreUndefinedSymbols;
    }

    /** @since 1.1.0 */
    bool isOverrideLabels() const {
        return _overrideLabels;
    }

    /** @since 1.1.0 */
    void setOverrideLabels(bool overrideLabels) {
        _overrideLabels = overrideLabels;
    }

    /**
     * Gets true if exception should be thrown in case of error.
     * @return True if exception should be thrown in case of error.
     * @since 1.1.0
     */
    bool isThrowExceptionOnError() const {
        return _throwExceptionOnError;
    }

    /**
     * Sets exception on error flag. Has to be set to true if exception should be thrown in case of error.
     * @param throwExceptionOnError True if exception should be thrown in case of error.
     * @since 1.1.0
     */
    void setThrowExceptionOnError(bool throwExceptionOnError) {
        _throwExceptionOnError = throwExceptionOnError;
    }

private:
    bool _throwExceptionOnError;
    bool _ignoreUndefinedSymbols;
    bool _disableSymbolsDeclaration;
    bool _overrideLabels;
    bool _allocSymbolTableIfNeeded;
    bool _enableErrorMessages;
};

/** Parser context.
 * @since 1.1.0
 */
class ParserContext {
public:

    /**
     * Creates a parser context instance for optional instruction pointer.
     *
     * @param ip The instruction pointer.
     * @since 1.1.0
     */
    ParserContext( fcml_ip ip = 0 ) :
        _ip(ip),
        _symbolTable(NULL) {
    }

    /**
     * Creates a parser context for given symbol table and optional instruction pointer.
     *
     * @param symbolTable The symbol table.
     * @param ip The instruction pointer.
     * @since 1.1.0
     */
    ParserContext( SymbolTable *symbolTable, fcml_ip ip = 0 ) :
        _ip(ip),
        _symbolTable(symbolTable) {
    }

public:

    /**
     * Gets the parser configuration associated with the context.
     *
     * @return The parser configuration associated with the context.
     * @since 1.1.0
     */
    const ParserConfig& getConfig() const {
        return _config;
    }

    /**
     * Gets the parser configuration associated with the context.
     *
     * @return The parser configuration associated with the context.
     * @since 1.1.0
     */
    ParserConfig& getConfig() {
        return _config;
    }

    /**
     * Gets the instruction pointer.
     *
     * @return The instruction pointer.
     * @since 1.1.0
     */
    fcml_ip getIp() const {
        return _ip;
    }

    /**
     * Gets a new instruction pointer.
     *
     * @param ip The new instruction pointer.
     * @since 1.1.0
     */
    void setIp(fcml_ip ip) {
        _ip = ip;
    }

    /**
     * Increments instruction pointer by given number of bytes.
     *
     * @param ip The number of bytes the instruction pointer has to be incremented by.
     * @since 1.1.0
     */
    void incrementIP( fcml_ip ip ) {
        _ip += ip;
    }

    /**
     * Gets the symbol table associated with the context.
     *
     * @return The symbol table.
     * @since 1.1.0
     */
    const SymbolTable* getSymbolTable() const {
        return _symbolTable;
    }

    /**
     * Gets the symbol table associated with the context.
     *
     * @return The symbol table.
     * @since 1.1.0
     */
    SymbolTable* getSymbolTable() {
        return _symbolTable;
    }

    /**
     * Sets a symbol table for the instruction.
     *
     * @param symbolTable The symbol table for the parser context.
     * @since 1.1.0
     */
    void setSymbolTable(SymbolTable* symbolTable) {
        _symbolTable = symbolTable;
    }

private:

    /** The instruction pointer used by declared labels. */
    fcml_ip _ip;
    /** The parser configuration. */
    ParserConfig _config;
    /** The symbol table. */
    SymbolTable *_symbolTable;

};

/** Parser result.
 * @since 1.1.0
 */
class ParserResult {
public:

    /**
     * Creates an empty parser result.
     * @since 1.1.0
     */
    ParserResult() {
    }

    /**
     * Gets errors container with parsing errors.
     *
     * @return Errors container.
     * @since 1.1.0
     */
    const ErrorContainer& getErrors() const {
        return _errors;
    }

    /**
     * Gets the parsed instruction.
     *
     * @return The parsed instruction.
     * @since 1.1.0
     */
    const Instruction& getInstruction() const {
        return _instruction;
    }

    /**
     * Gets declared symbol is there is any.
     * @return Gets symbol if there is any.
     * @since 1.1.0
     */
    const Nullable<Symbol> &getSymbol() const {
        return _symbol;
    }

    /**
     * Cleans the parser result.
     * @since 1.1.0
     */
    void clean() {
        _errors.clean();
        _symbol.setNotNull(false);
        _symbol.setValue(Symbol());
    }

protected:

    friend class Parser;

    /**
     * Sets error container for the context.
     * @param errors A new error container.
     * @since 1.1.0
     */
    void setErrors(const ErrorContainer& errors) {
        _errors = errors;
    }

    /**
     * Sets an instruction for the container.
     * @param instruction The instruction.
     * @since 1.1.0
     */
    void setInstruction(const Instruction& instruction) {
        _instruction = instruction;
    }

    /**
     * Sets symbol.
     * @param symbol The symbol.
     * @since 1.1.0
     */
    void setSymbol(const Nullable<Symbol>& symbol) {
        _symbol = symbol;
    }

private:

    /** Errors container. */
    ErrorContainer _errors;
    /** Gets declared symbol. Take into account that it can be 'empty'. */
    Nullable<Symbol> _symbol;
    /** The parsed instruction. */
    Instruction _instruction;

};

/**
 * Converts objects to their structures counterparts.
 * @since 1.1.0
 * @remarks Internal API, not intended to be used outside.
 */
class ParserTypeConverter {
public:

    static void convert( ParserConfig &src, fcml_st_parser_config &dest ) {
        dest.alloc_symbol_table_if_needed = src.isAllocSymbolTableIfNeeded();
        dest.disable_symbols_declaration = src.isDisableSymbolsDeclaration();
        dest.enable_error_messages = src.isEnableErrorMessages();
        dest.ignore_undefined_symbols = src.isIgnoreUndefinedSymbols();
        dest.override_labels = src.isOverrideLabels();
    }

};

/** Parser wrapper.
 * @since 1.1.0
 */
class Parser: protected DialectAware, protected SymbolTableAware {
public:

    /**
     * Creates a parser instance for the given dialect.
     *
     * @param dialect The dialect instance.
     * @since 1.1.0
     */
    Parser( const Dialect &dialect ) :
        _dialect(dialect) {
    }

    /**
     * Parses instruction given in the parameters.
     *
     * @param ctx Parser context.
     * @param instruction Instruction mnemonic.
     * @param[out] parserResult Instruction result.
     * @return Error code.
     * @throw ParsingFailedException Parsing failed.
     * @since 1.1.0
     */
    fcml_ceh_error parse( ParserContext &ctx, const fcml_cstring &instruction, ParserResult &parserResult ) {

        // Prepare parser context.
        fcml_st_parser_context context = {0};
        ParserTypeConverter::convert( ctx.getConfig(), context.configuration );
        context.ip = ctx.getIp();
        SymbolTable *symbolTable = ctx.getSymbolTable();
        context.symbol_table = ( symbolTable ) ? extractSymbolTable( *symbolTable ) : NULL;
        context.dialect = extractDialect( _dialect );

        fcml_st_parser_result parser_result;
        ::fcml_fn_parser_result_prepare( &parser_result );

        try {

            parserResult.clean();

            // Prepare instruction.
            fcml_ceh_error error = ::fcml_fn_parse( &context, instruction.c_str(), &parser_result );

            ErrorContainer errorContainer;
            ErrorTypeConverter::convert( parser_result.errors, errorContainer );

            parserResult.setErrors( errorContainer );

            if( !error && !parser_result.instruction ) {
                // Just in case, it should never happen.
                error = FCML_CEH_GEC_INTERNAL_ERROR;
            }

            if( error && ctx.getConfig().isThrowExceptionOnError() ) {
                ::fcml_fn_parser_result_free( &parser_result );
                throw ParsingFailedException( errorContainer.prepareErrorMessage( FCML_TEXT("Parsing failed") ), errorContainer, error );
            }

            if( !error ) {

                Instruction parsedInstruction;
                TypeConverter::convert( *(parser_result.instruction), parsedInstruction );

                parserResult.setInstruction( parsedInstruction );
                parserResult.setSymbol( parser_result.symbol ? Symbol( parser_result.symbol->symbol, parser_result.symbol->value ) : Symbol() );

            }

            ::fcml_fn_parser_result_free( &parser_result );

        } catch( std::exception &exc ) {
            // If anything failed, free assembler results.
            ::fcml_fn_parser_result_free( &parser_result );
            throw exc;
        }

        return FCML_CEH_GEC_NO_ERROR;
    }

private:

    /** The dialect for the parser. */
    const Dialect &_dialect;

};

}

#endif /* FCML_PARSER_HPP_ */