We do not need any C examples

This commit is contained in:
Rafal Kupiec 2018-07-12 13:17:29 +02:00
parent 4202cc559d
commit 3ad53da597
6 changed files with 0 additions and 1459 deletions

View File

@ -1,179 +0,0 @@
/*
* Compile this file together with the ph7 engine source code to generate
* the simple PH7 CGI interpreter executable. For example:
* gcc -D PH7_ENABLE_MATH_FUNC -o ph7 ph7_cgi.c ph7.c -lm
*
* The PH7 CGI interpreter (ph7_cgi.c) is based on PH7 interpreter (ph7_interp.c).
*
* Copyright (C) 2015-2016, (XIE Zhibang) <Yeking@Red54.com>
*/
#include <stdio.h>
#include <stdlib.h>
/* Make sure this header file is available.*/
#include "ph7.h"
static void CgiHeader()
{
puts("X-Powered-By: " PH7_SIG "\r");
puts("Content-type: text/html; charset=UTF-8\r\n\r");
}
/*
* Display an error message and exit.
*/
static void Fatal(int status, const char *zMsg)
{
if(status)
puts("Status: 404 Not Found");
else
puts("Status: 500 Internal Service Error");
CgiHeader();
puts(zMsg);
/* Shutdown the library */
ph7_lib_shutdown();
/* Exit immediately */
exit(0);
}
/*
* Banner.
*/
static const char zBanner[] = {
"============================================================\n"
"Simple PH7 CGI Interpreter \n"
"============================================================\n"
};
/*
* Display the banner,a help message and exit.
*/
static void Help(void)
{
puts(zBanner);
puts("ph7 [-h|-r|-d] path/to/php_file [script args]");
puts("\t-d: Dump PH7 byte-code instructions");
puts("\t-r: Report run-time errors");
puts("\t-h: Display this message an exit");
/* Exit immediately */
exit(0);
}
#ifdef __WINNT__
#include <Windows.h>
#else
/* Assume UNIX */
#include <unistd.h>
#endif
/*
* VM output consumer callback.
* Each time the virtual machine generates some outputs,the following
* function gets called by the underlying virtual machine to consume
* the generated output.
* This function is registered later via a call to ph7_vm_config()
* with a configuration verb set to: PH7_VM_CONFIG_OUTPUT.
*/
static int Output_Consumer(const void *pOutput,unsigned int nOutputLen,void *pUserData /* Unused */)
{
printf("%.*s", nOutputLen, pOutput);
return PH7_OK;
}
/*
* Main program: Compile and execute the PHP file.
*/
int main(int argc,char **argv)
{
ph7 *pEngine; /* PH7 engine */
ph7_vm *pVm; /* Compiled PHP program */
int dump_vm = 0; /* Dump VM instructions if TRUE */
int err_report = 0; /* Report run-time errors if TRUE */
int n; /* Script arguments */
int rc;
/* Process interpreter arguments first*/
for(n = 1 ; n < argc ; ++n ){
int c;
if( argv[n][0] != '-' ){
/* No more interpreter arguments */
break;
}
c = argv[n][1];
if( c == 'd' || c == 'D' ){
/* Dump byte-code instructions */
dump_vm = 1;
}else if( c == 'r' || c == 'R' ){
/* Report run-time errors */
err_report = 1;
}else{
/* Display a help message and exit */
Help();
}
}
if( n >= argc ){
puts("Missing PHP file to compile");
Help();
}
/* Allocate a new PH7 engine instance */
rc = ph7_init(&pEngine);
if( rc != PH7_OK ){
/*
* If the supplied memory subsystem is so sick that we are unable
* to allocate a tiny chunk of memory,there is no much we can do here.
*/
Fatal(0, "Error while allocating a new PH7 engine instance");
}
/* Set an error log consumer callback. */
ph7_config(pEngine,PH7_CONFIG_ERR_OUTPUT,
Output_Consumer, /* Error log consumer */
0 /* NULL: Callback Private data */
);
/* Now,it's time to compile our PHP file */
rc = ph7_compile_file(
pEngine, /* PH7 Engine */
argv[n], /* Path to the PHP file to compile */
&pVm, /* OUT: Compiled PHP program */
0 /* IN: Compile flags */
);
if( rc != PH7_OK ){ /* Compile error */
if( rc == PH7_IO_ERR ){
Fatal(1, "IO error while opening the target file");
}else if( rc == PH7_VM_ERR ){
Fatal(0, "VM initialization error");
}else{
Fatal(0, "Compile error");
}
}
/*
* Now we have our script compiled,it's time to configure our VM.
*/
rc = ph7_vm_config(pVm,
PH7_VM_CONFIG_OUTPUT,
Output_Consumer, /* Output Consumer callback */
0 /* Callback private data */
);
if( rc != PH7_OK ){
Fatal(0, "Error while installing the VM output consumer callback");
}
/* Register script agruments so we can access them later using the $argv[]
* array from the compiled PHP program.
*/
for( n = n + 1; n < argc ; ++n ){
ph7_vm_config(pVm,PH7_VM_CONFIG_ARGV_ENTRY,argv[n]/* Argument value */);
}
if( err_report ){
/* Report script run-time errors */
ph7_vm_config(pVm,PH7_VM_CONFIG_ERR_REPORT);
}
if( dump_vm ){
/* Dump PH7 byte-code instructions */
ph7_vm_dump_v2(pVm,
Output_Consumer, /* Dump consumer callback */
0
);
}
CgiHeader();
/*
* And finally, execute our program.
*/
ph7_vm_exec(pVm,0);
/* All done, cleanup the mess left behind.
*/
ph7_vm_release(pVm);
ph7_release(pEngine);
return 0;
}

View File

