4chan/lib/ini.php
2025-04-17 14:46:47 -05:00

124 lines
2.8 KiB
PHP

<?php
// The description of the INI format
$INI_PATTERN = '/^[ \t]*([A-Z0-9_-]+)[ \t]*=[ \t]*((?:[^\r\n]|(?<=\\\\)[\r\n]{1,2})*)/m';
// Global config dir absolute folder (no trailing slash)
$configdir = '/www/global/yotsuba/config';
$yconfgdir = '/www/global/yotsuba/config';
function parse_ini( $filename )
{
global $INI_PATTERN;
$file = @file_get_contents( $filename );
if( !$file ) return array();
preg_match_all( $INI_PATTERN, $file, $matches, PREG_SET_ORDER );
$ret = array();
foreach( $matches as $match ) {
// replace backslash-newlines with newlines
$v = preg_replace( '|\\\\[\r\n]+|', "\n", $match[ 2 ] );
$v = ltrim( $v );
$ret[ $match[ 1 ] ] = $v;
}
return $ret;
}
function write_constants( $new )
{
global $constants;
foreach( $new as $k => $v ) {
$constants[ $k ] = $v; // update the constants array
}
}
function load_ini( $filename )
{
global $constants, $INI_PATTERN, $loaded_files;
$file = file_get_contents( $filename );
preg_match_all( $INI_PATTERN, $file, $matches, PREG_SET_ORDER );
foreach( $matches as $match ) {
// replace backslash-newlines with newlines
$match[ 2 ] = preg_replace( '|\\\\[\r\n]+|', "\n", $match[ 2 ] );
$match[ 2 ] = ltrim( $match[ 2 ] );
$constants[ $match[ 1 ] ] = $match[ 2 ]; // update the constants array
}
$loaded_files[$filename] = 1;
}
function special_callback( $matches )
{
global $constants;
$val = str_replace( "!file ", "", $matches[ 1 ], $is_file );
if( $is_file ) {
return @file_get_contents( $val );
}
$val = str_replace( "!rand ", "", $matches[ 1 ], $is_rand );
if( $is_rand ) {
$choices = explode( ",", $val );
$val = array_rand( array_flip( $choices ) );
$val = trim( $val );
return $val;
}
return evaluate( $constants[ $val ] );
}
function evaluate( $val )
{
if( $val === 'yes' ) {
$val = true;
settype($val, "bool");
} else if( $val === 'no' ) {
$val = false;
settype($val, "bool");
} else {
$val = preg_replace_callback( '|\{\{(.*?)\}\}|', "special_callback", $val );
// for numeric values, try to keep the PHP internal type as 'int'
if (ctype_digit($val)) {
settype($val, "int");
}
}
return $val;
}
function finalize_constants()
{
global $constants;
$c2 = array();
foreach( $constants as $key => $val ) {
$val = evaluate( $val );
$c2[ $key ] = $val;
if( !defined( $key ) ) {
define( $key, $val );
}
}
$constants = $c2;
}
$constants = array();
$loaded_files = array();
// quick wrapper function
function load_ini_file( $filename )
{
global $loaded_files, $configdir, $constants;
if( strpos( $filename, '/' ) !== 0 ) $filename = "$configdir/$filename";
if( in_array( $filename, $loaded_files ) ) return;
$constants = array();
load_ini($filename);
finalize_constants();
}