/* $LynxId: LYrcFile.c,v 1.107 2022/04/02 00:12:18 Paul.G.Fox Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #define MSG_ENABLE_LYNXRC N_("Normally disabled. See ENABLE_LYNXRC in lynx.cfg\n") #define putBool(value) ((value) ? "on" : "off") /* *INDENT-OFF* */ static Config_Enum tbl_DTD_recovery[] = { { "true", TRUE }, { "false", FALSE }, { "on", TRUE }, { "off", FALSE }, { "sortasgml", TRUE }, { "tagsoup", FALSE }, { NULL, -1 }, }; static Config_Enum tbl_HTTP_protocol[] = { { "1.0", HTTP_1_0 }, { "1.1", HTTP_1_1 }, { NULL, -1 }, }; static Config_Enum tbl_bad_html[] = { { "ignore", BAD_HTML_IGNORE }, { "trace", BAD_HTML_TRACE }, { "message", BAD_HTML_MESSAGE }, { "warn", BAD_HTML_WARN }, { NULL, -1 } }; #ifdef DIRED_SUPPORT static Config_Enum tbl_dir_list_style[] = { { "FILES_FIRST", FILES_FIRST }, { "DIRECTORIES_FIRST", DIRS_FIRST }, { "MIXED_STYLE", MIXED_STYLE }, { NULL, MIXED_STYLE }, }; #ifdef LONG_LIST static Config_Enum tbl_dir_list_order[] = { { "ORDER_BY_NAME", ORDER_BY_NAME }, { "ORDER_BY_TYPE", ORDER_BY_TYPE }, { "ORDER_BY_SIZE", ORDER_BY_SIZE }, { "ORDER_BY_DATE", ORDER_BY_DATE }, { "ORDER_BY_MODE", ORDER_BY_MODE }, #ifndef NO_GROUPS { "ORDER_BY_USER", ORDER_BY_USER }, { "ORDER_BY_GROUP", ORDER_BY_GROUP }, #endif { NULL, ORDER_BY_NAME }, }; #endif /* LONG_LIST */ #endif /* DIRED_SUPPORT */ static Config_Enum tbl_file_sort[] = { { "BY_FILENAME", FILE_BY_NAME }, { "BY_TYPE", FILE_BY_TYPE }, { "BY_SIZE", FILE_BY_SIZE }, { "BY_DATE", FILE_BY_DATE }, { NULL, -1 }, }; #ifdef USE_IDN2 static Config_Enum tbl_idna_mode[] = { { "IDNA2003", LYidna2003 }, { "IDNA2008", LYidna2008 }, { "TR46", LYidnaTR46 }, { "Compatible", LYidnaCompat }, { NULL, -1 }, }; #endif Config_Enum tbl_keypad_mode[] = { { "FIELDS_ARE_NUMBERED", FIELDS_ARE_NUMBERED }, { "LINKS_AND_FIELDS_ARE_NUMBERED", LINKS_AND_FIELDS_ARE_NUMBERED }, { "LINKS_ARE_NUMBERED", LINKS_ARE_NUMBERED }, { "LINKS_ARE_NOT_NUMBERED", NUMBERS_AS_ARROWS }, /* obsolete variations: */ { "LINKS_AND_FORM_FIELDS_ARE_NUMBERED", LINKS_AND_FIELDS_ARE_NUMBERED }, { "NUMBERS_AS_ARROWS", NUMBERS_AS_ARROWS }, { NULL, DEFAULT_KEYPAD_MODE } }; Config_Enum tbl_multi_bookmarks[] = { { "OFF", MBM_OFF }, { "STANDARD", MBM_STANDARD }, { "ON", MBM_STANDARD }, { "ADVANCED", MBM_ADVANCED }, { NULL, -1 } }; Config_Enum tbl_preferred_content[] = { { STR_BINARY, contentBINARY }, { STR_PLAINTEXT, contentTEXT }, { STR_HTML, contentHTML }, { NULL, -1 } }; /* the names in this table are used as lowercase in HTTP.c */ Config_Enum tbl_preferred_encoding[] = { { "none", encodingNONE }, #if defined(USE_ZLIB) || defined(GZIP_PATH) { "gzip", encodingGZIP }, { "deflate", encodingDEFLATE }, #endif #if defined(USE_ZLIB) || defined(COMPRESS_PATH) { "compress", encodingCOMPRESS }, #endif #if defined(USE_BZLIB) || defined(BZIP2_PATH) { "bzip2", encodingBZIP2 }, #endif #if defined(USE_BROTLI) || defined(BROTLI_PATH) { "br", encodingBROTLI }, #endif { "all", encodingALL }, { NULL, -1 } }; Config_Enum tbl_preferred_media[] = { { "INTERNAL", mediaOpt1 }, { "CONFIGFILE", mediaOpt2 }, { "USER", mediaOpt3 }, { "SYSTEM", mediaOpt4 }, { "ALL", mediaALL }, { NULL, -1 } }; static Config_Enum tbl_show_colors[] = { { "default", SHOW_COLOR_UNKNOWN }, { "default", SHOW_COLOR_OFF }, { "default", SHOW_COLOR_ON }, { "on", SHOW_COLOR_UNKNOWN }, { "off", SHOW_COLOR_UNKNOWN }, { "never", SHOW_COLOR_NEVER }, { "always", SHOW_COLOR_ALWAYS }, { NULL, SHOW_COLOR_UNKNOWN } }; Config_Enum tbl_transfer_rate[] = { { "NONE", rateOFF }, { "KB", rateKB }, { "TRUE", rateKB }, { "BYTES", rateBYTES }, { "FALSE", rateBYTES }, #ifdef USE_READPROGRESS { "KB,ETA", rateEtaKB }, { "BYTES,ETA", rateEtaBYTES }, { "KB2,ETA", rateEtaKB2 }, { "BYTES2,ETA", rateEtaBYTES2 }, #endif #ifdef USE_PROGRESSBAR { "METER", rateBAR }, { "FALSE", rateBAR }, #endif { NULL, -1 }, }; Config_Enum tbl_user_mode[] = { { "MINIMAL", MINIMAL_MODE }, { "ADVANCED", ADVANCED_MODE }, { "INTERMEDIATE", INTERMEDIATE_MODE }, { "NOVICE", NOVICE_MODE }, { NULL, NOVICE_MODE } }; static Config_Enum tbl_visited_links[] = { { "FIRST_REVERSED", VISITED_LINKS_AS_FIRST_V | VISITED_LINKS_REVERSE }, { "FIRST", VISITED_LINKS_AS_FIRST_V }, { "TREE", VISITED_LINKS_AS_TREE }, { "LAST_REVERSED", VISITED_LINKS_AS_LATEST | VISITED_LINKS_REVERSE }, { "LAST", VISITED_LINKS_AS_LATEST }, { NULL, DEFAULT_VISITED_LINKS } }; Config_Enum tbl_cookie_version[] = { { "RFC-2109", COOKIES_RFC_2109 }, { "RFC-2965", COOKIES_RFC_2965 }, { "RFC-6265", COOKIES_RFC_6265 }, { NULL, -1 } }; Config_Enum tbl_force_prompt[] = { { "prompt", FORCE_PROMPT_DFT }, { "yes", FORCE_PROMPT_YES }, { "no", FORCE_PROMPT_NO }, { NULL, -1 } }; /* *INDENT-ON* */ static BOOL getBool(char *src) { return (BOOL) (!strncasecomp(src, "on", 2) || !strncasecomp(src, "true", 4)); } const char *LYputEnum(Config_Enum * table, int value) { while (table->name != 0) { if (table->value == value) { return table->name; } table++; } return "?"; } BOOL LYgetEnum(Config_Enum * table, const char *name, int *result) { Config_Enum *found = 0; unsigned len = (unsigned) strlen(name); int match = 0; if (len != 0) { while (table->name != 0) { if (!strncasecomp(table->name, name, (int) len)) { found = table; if (!strcasecomp(table->name, name)) { match = 1; break; } ++match; } table++; } if (match == 1) { /* if unambiguous */ *result = found->value; return TRUE; } } CTRACE((tfp, "LYgetEnum: no match found for \"%s\"\n", name)); return FALSE; /* no match */ } /* these are for data that are normally not read/written from .lynxrc */ #define PARSE_SET(n,v,h) {n, 1, CONF_BOOL, UNION_SET(v), 0, 0, 0, h} #define PARSE_ARY(n,v,t,h) {n, 1, CONF_ARRAY, UNION_INT(v), t, 0, 0, h} #define PARSE_ENU(n,v,t,h) {n, 1, CONF_ENUM, UNION_INT(v), 0, t, 0, h} #define PARSE_LIS(n,v,h) {n, 1, CONF_LIS, UNION_STR(v), 0, 0, 0, h} #define PARSE_STR(n,v,h) {n, 1, CONF_STR, UNION_STR(v), 0, 0, 0, h} #define PARSE_FUN(n,v,w,h) {n, 1, CONF_FUN, UNION_FUN(v), 0, 0, w, h} #define PARSE_MBM(n,h) {n, 1, CONF_MBM, UNION_DEF(0), 0, 0, 0, h} /* these are for data that are optionally read/written from .lynxrc */ #define MAYBE_SET(n,v,h) {n, 0, CONF_BOOL, UNION_SET(v), 0, 0, 0, h} #define MAYBE_ARY(n,v,t,h) {n, 0, CONF_ARRAY, UNION_INT(v), t, 0, 0, h} #define MAYBE_ENU(n,v,t,h) {n, 0, CONF_ENUM, UNION_INT(v), 0, t, 0, h} #define MAYBE_LIS(n,v,h) {n, 0, CONF_LIS, UNION_STR(v), 0, 0, 0, h} #define MAYBE_STR(n,v,h) {n, 0, CONF_STR, UNION_STR(v), 0, 0, 0, h} #define MAYBE_FUN(n,v,w,h) {n, 0, CONF_FUN, UNION_FUN(v), 0, 0, w, h} #define MAYBE_MBM(n,h) {n, 0, CONF_MBM, UNION_DEF(0), 0, 0, 0, h} #define PARSE_NIL {NULL, 1, CONF_NIL, UNION_DEF(0), 0, 0, 0, 0} typedef enum { CONF_NIL = 0 ,CONF_ARRAY ,CONF_BOOL ,CONF_FUN ,CONF_INT ,CONF_ENUM ,CONF_LIS ,CONF_MBM ,CONF_STR } Conf_Types; typedef struct config_type { const char *name; int enabled; /* see lynx.cfg ENABLE_LYNXRC "off" lines */ Conf_Types type; ParseData; const char **strings; Config_Enum *table; void (*write_it) (FILE *fp, struct config_type *); const char *note; } Config_Type; static int get_assume_charset(char *value) { int i; for (i = 0; i < LYNumCharsets; ++i) { if (!strcasecomp(value, LYCharSet_UC[i].MIMEname)) { UCLYhndl_for_unspec = i; break; } } return 0; } static void put_assume_charset(FILE *fp, struct config_type *tbl) { int i; for (i = 0; i < LYNumCharsets; ++i) fprintf(fp, "# %s\n", LYCharSet_UC[i].MIMEname); fprintf(fp, "%s=%s\n\n", tbl->name, LYCharSet_UC[UCLYhndl_for_unspec].MIMEname); } static int get_display_charset(char *value) { int i = 0; i = UCGetLYhndl_byAnyName(value); /* by MIME or full name */ if (i >= 0) current_char_set = i; return 0; } static void put_display_charset(FILE *fp, struct config_type *tbl) { int i; for (i = 0; LYchar_set_names[i]; i++) fprintf(fp, "# %s\n", LYchar_set_names[i]); fprintf(fp, "%s=%s\n\n", tbl->name, LYchar_set_names[current_char_set]); } static int get_editor(char *value) {
#
#
#           The Nim Compiler
#        (c) Copyright 2012 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