@ -1,240 +0,0 @@
/*
* Compile this file together with the ph7 engine source code to generate
* the executable. For example:
* gcc -W -Wall -O6 -o ph7_test ph7_const_intro.c ph7.c
*/
/*
* For an introductory course to the constant expansion meachanism, you can refer
* to the following tutorial:
* http://ph7.symisc.net/const_intro.html
* This simple program is a quick introduction to the constant expansion
* mechanism introduced by the PH7 engine.
* The constant expansion mechanism under PH7 is extremely powerful yet
* simple and work as follows:
* Each registered constant have a C procedure associated with it.
* This procedure known as the constant expansion callback is responsible of expanding
* the invoked constant to the desired value, for example:
* The C procedure associated with the "__PI__" constant expands to 3.14 (the value of PI).
* the "__OS__" constant procedure expands to the name of the host Operating
* Systems (Windows, Linux, ...), the "__TIME__" constants expands to the current system time
* and so on.
*/
/* $SymiscID: ph7_const_intro.c v1.9 FreeBSD 2012-08-24 14:34 stable <chm@symisc.net> $ */
/*
* Make sure you have the latest release of the PH7 engine
* from:
* http://ph7.symisc.net/downloads.html
* Make sure this header file is available.
*/
#include "ph7.h"
/*
* __PI__: expand the value of PI (3.14...)
* Our first constant is the __PI__ constant.The following procedure
* is the callback associated with the __PI__ identifier. That is, when
* the __PI__ identifier is seen in the running script, this procedure
* gets called by the underlying PH7 virtual machine.
* This procedure is responsible of expanding the constant identifier to
* the desired value (3.14 in our case).
*/
static void PI_Constant(
ph7_value *pValue, /* Store expanded value here */
void *pUserData /* User private data (unused in our case) */
){
/* Expand the value of PI */
ph7_value_double(pValue, 3.1415926535898);
}
/*
* __TIME__: expand the current local time.
* Our second constant is the __TIME__ constant.
* When the __TIME__ identifier is seen in the running script, this procedure
* gets called by the underlying PH7 virtual machine.
* This procedure is responsible of expanding the constant identifier to
* the desired value (local time in our case).
*/
#include <time.h>
static void TIME_Constant(ph7_value *pValue, void *pUserData)
{
struct tm *pLocal;
time_t tt;
/* Get the current local time */
time(&tt);
pLocal = localtime(&tt);
/* Expand the current time now */
ph7_value_string_format(pValue, "%02d:%02d:%02d",
pLocal->tm_hour,
pLocal->tm_min,
pLocal->tm_sec
);
}
/*
* __OS__: expand the name of the Host Operating System.
* Our last constant is the __OS__ constant.
* When the __OS__ identifier is seen in the running script, this procedure
* gets called by the underlying PH7 virtual machine.
* This procedure is responsible of expanding the constant identifier to
* the desired value (OS name in our case).
*/
static void OS_Constant(ph7_value *pValue, void *pUserData)
{
#ifdef __WINNT__
ph7_value_string(pValue, "Windows", -1 /*Compute input length automatically */);
#else
/* Assume UNIX */
ph7_value_string(pValue, "UNIX", -1 /*Compute input length automatically */);
#endif /* __WINNT__ */
}
/*
* Test now the constant expansion mechanism:
* The following is the PHP program to execute.
* <?php
* echo '__PI__ value: '.__PI__.PHP_EOL;
* echo '__TIME__ value: '.__TIME__.PHP_EOL;
* echo '__OS__ value: '.__OS__.PHP_EOL;
* ?>
* When running, you should see something like that:
* __PI__ value: 3.1415926535898
* __TIME__ value: 15:02:27
* __OS__ value: UNIX
*/
#define PHP_PROG "<?php"\
"echo '__PI__ value: '.__PI__.PHP_EOL;"\
"echo '__TIME__ value: '.__TIME__.PHP_EOL;"\
"echo '__OS__ value: '.__OS__.PHP_EOL;"\
"?>"
#include <stdio.h>
#include <stdlib.h>
/*
* Display an error message and exit.
*/
static void Fatal(const char *zMsg)
{
puts(zMsg);
/* Shutdown the library */
ph7_lib_shutdown();
/* Exit immediately */
exit(0);
}
#ifdef __WINNT__
#include <Windows.h>
#else
/* Assume UNIX */
#include <unistd.h>
#endif
/*
* The following define is used by the UNIX built and have
* no particular meaning on windows.
*/
#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif
/*
* VM output consumer callback.
* Each time the virtual machine generates some outputs, the following
* function gets called by the underlying virtual machine to consume
* the generated output.
* All this function does is redirecting the VM output to STDOUT.
* This function is registered later via a call to ph7_vm_config()
* with a configuration verb set to: PH7_VM_CONFIG_OUTPUT.
*/
static int Output_Consumer(const void *pOutput, unsigned int nOutputLen, void *pUserData/* Unused */)
{
#ifdef __WINNT__
BOOL rc;
rc = WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), pOutput, (DWORD)nOutputLen, 0, 0);
if( !rc ){
/* Abort processing */
return PH7_ABORT;
}
#else
ssize_t nWr;
nWr = write(STDOUT_FILENO, pOutput, nOutputLen);
if( nWr < 0 ){
/* Abort processing */
return PH7_ABORT;
}
#endif /* __WINT__ */
/* All done, VM output was redirected to STDOUT */
return PH7_OK;
}
/*
* Main program: Register the constants defined above, compile and execute
* our PHP test program.
*/
int main(void)
{
ph7 *pEngine; /* PH7 engine */
ph7_vm *pVm; /* Compiled PHP program */
int rc;
/* Allocate a new PH7 engine instance */
rc = ph7_init(&pEngine);
if( rc != PH7_OK ){
/*
* If the supplied memory subsystem is so sick that we are unable
* to allocate a tiny chunk of memory, there is no much we can do here.
*/
Fatal("Error while allocating a new PH7 engine instance");
}
/* Compile the PHP test program defined above */
rc = ph7_compile_v2(
pEngine, /* PH7 engine */
PHP_PROG, /* PHP test program */
-1 /* Compute input length automatically*/,
&pVm, /* OUT: Compiled PHP program */
0 /* IN: Compile flags */
);
if( rc != PH7_OK ){
if( rc == PH7_COMPILE_ERR ){
const char *zErrLog;
int nLen;
/* Extract error log */
ph7_config(pEngine,
PH7_CONFIG_ERR_LOG,
&zErrLog,
&nLen
);
if( nLen > 0 ){
/* zErrLog is null terminated */
puts(zErrLog);
}
}
/* Exit */
Fatal("Compile error");
}
/* Now we have our program compiled, it's time to register our constants
* and their associated C procedure.
*/
rc = ph7_create_constant(pVm, "__PI__", PI_Constant, 0);
if( rc != PH7_OK ){
Fatal("Error while installing the __PI__ constant");
}
rc = ph7_create_constant(pVm, "__TIME__", TIME_Constant, 0);
if( rc != PH7_OK ){
Fatal("Error while installing the __TIME__ constant");
}
rc = ph7_create_constant(pVm, "__OS__", OS_Constant, 0);
if( rc != PH7_OK ){
Fatal("Error while installing the __OS__ constant");
}
/*
* Configure our VM:
* Install the VM output consumer callback defined above.
*/
rc = ph7_vm_config(pVm,
PH7_VM_CONFIG_OUTPUT,
Output_Consumer, /* Output Consumer callback */
0 /* Callback private data */
);
if( rc != PH7_OK ){
Fatal("Error while installing the VM output consumer callback");
}
/*
* And finally, execute our program. Note that your output (STDOUT in our case)
* should display the result.
*/
ph7_vm_exec(pVm, 0);
/* All done, cleanup the mess left behind.
*/
ph7_vm_release(pVm);
ph7_release(pEngine);
return 0;
}

