/*
* boxes - Command line filter to draw/remove ASCII boxes around text
* Copyright (c) 1999-2023 Thomas Jensen and the boxes contributors
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
* License, version 3, as published by the Free Software Foundation.
* This program 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 General Public License for more
* details.
* You should have received a copy of the GNU General Public License along with this program.
* If not, see .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
/*
* Project-wide globals and data structures
*/
#ifndef BOXES_H
#define BOXES_H
/* #define DEBUG 1 */
/* #define REGEXP_DEBUG 1 */
/* #define PARSER_DEBUG 1 */
/* #define LEXER_DEBUG 1 */
/* #define DISCOVERY_DEBUG 1 */
#include
#include
#include "bxstring.h"
#include "regulex.h"
#define PROJECT "boxes" /* name of program */
#define VERSION "--BVERSION--" /* current release of project */
#define GLOBALCONF "--GLOBALCONF--" /* name of system-wide config file */
#define DEF_INDENTMODE 'b' /* default indent mode of a design (indent box, not text) */
/*
* max. supported line length in bytes
* This is how many characters of a line will be read. Anything beyond
* will be discarded. The line feed character at the end does not count.
* (This should have been done via sysconf(), but I didn't do it in order
* to ease porting to non-unix platforms.)
*/
#if defined(LINE_MAX_BYTES) && (LINE_MAX_BYTES < 2048)
#undef LINE_MAX_BYTES
#endif
#ifndef LINE_MAX_BYTES
#define LINE_MAX_BYTES 16382
#endif
/* Macro to declare a function parameter as intentionally unused in order to avoid compiler warnings */
#define UNUSED(variable) ((void)(variable))
#define BTOP 0 /* for use with sides */
#define BRIG 1
#define BBOT 2
#define BLEF 3
typedef enum {
NW, NNW, N, NNE, NE, ENE, E, ESE, SE, SSE, S, SSW, SW, WSW, W, WNW
} shape_t;
typedef struct {
shape_t name;
char **chars;
bxstr_t **mbcs;
size_t height;
size_t width;
/** elastic is used only in original definition */
int elastic;
/** For each shape line 0..height-1, a flag which is 1 if all shapes to the left of this shape are blank on the
* same shape line. Always 1 if the shape is part of the left (west) box side. */
int *blank_leftward;
/** For each shape line 0..height-1, a flag which is 1 if all shapes to the right of this shape are blank on the
* same shape line. Always 1 if the shape is part of the right (east) box side. */
int *blank_rightward;
} sentry_t;
#define SENTRY_INITIALIZER (sentry_t) {NW, NULL, NULL, 0, 0, 0, NULL, NULL}
#define NUM_SHAPES 16
#define NUM_SIDES 4
#define NUM_CORNERS 4
typedef struct {
bxstr_t *search;
bxstr_t *repstr;
pcre2_code *prog; /* compiled search pattern */
int line; /* line of definition in config file */
char mode; /* 'g' or 'o' */
} reprule_t;
typedef struct {
char *name; /* primary name of the box design */
char **aliases; /* zero-terminated array of alias names of the design */
bxstr_t *author; /* creator of the configuration file entry */
bxstr_t *designer; /* creator of the original ASCII artwork */
bxstr_t *created; /* date created, free format */
char *revision; /* revision number of design */
bxstr_t *revdate; /* date of current revision */
bxstr_t *sample; /* the complete sample block in one string */
char indentmode; /* 'b', 't', or 'n' */
sentry_t shape[NUM_SHAPES];
size_t maxshapeheight; /* height of highest shape in design */
size_t minwidth;
size_t minheight;
int padding[NUM_SIDES];
char **tags;
bxstr_t *defined_in; /* path to config file where this was defined */
reprule_t *current_rule;
reprule_t *reprules; /* applied when drawing a box */
size_t anz_reprules;
reprule_t *revrules; /* applied upon removal of a box */
size_t anz_revrules;
} design_t;
extern design_t *designs;
extern int num_designs;
typedef struct { /* Command line options: */
char valign; /** `-a`: text position inside box */
char halign; /** `-a`: ( h[lcr]v[tcb] ) */
char justify; /** `-a`: 'l', 'c', 'r', or '\0' */
char *cld; /** `-c`: commandline design definition */
int color; /** `--color` or `--no-color`: `force_monochrome`, `color_from_terminal`, or `force_ansi_color` */
design_t *design; /** `-d`: currently used box design */
int design_choice_by_user; /** `-d`, `-c`: true if design was chosen by user */
char *eol; /** `-e`: line break to use. Never NULL, default to "\n". */
int eol_overridden; /** `-e`: 0: value in `eol` is the default; 1: value in `eol` specified via `-e` */
char *f; /** `-f`: config file path */
int help; /** `-h`: flags if help argument was specified */
char indentmode; /** `-i`: 'b', 't', 'n', or '\0' */
int killblank; /** `-k`: kill blank lines, -1 if not set */
int l; /** `-l`: list available designs */
int mend; /** `-m`: 1 if -m is given, 2 in 2nd loop */
char *encoding; /** `-n`: character encoding override for input and output text */
int padding[NUM_SIDES]; /** `-p`: in spaces or lines resp. */
char **query; /** `-q`: parsed tag query expression passed in via -q; also, special handling of web UI needs */
int r; /** `-r`: remove box from input */
long reqwidth; /** `-s`: requested box width */
long reqheight; /** `-s`: requested box height */
int tabstop; /** `-t`: tab stop distance */
char tabexp; /** `-t`: tab expansion mode (for leading tabs) */
int version_requested; /** `-v`: request to show version number */
FILE *infile;
FILE *outfile;
} opt_t;
extern opt_t opt;
/* The possible values of the `color` field from `opt_t`: */
#define force_monochrome 0
#define color_from_terminal 1
#define force_ansi_color 2
/** Flag indicating if ANSI color codes should be printed (1) or not (0) */
extern int color_output_enabled;
typedef struct {
bxstr_t *text; /* text content of the line as a boxes string */
uint32_t *cache_visible; /* only the visible characters of `text`, initially NULL. This is a cache. */
size_t *tabpos; /* tab positions in expanded work strings, or NULL if not needed */
size_t tabpos_len; /* number of tabs in a line */
} line_t;
typedef struct {
line_t *lines;
size_t num_lines; /* number of entries in input */
size_t maxline; /* length in columns of longest input line */
size_t indent; /* common number of leading spaces found in all input lines */
int final_newline; /* true if the last line of input ends with newline */
} input_t;
extern input_t input;
#endif /* BOXES_H */
/* vim: set cindent sw=4: */