<commit_before>﻿using Pchp.Core;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace Pchp.Library
{
    /// <summary>
    /// Manages association of PHP option names and flags.
    /// </summary>
    [PhpHidden]
    public static class StandardPhpOptions
    {
        public delegate PhpValue GetSetDelegate(Context ctx, IPhpConfigurationService config, string option, PhpValue value, IniAction action);

        /// <summary>
        /// An action which can be performed on option.
        /// </summary>
        public enum IniAction
        {
            Set, Get
        }

        public static bool IsGet(this IniAction action) => action == IniAction.Get;

        public static bool IsSet(this IniAction action) => action == IniAction.Set;

        [Flags]
        public enum IniFlags : byte
        {
            Unsupported = 0,
            Global = 0,

            Supported = 1,
            Local = 2,
            Http = 4,
        }

        [Flags]
        public enum IniAccessability
        {
            User = 1,
            PerDirectory = 2,
            System = 4,
            All = 7,

            Global = PerDirectory | System,
            Local = All
        }

        /// <summary>
        /// Holds information about the standard PHP option.
        /// </summary>
        public struct OptionDefinition
        {
            public readonly IniFlags Flags;
            public readonly GetSetDelegate Gsr;
            public readonly string Extension;

            internal OptionDefinition(IniFlags flags, GetSetDelegate gsr, string extension)
            {
                this.Flags = flags;
                this.Gsr = gsr;
                this.Extension = extension;
            }
        }

        /// <summary>
        /// Provides state, definition and values of an option.
        /// </summary>
        public struct OptionDump
        {
            /// <summary>
            /// Option PHP name.
            /// </summary>
            public string Name;

            /// <summary>
            /// Corresponding extension name.
            /// </summary>
            public string ExtensionName => Definition.Extension;

            /// <summary>
            /// Internal option definition.
            /// </summary>
            public OptionDefinition Definition;

            /// <summary>
            /// Actual option value.
            /// </summary>
            public PhpValue
                LocalValue,
                DefaultValue;
        }

        static readonly GetSetDelegate s_emptyGsr = new GetSetDelegate((ctx, s, name, value, action) => PhpValue.Null);

        static void AssertGet(string option, IniAction action)
        {
            if (action != IniAction.Get)
            {
                PhpException.ArgumentValueNotSupported(option, action);
            }
        }

        static PhpValue GsrCore(Context ctx, IPhpConfigurationService config, string option, PhpValue value, IniAction action)
        {
            switch (option.ToLowerInvariant())
            {
                case "precision":
                    // TODO: this can be set in .NET <see cref="Core.Convert.ToString(double, Context)"/> by specifying "G{precision}", consider performance
                    AssertGet(option, action);
                    return (PhpValue)15;    // default Double precision in .NET
                case "allow_url_fopen":
                    return (PhpValue)GetSet(ref config.Core.AllowUrlFopen, true, value, action);
                case "include_path":
                    return (PhpValue)GetSet(ref config.Core.IncludePaths, ".", value, action);
                case "allow_url_include":
                    AssertGet(option, action);
                    return PhpValue.False;

                case "disable_functions":
                case "disable_classes":
                    AssertGet(option, action);
                    return (PhpValue)string.Empty;

                case "memory_limit":
                    AssertGet(option, action);
                    return (PhpValue)(-1); // no memory limit

                case "post_max_size":
                case "upload_max_filesize":
                    AssertGet(option, action);
                    return (PhpValue)ctx.HttpPhpContext.MaxRequestSize;

                case "docref_root":
                    return (PhpValue)GetSet(ref config.Core.docref_root, "", value, action);
                case "docref_ext":
                    return (PhpValue)GetSet(ref config.Core.docref_ext, "", value, action);<commit_msg>'post_max_size' and 'upload_max_filesize' on cli nullref fix<commit_after>﻿using Pchp.Core;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace Pchp.Library
{
    /// <summary>
    /// Manages association of PHP option names and flags.
    /// </summary>
    [PhpHidden]
    public static class StandardPhpOptions
    {
        public delegate PhpValue GetSetDelegate(Context ctx, IPhpConfigurationService config, string option, PhpValue value, IniAction action);

        /// <summary>
        /// An action which can be performed on option.
        /// </summary>
        public enum IniAction
        {
            Set, Get
        }

        public static bool IsGet(this IniAction action) => action == IniAction.Get;

        public static bool IsSet(this IniAction action) => action == IniAction.Set;

        [Flags]
        public enum IniFlags : byte
        {
            Unsupported = 0,
            Global = 0,

            Supported = 1,
            Local = 2,
            Http = 4,
        }

        [Flags]
        public enum IniAccessability
        {
            User = 1,
            PerDirectory = 2,
            System = 4,
            All = 7,

            Global = PerDirectory | System,
            Local = All
        }

        /// <summary>
        /// Holds information about the standard PHP option.
        /// </summary>
        public struct OptionDefinition
        {
            public readonly IniFlags Flags;
            public readonly GetSetDelegate Gsr;
            public readonly string Extension;

            internal OptionDefinition(IniFlags flags, GetSetDelegate gsr, string extension)
            {
                this.Flags = flags;
                this.Gsr = gsr;
                this.Extension = extension;
            }
        }

        /// <summary>
        /// Provides state, definition and values of an option.
        /// </summary>
        public struct OptionDump
        {
            /// <summary>
            /// Option PHP name.
            /// </summary>
            public string Name;

            /// <summary>
            /// Corresponding extension name.
            /// </summary>
            public string ExtensionName => Definition.Extension;

            /// <summary>
            /// Internal option definition.
            /// </summary>
            public OptionDefinition Definition;

            /// <summary>
            /// Actual option value.
            /// </summary>
            public PhpValue
                LocalValue,
                DefaultValue;
        }

        static readonly GetSetDelegate s_emptyGsr = new GetSetDelegate((ctx, s, name, value, action) => PhpValue.Null);

        static void AssertGet(string option, IniAction action)
        {
            if (action != IniAction.Get)
            {
                PhpException.ArgumentValueNotSupported(option, action);
            }
        }

        static PhpValue GsrCore(Context ctx, IPhpConfigurationService config, string option, PhpValue value, IniAction action)
        {
            switch (option.ToLowerInvariant())
            {
                case "precision":
                    // TODO: this can be set in .NET <see cref="Core.Convert.ToString(double, Context)"/> by specifying "G{precision}", consider performance
                    AssertGet(option, action);
                    return (PhpValue)15;    // default Double precision in .NET
                case "allow_url_fopen":
                    return (PhpValue)GetSet(ref config.Core.AllowUrlFopen, true, value, action);
                case "include_path":
                    return (PhpValue)GetSet(ref config.Core.IncludePaths, ".", value, action);
                case "allow_url_include":
                    AssertGet(option, action);
                    return PhpValue.False;

                case "disable_functions":
                case "disable_classes":
                    AssertGet(option, action);
                    return (PhpValue)string.Empty;

                case "memory_limit":
                    AssertGet(option, action);
                    return (PhpValue)(-1); // no memory limit

                case "post_max_size":
                case "upload_max_filesize":
                    AssertGet(option, action);
                    return ctx.HttpPhpContext != null ? ctx.HttpPhpContext.MaxRequestSize : (8_000_000/*cli mode, just return something*/);

                case "docref_root":
                    return (PhpValue)GetSet(ref config.Core.docref_root, "", value, action);
                case "docref_ext":
                    return (PhpValue)GetSet(ref config.Core.docref_ext, "", value, action);
{'fraction_non_alphanumeric': 0.09053147300031952, 'fraction_numerical': 0.0033017360741293003, 'mean_word_length': 1.4801901743264658, 'pattern_counts': {'":': 22, '<': 37, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5263420', 'n_tokens_mistral': 2378, 'n_tokens_neox': 2247, 'n_words': 634}