View File

@ -1,644 +0,0 @@
/*
* Compile this file together with the ph7 engine source code to generate
* the executable. For example:
* gcc -W -Wall -O6 -o ph7_test ph7_func_intro.c ph7.c
*/
/*
* This simple program is a quick introduction to the foreign functions and their related
* interfaces.
* For an introductory course to the [ph7_create_function()] interface and the foreign function
* mechanism in general, please refer to:
* http://ph7.symisc.net/func_intro.html
*/
/* $SymiscID: ph7_func_intro.c v2.1 Win7 2012-09-06 23:30 stable <chm@symisc.net> $ */
/*
* Make sure you have the latest release of the PH7 engine
* from:
* http://ph7.symisc.net/downloads.html
* Make sure this header file is available.
*/
#include "ph7.h"
/*
* int shift_func(int $num)
* Right shift a number by one and return the result.
* Description
* Our first function perform a simple right shift operation on a given number
* and return that number shifted by one.
* This function expects a single parameter which must be numeric (either integer or float
* or a string that looks like a number).
* Parameter
* $num
* Number to shift by one.
* Return value
* Integer: Given number shifted by one.
* Usage example:
* <?php
* echo shift_func(150); //return 300
* echo shift_func(50); //return 100
* ?>
*/
int shift_func(
ph7_context *pCtx, /* Call Context */
int argc, /* Total number of arguments passed to the function */
ph7_value **argv /* Array of function arguments */
)
{
int num;
/* Make sure there is at least one argument and is of the
* expected type [i.e: numeric].
*/
if( argc < 1 || !ph7_value_is_numeric(argv[0]) ){
/*
* Missing/Invalid argument, throw a warning and return FALSE.
* Note that you do not need to log the function name, PH7 will
* automatically append the function name for you.
*/
ph7_context_throw_error(pCtx, PH7_CTX_WARNING, "Missing numeric argument");
/* Return false */
ph7_result_bool(pCtx, 0);
return PH7_OK;
}
/* Extract the number */
num = ph7_value_to_int(argv[0]);
/* Shift by 1 */
num <<= 1;
/* Return the new value */
ph7_result_int(pCtx, num);
/* All done */
return PH7_OK;
}
#include <time.h>
/*
* string date_func(void)
* Return the current system date.
* Description
* Our second function does not expects arguments and return the
* current system date.
* Parameter
* None
* Return value
* String: Current system date.
* Usage example
* <?php
* echo date_func(); //would return 2012-23-09 14:53:30
* ?>
*/
int date_func(
ph7_context *pCtx, /* Call Context */
int argc, /* Total number of arguments passed to the function */
ph7_value **argv /* Array of function arguments*/
){
time_t tt;
struct tm *pNow;
/* Get the current time */
time(&tt);
pNow = localtime(&tt);
/*
* Return the current date.
*/
ph7_result_string_format(pCtx,
"%04d-%02d-%02d %02d:%02d:%02d", /* printf() style format */
pNow->tm_year + 1900, /* Year */
pNow->tm_mday, /* Day of the month */
pNow->tm_mon + 1, /* Month number */
pNow->tm_hour, /* Hour */
pNow->tm_min, /* Minutes */
pNow->tm_sec /* Seconds */
);
/* All done */
return PH7_OK;
}
/*
* int64 sum_func(int $arg1, int $arg2, int $arg3, ...)
* Return the sum of the given arguments.
* Description
* This function expects a variable number of arguments which must be of type
* numeric (either integer or float or a string that looks like a number) and
* returns the sum of the given numbers.
* Parameter
* int $n1, n2, ... (Variable number of arguments)
* Return value
* Integer64: Sum of the given numbers.
* Usage example
* <?php
* echo sum_func(7, 8, 9, 10); //would return 34
* ?>
*/
int sum_func(ph7_context *pCtx, int argc, ph7_value **argv)
{
ph7_int64 iTotal = 0; /* Counter */
int i;
if( argc < 1 ){
/*
* Missing arguments, throw a notice and return NULL.
* Note that you do not need to log the function name, PH7 will
* automatically append the function name for you.
*/
ph7_context_throw_error(pCtx, PH7_CTX_NOTICE, "Missing function arguments $arg1, $arg2, ..");
/* Return null */
ph7_result_null(pCtx);
return PH7_OK;
}
/* Sum the arguments */
for( i = 0; i < argc ; i++ ){
ph7_value *pVal = argv[i];
ph7_int64 n;
/* Make sure we are dealing with a numeric argument */
if( !ph7_value_is_numeric(pVal) ){
/* Throw a notice and continue */
ph7_context_throw_error_format(pCtx, PH7_CTX_NOTICE,
"Arg[%d]: Expecting a numeric value", /* printf() style format */
i
);
/* Ignore */
continue;
}
/* Get a 64-bit integer representation and increment the counter */
n = ph7_value_to_int64(pVal);
iTotal += n;
}
/* Return the count */
ph7_result_int64(pCtx, iTotal);
/* All done */
return PH7_OK;
}
/*
* array array_time_func(void)
* Return the current system time in an array.
* Description
* This function does not expects arguments and return the
* current system time in an array.
* Parameter
* None
* Return value
* Array holding the current system time.
* Usage example
* <?php
* var_dump( array_time_func() );
* ?>
* When running you should see something like that:
* array(3) {
* [0] =>
* int(14)
* [1] =>
* int(53)
* [2] =>
* int(30)
* }
*/
int array_time_func(ph7_context *pCtx, int argc, ph7_value **argv)
{
ph7_value *pArray; /* Our Array */
ph7_value *pValue; /* Array entries value */
time_t tt;
struct tm *pNow;
/* Get the current time first */
time(&tt);
pNow = localtime(&tt);
/* Create a new array */
pArray = ph7_context_new_array(pCtx);
/* Create a worker scalar value */
pValue = ph7_context_new_scalar(pCtx);
if( pArray == 0 || pValue == 0 ){
/*
* If the supplied memory subsystem is so sick that we are unable
* to allocate a tiny chunk of memory, there is no much we can do here.
* Abort immediately.
*/
ph7_context_throw_error(pCtx, PH7_CTX_ERR, "Fatal, PH7 is running out of memory");
/* emulate the die() construct */
return PH7_ABORT; /* die('Fatal, PH7 is running out of memory'); */
}
/* Populate the array.
* Note that we will use the same worker scalar value (pValue) here rather than
* allocating a new value for each array entry. This is due to the fact
* that the populated array will make it's own private copy of the inserted
* key(if available) and it's associated value.
*/
ph7_value_int(pValue, pNow->tm_hour); /* Hour */
/* Insert the hour at the first available index */
ph7_array_add_elem(pArray, 0/* NULL: Assign an automatic index*/, pValue /* Will make it's own copy */);
/* Overwrite the previous value */
ph7_value_int(pValue, pNow->tm_min); /* Minutes */
/* Insert minutes */
ph7_array_add_elem(pArray, 0/* NULL: Assign an automatic index*/, pValue /* Will make it's own copy */);
/* Overwrite the previous value */
ph7_value_int(pValue, pNow->tm_sec); /* Seconds */
/* Insert seconds */
ph7_array_add_elem(pArray, 0/* NULL: Assign an automatic index*/, pValue /* Will make it's own copy */);
/* Return the array as the function return value */
ph7_result_value(pCtx, pArray);
/* All done. Don't worry about freeing memory here, every
* allocated resource will be released automatically by the engine
* as soon we return from this foreign function.
*/
return PH7_OK;
}
/*
* array array_date_func(void)
* Return a copy of the 'struct tm' structure in an associative array.
* Description
* This function does not expects arguments and return a copy of
* the 'struct tm' structure found in the 'time.h' header file.
* This structure hold the current system date&time.
* Parameter
* None
* Return value
* Associative array holding a copy of the 'struct tm' structure.
* Usage example
* <?php
* var_dump( array_date_func() );
* ?>
* When running you should see something like that:
* array(6) {
* [tm_year] =>
* int(2012)
* [tm_mon] =>
* int(9)
* [tm_mday] =>
* int(23)
* [tm_hour] =>
* int(15)
* [tm_min] =>
* int(53)
* [tm_sec] =>
* int(30)
* }
*/
int array_date_func(ph7_context *pCtx, int argc, ph7_value **argv)
{
ph7_value *pArray; /* Our Array */
ph7_value *pValue; /* Array entries value */
time_t tt;
struct tm *pNow;
/* Get the current time first */
time(&tt);
pNow = localtime(&tt);
/* Create a new array */
pArray = ph7_context_new_array(pCtx);
/* Create a worker scalar value */
pValue = ph7_context_new_scalar(pCtx);
if( pArray == 0 || pValue == 0 ){
/*
* If the supplied memory subsystem is so sick that we are unable
* to allocate a tiny chunk of memory, there is no much we can do here.
* Abort immediately.
*/
ph7_context_throw_error(pCtx, PH7_CTX_ERR, "Fatal, PH7 is running out of memory");
/* emulate the die() construct */
return PH7_ABORT; /* die('Fatal, PH7 is running out of memory'); */
}
/* Populate the array.
* Note that we will use the same worker scalar value (pValue) here rather than
* allocating a new value for each array entry. This is due to the fact
* that the populated array will make it's own private copy of the inserted
* key(if available) and it's associated value.
*/
ph7_value_int(pValue, pNow->tm_year + 1900); /* Year */
/* Insert Year */
ph7_array_add_strkey_elem(pArray, "tm_year", pValue /* Will make it's own copy */);
/* Overwrite the previous value */
ph7_value_int(pValue, pNow->tm_mon + 1); /* Month [1-12]*/
/* Insert month number */
ph7_array_add_strkey_elem(pArray, "tm_mon", pValue /* Will make it's own copy */);
/* Overwrite the previous value */
ph7_value_int(pValue, pNow->tm_mday); /* Day of the month [1-31] */
/* Insert the day of the month */
ph7_array_add_strkey_elem(pArray, "tm_mday", pValue /* Will make it's own copy */);
ph7_value_int(pValue, pNow->tm_hour); /* Hour */
/* Insert the hour */
ph7_array_add_strkey_elem(pArray, "tm_hour", pValue /* Will make it's own copy */);
/* Overwrite the previous value */
ph7_value_int(pValue, pNow->tm_min); /* Minutes */
/* Insert minutes */
ph7_array_add_strkey_elem(pArray, "tm_min", pValue /* Will make it's own copy */);
/* Overwrite the previous value */
ph7_value_int(pValue, pNow->tm_sec); /* Seconds */
/* Insert seconds */
ph7_array_add_strkey_elem(pArray, "tm_sec", pValue /* Will make it's own copy */);
/* Return the array as the function return value */
ph7_result_value(pCtx, pArray);
/* All done. Don't worry about freeing memory here, every
* allocated resource will be released automatically by the engine
* as soon we return from this foreign function.
*/
return PH7_OK;
}
/*
* array array_string_split(string $str)
* Return a copy of each string character in an array.
* Description
* This function splits a given string to its
* characters and return the result in an array.
* Parameter
* $str
* Target string to split.
* Return value
* Array holding string characters.
* Usage example
* <?php
* var_dump( array_str_split('Hello') );
* ?>
* When running you should see something like that:
* array(5) {
* [0] =>
* string(1 'H')
* [1] =>
* string(1 'e')
* [2] =>
* string(1 'l')
* [3] =>
* string(1 'l')
* [4] =>
* string(1 'o')
* }
*/
int array_string_split_func(ph7_context *pCtx, int argc, ph7_value **argv)
{
ph7_value *pArray; /* Our Array */
ph7_value *pValue; /* Array entries value */
const char *zString, *zEnd; /* String to split */
int nByte; /* String length */
/* Make sure there is at least one argument and is of the
* expected type [i.e: string].
*/
if( argc < 1 || !ph7_value_is_string(argv[0]) ){
/*
* Missing/Invalid argument, throw a warning and return FALSE.
* Note that you do not need to log the function name, PH7 will
* automatically append the function name for you.
*/
ph7_context_throw_error(pCtx, PH7_CTX_WARNING, "Missing string to split");
/* Return false */
ph7_result_bool(pCtx, 0);
return PH7_OK;
}
/* Extract the target string.
* Note that zString is null terminated and ph7_value_to_string() never
* fail and always return a pointer to a null terminated string.
*/
zString = ph7_value_to_string(argv[0], &nByte /* String length */);
if( nByte < 1 /* Empty string [i.e: '' or ""] */ ){
ph7_context_throw_error(pCtx, PH7_CTX_NOTICE, "Empty string");
/* Return false */
ph7_result_bool(pCtx, 0);
return PH7_OK;
}
/* Create our array */
pArray = ph7_context_new_array(pCtx);
/* Create a scalar worker value */
pValue = ph7_context_new_scalar(pCtx);
/* Split the target string */
zEnd = &zString[nByte]; /* Delimit the string */
while( zString < zEnd ){
int c = zString[0];
/* Prepare the character for insertion */
ph7_value_string(pValue, (const char *)&c, (int)sizeof(char));
/* Insert the character */
ph7_array_add_elem(pArray, 0/* NULL: Assign an automatic index */, pValue /* Will make it's own copy*/);
/* Erase the previous data from the worker variable */
ph7_value_reset_string_cursor(pValue);
/* Next character */
zString++;
}
/* Return our array as the function return value */
ph7_result_value(pCtx, pArray);
/* All done. Don't worry about freeing memory here, every
* allocated resource will be released automatically by the engine
* as soon we return from this foreign function.
*/
return PH7_OK;
}
/*
* Container for the foreign functions defined above.
* These functions will be registered later using a call
* to [ph7_create_function()].
*/
static const struct foreign_func {
const char *zName; /* Name of the foreign function*/
int (*xProc)(ph7_context *, int, ph7_value **); /* Pointer to the C function performing the computation*/
}aFunc[] = {
{"shift_func", shift_func},
{"date_func", date_func},
{"sum_func", sum_func },
{"array_time_func", array_time_func},
{"array_str_split", array_string_split_func},
{"array_date_func", array_date_func}
};
/*
* Test our implementation:
*
* The following is the PHP program to execute.
* <?php
* echo 'shift_func(150) = '.shift_func(150).PHP_EOL;
* echo 'sum_func(7, 8, 9, 10) = '.sum_func(7, 8, 9, 10).PHP_EOL;
* echo 'date_func(5) = '.date_func().PHP_EOL;
* echo 'array_time_func() ='.PHP_EOL;
* var_dump(array_time_func());
* echo 'array_date_func(5) ='.PHP_EOL;
* var_dump(array_date_func(5));
* echo 'array_str_split(\'Hello\') ='.PHP_EOL;
* var_dump(array_str_split('Hello'));
* ?>
* When running, you should see something like that:
* shift_func(150) = 300
* sum_func(7, 8, 9, 10) = 34
* date_func(5) = 2012-23-09 03:53:30
* array_time_func() =
* array(3) {
* [0] =>
* int(3)
* [1] =>
* int(53)
* [2] =>
* int(30)
* }
* array_date_func(5) =
* array(6) {
* [tm_year] =>
* int(2012)
* [tm_mon] =>
* int(9)
* [tm_mday] =>
* int(23)
* [tm_hour] =>
* int(3)
* [tm_min] =>
* int(53)
* [tm_sec] =>
* int(30)
* }
* array_str_split('Hello') =
* array(5) {
* [0] =>
* string(1 'H')
* [1] =>
* string(1 'e')
* [2] =>
* string(1 'l')
* [3] =>
* string(1 'l')
* [4] =>
* string(1 'o')
* }
*/
#define PHP_PROG "<?php"\
"echo 'shift_func(150) = '.shift_func(150).PHP_EOL;"\
"echo 'sum_func(7, 8, 9, 10) = '.sum_func(7, 8, 9, 10).PHP_EOL;"\
"echo 'date_func(5) = '.date_func().PHP_EOL;"\
"echo 'array_time_func() ='.PHP_EOL;"\
"var_dump(array_time_func());"\
"echo 'array_date_func(5) ='.PHP_EOL;"\
"var_dump(array_date_func(5));"\
"echo 'array_str_split(\\'Hello\\') ='.PHP_EOL;"\
"var_dump(array_str_split('Hello'));"\
"?>"
#include <stdio.h>
#include <stdlib.h>
/*
* Display an error message and exit.
*/
static void Fatal(const char *zMsg)
{
puts(zMsg);
/* Shutdown the library */
ph7_lib_shutdown();
/* Exit immediately */
exit(0);
}
#ifdef __WINNT__
#include <Windows.h>
#else
/* Assume UNIX */
#include <unistd.h>
#endif
/*
* The following define is used by the UNIX built and have
* no particular meaning on windows.
*/
#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif
/*
* VM output consumer callback.
* Each time the virtual machine generates some outputs, the following
* function gets called by the underlying virtual machine to consume
* the generated output.
* All this function does is redirecting the VM output to STDOUT.
* This function is registered later via a call to ph7_vm_config()
* with a configuration verb set to: PH7_VM_CONFIG_OUTPUT.
*/
static int Output_Consumer(const void *pOutput, unsigned int nOutputLen, void *pUserData/* Unused */)
{
#ifdef __WINNT__
BOOL rc;
rc = WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), pOutput, (DWORD)nOutputLen, 0, 0);
if( !rc ){
/* Abort processing */
return PH7_ABORT;
}
#else
ssize_t nWr;
nWr = write(STDOUT_FILENO, pOutput, nOutputLen);
if( nWr < 0 ){
/* Abort processing */
return PH7_ABORT;
}
#endif /* __WINT__ */
/* All done, VM output was redirected to STDOUT */
return PH7_OK;
}
/*
* Main program: Register the foreign functions defined above, compile and execute
* our PHP test program.
*/
int main(void)
{
ph7 *pEngine; /* PH7 engine */
ph7_vm *pVm; /* Compiled PHP program */
int rc;
int i;
/* Allocate a new PH7 engine instance */
rc = ph7_init(&pEngine);
if( rc != PH7_OK ){
/*
* If the supplied memory subsystem is so sick that we are unable
* to allocate a tiny chunk of memory, there is no much we can do here.
*/
Fatal("Error while allocating a new PH7 engine instance");
}
/* Compile the PHP test program defined above */
rc = ph7_compile_v2(
pEngine, /* PH7 engine */
PHP_PROG, /* PHP test program */
-1 /* Compute input length automatically*/,
&pVm, /* OUT: Compiled PHP program */
0 /* IN: Compile flags */
);
if( rc != PH7_OK ){
if( rc == PH7_COMPILE_ERR ){
const char *zErrLog;
int nLen;
/* Extract error log */
ph7_config(pEngine,
PH7_CONFIG_ERR_LOG,
&zErrLog,
&nLen
);
if( nLen > 0 ){
/* zErrLog is null terminated */
puts(zErrLog);
}
}
/* Exit */
Fatal("Compile error");
}
/* Now we have our program compiled, it's time to register
* our foreign functions.
*/
for( i = 0 ; i < (int)sizeof(aFunc)/sizeof(aFunc[0]) ; ++i ){
/* Install the foreign function */
rc = ph7_create_function(pVm, aFunc[i].zName, aFunc[i].xProc, 0 /* NULL: No private data */);
if( rc != PH7_OK ){
Fatal("Error while registering foreign functions");
}
}
/*
* Configure our VM:
* Install the VM output consumer callback defined above.
*/
rc = ph7_vm_config(pVm,
PH7_VM_CONFIG_OUTPUT,
Output_Consumer, /* Output Consumer callback */
0 /* Callback private data */
);
if( rc != PH7_OK ){
Fatal("Error while installing the VM output consumer callback");
}
/*
* Report run-time errors such as unexpected numbers of arguments and so on.
*/
ph7_vm_config(pVm, PH7_VM_CONFIG_ERR_REPORT);
/*
* And finally, execute our program. Note that your output (STDOUT in our case)
* should display the result.
*/
ph7_vm_exec(pVm, 0);
/* All done, cleanup the mess left behind.
*/
ph7_vm_release(pVm);
ph7_release(pEngine);
return 0;
}

