text: /* vim: set tabstop=8 softtabstop=4 shiftwidth=4 noexpandtab : */
  /*
   * jparse - tool that parses a block of JSON input
   *
   * "Because sometimes even the IOCCC Judges need some help." :-)
   *
   * This tool is currently being worked on by:
   *
   *	@xexyl
   *	https://xexyl.net		Cody Boone Ferguson
   *	https://ioccc.xexyl.net
   *
   * NOTE: This is _very incomplete_ and right now all it does is reads from either
   * stdin, the command line or a file, running yyparse() (actually ugly_parse())
   * on it. The grammar is incomplete, there are some things that are allowed that
   * are not valid JSON and many other things need to be done.
   *
   * This is very much a work in progress!
   */
  
  
  #if !defined(INCLUDE_JPARSE_H)
  #    define  INCLUDE_JPARSE_H
  
  
  #include <stdio.h>
  
  /*
   * dbg - debug, warning and error reporting facility
   */
  #include "dbg.h"
  
  /*
   * util - utility functions and definitions
   */
  #include "util.h"
  
  /*
   * JSON functions supporting mkiocccentry code
   */
  #include "json_parse.h"
  
  /*
   * sanity - reality checks
   */
  #include "sanity.h"
  
  /*
   * definitions
   */
  
  /* NOTE: UGLY_DEBUG MUST be defined prior to #including jparse.tab.h! */
  #define UGLY_DEBUG 1
  #define UGLY__BUFFER_STATE YY_BUFFER_STATE /* see comments in jparse.l as to why we do this here */
  #define UGLY_ABORT YYABORT  /* bison does not use the prefix for YYABORT so we do it for them */
  
  /*
   * jparse.tab.h - generated by bison
   */
  #include "jparse.tab.h"
  
  /*
   * usage message
   *
   * Use the usage() function to print the usage_msg([0-9]?)+ strings.
   */
  static const char * const usage_msg =
      "usage: %s [-h] [-v level] [-J level] [-q] [-V] [-s string] [file ...]\n"
      "\n"
      "\t-h\t\tprint help message and exit 0\n"
      "\t-v level\tset verbosity level (def level: %d)\n"
      "\t-J level\tset JSON verbosity level (def level: %d)\n"
      "\t\t\tNOTE: You must specify this option before -s as -s is processed immediately\n"
      "\t-q\t\tquiet mode: silence msg(), warn(), warnp() if -v 0 (def: not quiet)\n"
      "\t-V\t\tprint version string and exit 0\n"
      "\t-n\t\tdo not output newline after decode output\n"
      "\t-s\t\tread arg as a string\n"
      "\n"
      "\t[file]\t\tread and parse file\n"
      "\t\t\tNOTE: - means read from stdin\n"
      "\n"
      "jparse version: %s\n";
  
  
  /*
   * globals
   */
  extern bool output_newline;		/* true ==> -n not specified, output new line after each arg processed */
  extern unsigned num_errors;		/* > 0 number of errors encountered */
  /* lexer and parser specific variables */
  extern int ugly_lineno;			/* line number in lexer */
  extern char *ugly_text;			/* current text */
  extern FILE *ugly_in;			/* input file lexer/parser reads from */
  extern unsigned num_errors;		/* > 0 number of errors encountered */
  extern bool output_newline;		/* true ==> -n not specified, output new line after each arg processed */
  extern struct json tree;		/* the parse tree */
  extern int ugly_leng;
  
  
  /*
   * lexer specific
   */
  extern int ugly_lex(void);
  
  /*
   * function prototypes for jparse.y
   */
  extern void ugly_error(struct json *node, char const *format, ...);
  static void usage(int exitcode, char const *name, char const *str) __attribute__((noreturn));
  
  /*
   * function prototypes for jparse.l
   */
  extern struct json *parse_json(char const *ptr, size_t len, bool *is_valid, FILE *dbg_stream);
  extern struct json *parse_json_file(char const *filename, bool *is_valid, FILE *dbg_stream);
  
  
  #endif /* INCLUDE_JPARSE_H */
  