A Scripting Language for Web, Linux and Windows

A Scripting Language for Web, Linux and Windows

Howto: Integrate V1 Script with C/C++ API into own projects

You can integrate the V1 interpreter language with a simple C/C++ API into own applications.

Therefore download the newest development package from v1-script.net with precompiled v1.dll for Windows or libv1.so for Linux (libc >= 2.2 required) and VC++, GCC examples.

Here are 16 examples how to work with the C API. Take a look at v1.h to see all API functions.

Example 1: Hello World

#include <stdio.h>
#include "v1.h"

int main (int argcchar **argv
{
  
v1Startup ();
  
V1Context ctx v1CreateContext ();

  
// Evaluate V1 code  
  
const charcode "print ('Hello World');"
  
v1Eval (ctxcodestrlen (code));

  
v1DeleteContext (ctx);
  
v1Shutdown ();  
  return 
0;
}

Example 2: Calculate a value

#include <stdio.h>
#include "v1.h"

int main (int argcchar **argv
{  
  
v1Startup ();
  
V1Context ctx v1CreateContext ();
  
V1Data ret v1CreateData ();  

  
// Evaluate V1 code and return a calculated value  
  
const charcode "10+22*8;";   
  
v1Eval (ctxcodestrlen (code), ret);
  
printf ("Return: %g\r\n"v1Number(ret));

  
v1DeleteData (ret);  
  
v1DeleteContext (ctx);
  
v1Shutdown ();
  return 
0;
}

Example 3: Execute a V1 script file

#include <stdio.h>
#include "v1.h"

int main (int argcchar **argv
{  
  
v1Startup ();

  
// Execute a V1 filename
  
v1Execute (ctx"example.v1"argcargv); 

  
v1Shutdown ();
  return 
0;
}

Example 4: Fetch a parser error

#include <stdio.h>
#include "v1.h"

int main (int argcchar **argv
{  
  
v1Startup ();
  
V1Context ctx v1CreateContext ();

  
// Evaluate V1 code with parser error  
  
const charcode "print X ('Hello World');"
  
int retCode v1Eval (ctxcodestrlen (code));
  if (
v1Aborted (ctx))
    
printf ("Aborted with: %s\r\n", (const char*) v1LastError (ctx));

  
v1DeleteContext (ctx);
  
v1Shutdown ();
  return 
0;
}

Example 5: Exit with exit code

#include <stdio.h>
#include "v1.h"

int main (int argcchar **argv
{
  
v1Startup ();
  
V1Context ctx v1CreateContext ();

  
// Exit with exit code  
  
const charcode "exit(99);"
  
exitCode v1Eval (ctxcodestrlen (code));
  if (
v1Exited (ctx))
    
printf ("Exit Code: %i\r\n", (int) exitCode);

  
v1DeleteContext (ctx);
  
v1Shutdown ();
  return 
0;
}

Example 6: Set own error function

#include <stdio.h>
#include "v1.h"

int myErrorFunc (const charfilenameint line, const chartext
{
  
printf ("%s\r\n"text);
  return 
0;
}

int main (int argcchar **argv
{  
  
v1Startup ();

  
// Set own error function, otherwise errors will be printed to stdout/stderr
  
v1SetErrorFunction (myErrorFunc);

  
v1Shutdown ();
  return 
0;
}

Example 7: Working with own functions

#include <stdio.h>
#include "v1.h"


int myFunction (V1ArgList argsV1Data retV1Context ctx
{
  
// Check if first parameter is set and at least a string value (also number, bool, null possible)
  
if (v1Argument1NoString (args))
    return 
V1_RET_PARAM1|V1_RET_NUM_REQUIRED;

  
// Parameter 2 is required and must be an array 
  
if (v1ArgumentCount(args)<|| v1Argument2Type (args)<V1_DATATYPE_ARRAY)
    return 
V1_RET_PARAM2|V1_RET_ARRAY_REQUIRED;

  
// Parameter 3 is optional and must be a number value (also number, bool, null possible) 
  
if (v1ArgumentCount(args)>&& v1Argument3Type (args)>V1_DATATYPE_STR)
    return 
V1_RET_PARAM3|V1_RET_NUM_REQUIRED;

  
// Get the arguments      
  
printf ("myFunction() is called with %i arguments.\r\n"v1ArgumentCount(args));

  
V1Data arg1 v1Argument(args,0);
  
printf ("First argument: %s\r\n"v1String (arg1));

  
printf ("Second argument:\r\n");
  
V1Data arg2 v1Argument(args,1);
  
V1Data value; const charkey;
  
v1ArrayIterate (arg2);
  while (
value=v1ArrayNext (arg2, &key)) {
    
printf ("%s => %s\r\n", (const char*) key, (const char*) v1String (value));
  }

  if (
v1ArgumentCount(args)>2) {
    
V1Data arg3 v1Argument(args,2);
    
printf ("Third argument: %g\r\n"v1Number (arg3));
  }

  
/*
  // Raise a warning
  v1WarnInterprete (ctx, "Raise a warning");
  */

  /*
  // Abort, you can check if interpreter is aborted by v1IsAborted (ctx)
  v1AbortInterprete (ctx, "Now abort");
  return V1_RET_ABORT;
  */

  // Set return value as string
  
v1SetString (ret"My return value");
  return 
0;
}


int main (int argcchar **argv
{  
  
v1Startup ();
  
V1Context ctx v1CreateContext ();

  
// Register own function and call it
  
v1RegisterFunction (ctx"myFunction"myFunction);
  const 
charcode "print (myFunction ('Param 1', ['Param 2'=>'Value']));";
  
v1Eval (ctxcodestrlen (code));

  
v1DeleteContext (ctx);  
  
v1Shutdown ();
  return 
0;
}

Example 8: Set constants

#include <stdio.h>
#include "v1.h"

int main (int argcchar **argv
{  
  
v1Startup ();
  
V1Context ctx v1CreateContext ();

  
// Set simple constants
  
v1SetConstant (ctx"MY_CONSTANT"0"MY STRING"); // String "MY STRING"
  
v1SetConstant (ctx"MY_CONSTANT2"99NULL); // Number 99

  
const charcode 
    
"print (MY_CONSTANT);"\
    
"print (MY_CONSTANT2);";
  
v1Eval (ctxcodestrlen (code));  

  
v1DeleteContext (ctx);  
  
v1Shutdown ();
  return 
0;
}

Example 9: Read and change a global variable written by V1

#include <stdio.h>
#include "v1.h"

int main (int argcchar **argv
{  
  
v1Startup ();
  
V1Context ctx v1CreateContext ();

  
// Read a global variable written by V1
  
const charcode "a = time ();";
  
v1Eval (ctxcodestrlen (code));
  
V1Data a v1Symbol (ctx"a"V1_SYMBOLS_GLOBAL); // 0 = constants, 1 = global vars
  
if (a) {
    
printf ("a = %.13g\r\n", (double) v1Number (a));

    
// Change the variable
    
v1SetNumber (a99);
    
code "print('a is now ', a);";
    
v1Eval (ctxcodestrlen (code));
  }

  
v1DeleteContext (ctx);  
  
v1Shutdown ();
  return 
0;
}

Example 10: Manipulate a global array written by V1

#include <stdio.h>
#include "v1.h"

int main (int argcchar **argv
{  
  
v1Startup ();
  
V1Context ctx v1CreateContext ();

  
// Manipulate a global array written by V1
  
const charcode "b = array ('key1'=>'Value 1', 'key2'=>99, 'key3'=>true); print_r (b);";
  
v1Eval (ctxcodestrlen (code));

  
V1Data b v1Symbol (ctx"b"V1_SYMBOLS_GLOBAL); // 0 = constants, 1 = global vars
  
if (b) {
    
// Unset key2
    
v1UnsetArrayKey (b"key2");
    
printf ("b has now %u elements\r\n"v1ArraySize (b));

    
// Iterate the array
    
V1Data value; const charkey;
    
v1ArrayIterate (b);
    while (
value=v1ArrayNext (b, &key)) {
        
printf ("%s => %s\r\n", (const char*) key, (const char*) v1String (value));
    }

    
// Set a value in array safe:
    // Note! v1ArrayPut...() will insert/replace the complete array key/value pair
    // To change only the value of a key, first get the value with v1ArrayValue().
    // So the references to this value will be not destroyed!
    
V1Data v v1ArrayValue (b"key1");
    if (
v) {
        
v1SetNumber (v100);
    }
    
code "print ('key1 was changed by application.'); print_r (b);";
    
v1Eval (ctxcodestrlen (code));
  }

  
v1DeleteContext (ctx);  
  
v1Shutdown ();
  return 
0;
}

Example 11: Call a V1 user function

#include <stdio.h>
#include "v1.h"

int main (int argcchar **argv
{  
  
v1Startup ();
  
V1Context ctx v1CreateContext ();

  
// Define a V1 user function
  
code "function myUserFunc (arg1,arg2) { print ('myUserFunc() called from application with arg1=', arg1, ' and arg2=', arg2); return 'OK'; }";
  
v1Eval (ctxcodestrlen (code));

  
// Call the V1 function with arguments 
  
V1ArgList argList v1CreateArgList ();
  
V1Data ret v1CreateData ();
  
V1Data arg1 v1CreateData ();
  
v1SetString (arg1"Value for Argument 1");
  
V1Data arg2 v1CreateData ();
  
v1SetNumber (arg299);
  
v1SetArgument (argList0arg1);
  
v1SetArgument (argList1arg2);
  if (!
v1CallUserFunction (ctx"myUserFunc"argListret)) {
    
printf ("Return value: %s\r\n", (const char*) v1String (ret));
  }
  else {
    
printf ("%s\r\n", (const char*) v1LastError (ctx));
  }
  
v1DeleteData (arg1); // v1DeleteData() must be called for a corresponding v1CreateData()
  
v1DeleteData (arg2);
  
v1DeleteData (ret);
  
v1DeleteArgList (argList); // v1DeleteArgList() must be called for a corresponding v1CreateArgList()

  
v1DeleteContext (ctx);  
  
v1Shutdown ();
  return 
0;
}

Example 12: Read a V1 file handle

#include <stdio.h>
#include "v1.h"

int main (int argcchar **argv
{  
  
v1Startup ();
  
V1Context ctx v1CreateContext ();

  
// Create a file handle with V1 and work with it
  
code "fh = fopen ('testfile.txt', 'w+');";
  
v1Eval (ctxcodestrlen (code));
  
V1Data fh v1Symbol (ctx"fh"V1_SYMBOLS_GLOBAL); // 0 = constants, 1 = global vars

  
if (fh && v1HandleType (fh)==V1_HANDLETYPE_FILE) {
    
// Cast to FILE* HANDLE
    
FILEpFile = (FILE*) v1Handle (fh);
    if (
pFile) {
      
// Write 
      
const charbuf "Written by application";
      
unsigned int size strlen (buf);
      if (
fwrite (bufsizeof(char), sizepFile) < size) {
        
printf ("Problems to write file.\r\n");
      }
    }
  }

  
v1DeleteContext (ctx);  
  
v1Shutdown ();
  return 
0;
}

Example 13: Create a file and assign the file handle to a V1 variable

#include <stdio.h>
#include "v1.h"

int main (int argcchar **argv
{  
  
v1Startup ();
  
V1Context ctx v1CreateContext ();

  
// Create a WIN32 file and assign file handle to V1 variable (on Linux you can assign a FILE* pointer)
  
wchar_t wFilename[MAX_PATH+1];
  
DWORD size MultiByteToWideChar(CP_UTF80"testfile2.txt", -1wFilenameMAX_PATH);
  
wFilename[size]=0;

  
HANDLE hFile;
  if (
INVALID_HANDLE_VALUE == (hFile CreateFileW (wFilenameGENERIC_READ|GENERIC_WRITEFILE_SHARE_READ|FILE_SHARE_WRITENULLCREATE_ALWAYSFILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESSNULL))) {
    
printf ("Cannot create file.");
  }
  else {
    
V1Data symbol v1CreateSymbol (ctx"fh2"V1_SYMBOLS_CONSTANT); // 0=constants, 1=global vars, 2=first running function ...
    
v1SetHandle (ctxsymbolV1_HANDLETYPE_FILE, (V1HandlehFile); // only V1_HANDLETYPE_FILE, V1_HANDLETYPE_SOCKET allowed

    
code "fwrite (fh2, 'Written by V1'); fclose (fh2);";
    
v1Eval (ctxcodestrlen (code));
    
// Note! File handles will be closed also automatically in v1DeleteContext()
  


  
v1DeleteContext (ctx);  
  
v1Shutdown ();
  return 
0;
}

Example 14: Iterate all variables of current symbol table

#include <stdio.h>
#include "v1.h"

int main (int argcchar **argv
{  
  
v1Startup ();
  
V1Context ctx v1CreateContext ();

  
// Set some variables
  
code "a=1;b=2;c=['key'=>'value'];";
  
v1Eval (ctxcodestrlen (code));  

  
// Iterate all variables of current symbol table
  
V1Data value; const charname;
  
v1SymbolIterate (ctxv1CurrentSymbolTable (ctx));
  
printf ("Max. %u symbol tables available, current symbol table is %u.\r\n", (unsigned intv1SymbolTableCount (ctx), (unsigned intv1CurrentSymbolTable (ctx));
  while (
value=v1SymbolNext (ctxv1CurrentSymbolTable (ctx), &name)) {
    
printf ("%s => Type %i (string=\"%s\")\r\n", (const char*) name, (int) v1Type (value), (const char*) v1String (value));
  }

  
v1DeleteContext (ctx);  
  
v1Shutdown ();
  return 
0;
}

Example 15: Remove a function

#include <stdio.h>
#include "v1.h"

int main (int argcchar **argv
{  
  
v1Startup ();
  
V1Context ctx v1CreateContext ();

  
// Remove a function
  
code "function userFunc (x) { return sqrt(x); }; print (userFunc(16));";
  
v1Eval (ctxcodestrlen (code));
  if (
v1FunctionRegistered (ctx"userFunc")) {
    
v1RemoveFunction (ctx"userFunc");
    
// Redefinition will cause no error, because function was removed
    
v1Eval (ctxcodestrlen (code));
  }

  
v1DeleteContext (ctx);  
  
v1Shutdown ();
  return 
0;
}

Example 16: Create a constant array

#include <stdio.h>
#include "v1.h"

int main (int argcchar **argv
{  
  
v1Startup ();
  
V1Context ctx v1CreateContext ();

  
// Create a constant array
  
V1Data symbol v1CreateSymbol (ctx"mySymbol"V1_SYMBOLS_CONSTANT); // 0=constants, 1=global vars, 2=first running function ...
  
v1PutArrayString (symbol"key1""Value 1");
  
v1PutArrayString (symbol"key2""Value 2");
  
v1PutArrayBool (symbol"key3"true);
  
V1Data subArray v1PutArrayArray (symbol"subArray");   
  
v1PutArrayString (subArray"key1""Value 1");
  
v1PutArrayString (subArray"key2""Value 2");
  
v1PutArrayBool (subArray"key3"true);  
  
V1Data subArray2 v1PutArrayArray (symbol"subArray2"); 
  
// Push will create a vector (keys are set automatically 0,1,2 ...)
  
v1PushArrayString (subArray2"Value 1");
  
v1PushArrayNumber (subArray242.12);
  
v1PushArrayBool (subArray2true);

  
code "print_r (mySymbol);"
  
v1Eval (ctxcodestrlen (code));

  
// Try to overwrite constant array will cause error
  
code "mySymbol['key1']['key3']=42;"
  
v1Eval (ctxcodestrlen (code));
  
printf ("%s\r\n", (const char*) v1LastError (ctx));

  
v1DeleteContext (ctx);  
  
v1Shutdown ();
  return 
0;
}

back to Home