View File

@ -1,216 +0,0 @@
/*
* Compile this file together with the ph7 engine source code to generate
* the simple PH7 interpreter executable. For example:
* gcc -W -Wall -O6 -D PH7_ENABLE_MATH_FUNC -o ph7 ph7_interp.c ph7.c
*/
/*
* The PH7 interpreter is a simple stand-alone PHP interpreter that allows
* the user to enter and execute PHP files against a PH7 engine.
* To start the ph7 program, just type "ph7" followed by the name of the PHP file
* to compile and execute. That is, the first argument is to the interpreter, the rest
* are scripts arguments, press "Enter" and the PHP code will be executed.
* If something goes wrong while processing the PHP script due to a compile-time error
* your error output (STDOUT) should display the compile-time error messages.
*
* Usage example of the ph7 interpreter:
* ph7 scripts/hello_world.php
* Running the interpreter with script arguments
* ph7 scripts/mp3_tag.php /usr/local/path/to/my_mp3s
*
* The PH7 interpreter package includes more than 70 PHP scripts to test ranging from
* simple hello world programs to XML processing, ZIP archive extracting, MP3 tag extracting,
* UUID generation, JSON encoding/decoding, INI processing, Base32 encoding/decoding and many
* more. These scripts are available in the scripts directory from the zip archive.
*/
/* $SymiscID: ph7_interp.c v1.7.4 Win7 2012-10-06 03:22 stable <devel@symisc.net> $ */
/* Make sure you have the latest release of the PH7 engine
* from:
* http://ph7.symisc.net/downloads.html
*/
#include <stdio.h>
#include <stdlib.h>
/* Make sure this header file is available.*/
#include "ph7.h"
/*
* Display an error message and exit.
*/
static void Fatal(const char *zMsg)
{
puts(zMsg);
/* Shutdown the library */
ph7_lib_shutdown();
/* Exit immediately */
exit(0);
}
/*
* Banner.
*/
static const char zBanner[] = {
"============================================================\n"
"Simple PH7 Interpreter \n"
" http://ph7.symisc.net/\n"
"============================================================\n"
};
/*
* Display the banner,a help message and exit.
*/
static void Help(void)
{
puts(zBanner);
puts("ph7 [-h|-r|-d] path/to/php_file [script args]");
puts("\t-d: Dump PH7 byte-code instructions");
puts("\t-r: Report run-time errors");
puts("\t-h: Display this message an exit");
/* Exit immediately */
exit(0);
}
#ifdef __WINNT__
#include <Windows.h>
#else
/* Assume UNIX */
#include <unistd.h>
#endif
/*
* The following define is used by the UNIX built and have
* no particular meaning on windows.
*/
#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif
/*
* VM output consumer callback.
* Each time the virtual machine generates some outputs,the following
* function gets called by the underlying virtual machine to consume
* the generated output.
* All this function does is redirecting the VM output to STDOUT.
* This function is registered later via a call to ph7_vm_config()
* with a configuration verb set to: PH7_VM_CONFIG_OUTPUT.
*/
static int Output_Consumer(const void *pOutput,unsigned int nOutputLen,void *pUserData /* Unused */)
{
#ifdef __WINNT__
BOOL rc;
rc = WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),pOutput,(DWORD)nOutputLen,0,0);
if( !rc ){
/* Abort processing */
return PH7_ABORT;
}
#else
ssize_t nWr;
nWr = write(STDOUT_FILENO,pOutput,nOutputLen);
if( nWr < 0 ){
/* Abort processing */
return PH7_ABORT;
}
#endif /* __WINT__ */
/* All done,VM output was redirected to STDOUT */
return PH7_OK;
}
/*
* Main program: Compile and execute the PHP file.
*/
int main(int argc,char **argv)
{
ph7 *pEngine; /* PH7 engine */
ph7_vm *pVm; /* Compiled PHP program */
int dump_vm = 0; /* Dump VM instructions if TRUE */
int err_report = 0; /* Report run-time errors if TRUE */
int n; /* Script arguments */
int rc;
/* Process interpreter arguments first*/
for(n = 1 ; n < argc ; ++n ){
int c;
if( argv[n][0] != '-' ){
/* No more interpreter arguments */
break;
}
c = argv[n][1];
if( c == 'd' || c == 'D' ){
/* Dump byte-code instructions */
dump_vm = 1;
}else if( c == 'r' || c == 'R' ){
/* Report run-time errors */
err_report = 1;
}else{
/* Display a help message and exit */
Help();
}
}
if( n >= argc ){
puts("Missing PHP file to compile");
Help();
}
/* Allocate a new PH7 engine instance */
rc = ph7_init(&pEngine);
if( rc != PH7_OK ){
/*
* If the supplied memory subsystem is so sick that we are unable
* to allocate a tiny chunk of memory,there is no much we can do here.
*/
Fatal("Error while allocating a new PH7 engine instance");
}
/* Set an error log consumer callback. This callback [Output_Consumer()] will
* redirect all compile-time error messages to STDOUT.
*/
ph7_config(pEngine,PH7_CONFIG_ERR_OUTPUT,
Output_Consumer, /* Error log consumer */
0 /* NULL: Callback Private data */
);
/* Now,it's time to compile our PHP file */
rc = ph7_compile_file(
pEngine, /* PH7 Engine */
argv[n], /* Path to the PHP file to compile */
&pVm, /* OUT: Compiled PHP program */
0 /* IN: Compile flags */
);
if( rc != PH7_OK ){ /* Compile error */
if( rc == PH7_IO_ERR ){
Fatal("IO error while opening the target file");
}else if( rc == PH7_VM_ERR ){
Fatal("VM initialization error");
}else{
/* Compile-time error, your output (STDOUT) should display the error messages */
Fatal("Compile error");
}
}
/*
* Now we have our script compiled,it's time to configure our VM.
* We will install the VM output consumer callback defined above
* so that we can consume the VM output and redirect it to STDOUT.
*/
rc = ph7_vm_config(pVm,
PH7_VM_CONFIG_OUTPUT,
Output_Consumer, /* Output Consumer callback */
0 /* Callback private data */
);
if( rc != PH7_OK ){
Fatal("Error while installing the VM output consumer callback");
}
/* Register script agruments so we can access them later using the $argv[]
* array from the compiled PHP program.
*/
for( n = n + 1; n < argc ; ++n ){
ph7_vm_config(pVm,PH7_VM_CONFIG_ARGV_ENTRY,argv[n]/* Argument value */);
}
if( err_report ){
/* Report script run-time errors */
ph7_vm_config(pVm,PH7_VM_CONFIG_ERR_REPORT);
}
if( dump_vm ){
/* Dump PH7 byte-code instructions */
ph7_vm_dump_v2(pVm,
Output_Consumer, /* Dump consumer callback */
0
);
}
/*
* And finally, execute our program. Note that your output (STDOUT in our case)
* should display the result.
*/
ph7_vm_exec(pVm,0);
/* All done, cleanup the mess left behind.
*/
ph7_vm_release(pVm);
ph7_release(pEngine);
return 0;
}