## This module contains the data structures for the C code generation phase.

import
  ast, astalgo, ropes, passes, options, intsets, platform, sighashes,
  tables, ndi

from msgs import TLineInfo

type
  TLabel* = Rope              # for the C generator a label is just a rope
  TCFileSection* = enum       # the sections a generated C file consists of
    cfsMergeInfo,             # section containing merge information
    cfsHeaders,               # section for C include file headers
    cfsForwardTypes,          # section for C forward typedefs
    cfsTypes,                 # section for C typedefs
    cfsSeqTypes,              # section for sequence types only
                              # this is needed for strange type generation
                              # reasons
    cfsFieldInfo,             # section for field information
    cfsTypeInfo,              # section for type information
    cfsProcHeaders,           # section for C procs prototypes
    cfsVars,                  # section for C variable declarations
    cfsData,                  # section for C constant data
    cfsProcs,                 # section for C procs that are not inline
    cfsInitProc,              # section for the C init proc
    cfsTypeInit1,             # section 1 for declarations of type information
    cfsTypeInit2,             # section 2 for init of type information
    cfsTypeInit3,             # section 3 for init of type information
    cfsDebugInit,             # section for init of debug information
    cfsDynLibInit,            # section for init of dynamic library binding
    cfsDynLibDeinit           # section for deinitialization of dynamic
                              # libraries
  TCTypeKind* = enum          # describes the type kind of a C type
    ctVoid, ctChar, ctBool,
    ctInt, ctInt8, ctInt16, ctInt32, ctInt64,
    ctFloat, ctFloat32, ctFloat64, ctFloat128,
    ctUInt, ctUInt8, ctUInt16, ctUInt32, ctUInt64,
    ctArray, ctPtrToArray, ctStruct, ctPtr, ctNimStr, ctNimSeq, ctProc,
    ctCString
  TCFileSections* = array[TCFileSection, Rope] # represents a generated C file
  TCProcSection* = enum       # the sections a generated C proc consists of
    cpsLocals,                # section of local variables for C proc
    cpsInit,                  # section for init of variables for C proc
    cpsStmts                  # section of local statements for C proc
  TCProcSections* = array[TCProcSection, Rope] # represents a generated C proc
  BModule* = ref TCGen
  BProc* = ref TCProc
  TBlock* = object
    id*: int                  # the ID of the label; positive means that it
    label*: Rope              # generated text for the label
                              # nil if label is not used
    sections*: TCProcSections # the code beloging
    isLoop*: bool             # whether block is a loop
    nestedTryStmts*: int16    # how many try statements is it nested into
    nestedExceptStmts*: int16 # how many except statements is it nested into
    frameLen*: int16

  TCProc = object             # represents C proc that is currently generated
    prc*: PSym                # the Nim proc that this C proc belongs to
    beforeRetNeeded*: bool    # true iff 'BeforeRet' label for proc is needed
    threadVarAccessed*: bool  # true if the proc already accessed some threadvar
    lastLineInfo*: TLineInfo  # to avoid generating excessive 'nimln' statements
    currLineInfo*: TLineInfo  # AST codegen will make this superfluous
    nestedTryStmts*: seq[tuple[n: PNode, inExcept: bool]]
                              # in how many nested try statements we are
                              # (the vars must be volatile then)
                              # bool is true when are in the except part of a try block
    finallySafePoints*: seq[Rope]  # For correctly cleaning up exceptions when
                                   # using return in finally statements
    labels*: Natural          # for generating unique labels in the C proc
    blocks*: seq[TBlock]      # nested blocks
    breakIdx*: int            # the block that will be exited
                              # with a regular break
    options*: TOptions        # options that should be used for code
                              # generation; this is the same as prc.options
                              # unless prc == nil
    maxFrameLen*: int         # max length of frame descriptor
    module*: BModule          # used to prevent excessive parameter passing
    withinLoop*: int          # > 0 if we are within a loop
    splitDecls*: int          # > 0 if we are in some context for C++ that
                              # requires 'T x = T()' to become 'T x; x = T()'
                              # (yes, C++ is weird like that)
    gcFrameId*: Natural       # for the GC stack marking
    gcFrameType*: Rope        # the struct {} we put the GC markers into
    sigConflicts*: CountTable[string]

  TTypeSeq* = seq[PType]
  TypeCache* = Table[SigHash, Rope]

  Codegenflag* = enum
    preventStackTrace,  # true if stack traces need to be prevented
    usesThreadVars,     # true if the module uses a thread var
    frameDeclared,      # hack for ROD support so that we don't declare
                        # a frame var twice in an init proc
    isHeaderFile,       # C source file is the header file
    includesStringh,    # C source file already includes ``<string.h>``
    objHasKidsValid     # whether we can rely on tfObjHasKids


  BModuleList* = ref object of RootObj
    mainModProcs*, mainModInit*, otherModsInit*, mainDatInit*: Rope
    mapping*: Rope             # the generated mapping file (if requested)
    modules*: seq[BModule]     # list of all compiled modules
    forwardedProcsCounter*: int
    generatedHeader*: BModule
    breakPointId*: int
    breakpoints*: Rope # later the breakpoints are inserted into the main proc
    typeInfoMarker*: TypeCache
    config*: ConfigRef
    strVersion*, seqVersion*: int # version of the string/seq implementation to use

  TCGen =