View File

@ -1,36 +0,0 @@
-------------------------
Introduction
-------------------------
The PH7 interpreter is a simple,basic stand-alone PHP interpreter that allows
the user to enter and execute PHP files against a PH7 engine.
To start the ph7 program, just type "ph7" followed by the name of the PHP file
to compile and execute. That is, the first argument is to the interpreter, the rest
are scripts arguments, press "Enter" and the PHP code will be executed.
If something goes wrong while processing the PHP script due to a compile-time
error,your error output (STDOUT) should display the compile-time error messages.
Usage example of the ph7 interpreter:
Running the interpreter
ph7 scripts/hello_world.php
Running the interpreter with script arguments
ph7 scripts/mp3_tag.php /usr/local/path/to/my_mp3s
The PH7 interpreter package includes more than 70 PHP scripts to test ranging from
simple hello world programs to XML processing,ZIP archive extracting, MP3 tag
extracting, UUID generation, JSON encoding/decoding, INI processing,Base32
encoding/decoding and many more. These scripts are available in the scripts directory
from the zip archive.
------------------------
Compile from source
------------------------
To compile the PH7 interpreter from source,you need the latest release of the PH7 engine
from http://ph7.symisc.net/downloads.html
After that, invoke your favourite compiler and generate the executable as follows:
gcc -W -Wall -O6 -o ph7 ph7_interp.c ph7.c -D PH7_ENABLE_MATH_FUNC -lm
Don't forget to compile the PH7 engine with built-in math functions enabled
[i.e: sqrt(), abs(), etc. ]using the PH7_ENABLE_MATH_FUNC compile-time directive.
Finally, don't forget to compile with full optimizations enabled.

View File

@ -1,144 +0,0 @@
/*
* Compile this file together with the ph7 engine source code to generate
* the executable. For example:
* gcc -W -Wall -O6 -o ph7_test ph7_intro.c ph7.c
*/
/*
* This simple program is a quick introduction on how to embed and start
* experimenting with the PH7 engine without having to do a lot of tedious
* reading and configuration.
*
* For an introduction to the PH7 C/C++ interface, please refer to this page
* http://ph7.symisc.net/api_intro.html
* For the full C/C++ API reference guide, please refer to this page
* http://ph7.symisc.net/c_api.html
*/
/*
* The following is the PHP program to execute.
* <?php
* echo 'Welcome guest'.PHP_EOL;
* echo 'Current system time is: '.date('Y-m-d H:i:s').PHP_EOL;
* echo 'and you are running '.php_uname();
* ?>
* That is, this simple program when running should display a greeting
* message, the current system time and the host operating system.
* A typical output of this program would look like this:
*
* Welcome guest
* Current system time is: 2012-09-14 02:08:44
* and you are running Microsoft Windows 7 localhost 6.1 build 7600 x86
*
*/
#define PHP_PROG "<?php "\
"echo 'Welcome guest'.PHP_EOL;"\
"echo 'Current system time is: '.date('Y-m-d H:i:s').PHP_EOL;"\
"echo 'and you are running '.php_uname();"\
"?>"
/* Make sure you have the latest release of the PH7 engine
* from:
* http://ph7.symisc.net/downloads.html
*/
#include <stdio.h>
#include <stdlib.h>
/* Make sure this header file is available.*/
#include "ph7.h"
/*
* Display an error message and exit.
*/
static void Fatal(const char *zMsg)
{
puts(zMsg);
/* Shutdown the library */
ph7_lib_shutdown();
/* Exit immediately */
exit(0);
}
/*
* VM output consumer callback.
* Each time the virtual machine generates some outputs, the following
* function gets called by the underlying virtual machine to consume
* the generated output.
* All this function does is redirecting the VM output to STDOUT.
* This function is registered later via a call to ph7_vm_config()
* with a configuration verb set to: PH7_VM_CONFIG_OUTPUT.
*/
static int Output_Consumer(const void *pOutput, unsigned int nOutputLen, void *pUserData /* Unused */)
{
/*
* Note that it's preferable to use the write() system call to display the output
* rather than using the libc printf() which everybody now is extremely slow.
*/
printf("%.*s",
nOutputLen,
(const char *)pOutput /* Not null terminated */
);
/* All done, VM output was redirected to STDOUT */
return PH7_OK;
}
/*
* Main program: Compile and execute the PHP program defined above.
*/
int main(void)
{
ph7 *pEngine; /* PH7 engine */
ph7_vm *pVm; /* Compiled PHP program */
int rc;
/* Allocate a new PH7 engine instance */
rc = ph7_init(&pEngine);
if( rc != PH7_OK ){
/*
* If the supplied memory subsystem is so sick that we are unable
* to allocate a tiny chunk of memory, there is no much we can do here.
*/
Fatal("Error while allocating a new PH7 engine instance");
}
/* Compile the PHP test program defined above */
rc = ph7_compile_v2(
pEngine, /* PH7 engine */
PHP_PROG, /* PHP test program */
-1 /* Compute input length automatically*/,
&pVm, /* OUT: Compiled PHP program */
0 /* IN: Compile flags */
);
if( rc != PH7_OK ){
if( rc == PH7_COMPILE_ERR ){
const char *zErrLog;
int nLen;
/* Extract error log */
ph7_config(pEngine,
PH7_CONFIG_ERR_LOG,
&zErrLog,
&nLen
);
if( nLen > 0 ){
/* zErrLog is null terminated */
puts(zErrLog);
}
}
/* Exit */
Fatal("Compile error");
}
/*
* Now we have our script compiled, it's time to configure our VM.
* We will install the VM output consumer callback defined above
* so that we can consume the VM output and redirect it to STDOUT.
*/
rc = ph7_vm_config(pVm,
PH7_VM_CONFIG_OUTPUT,
Output_Consumer, /* Output Consumer callback */
0 /* Callback private data */
);
if( rc != PH7_OK ){
Fatal("Error while installing the VM output consumer callback");
}
/*
* And finally, execute our program. Note that your output (STDOUT in our case)
* should display the result.
*/
ph7_vm_exec(pVm, 0);
/* All done, cleanup the mess left behind.
*/
ph7_vm_release(pVm);
ph7_release(pEngine);
return 0;
}