FAQ
- How do you pronounce ICI?
It is pronounced the same as the word icky.
- What does ICI stand for?
Truth, justice and the Australian way! Actually nothing. It may or may not have been an acronym but has long since lost any acronymity.
- Who owns the ICI copyright?
No one, ICI is in the public domain. This means you can do anything you like with the source code and you don't have to mention where you got it. The ICI documentation however is under copyright and may not be used for commercial purposes without prior arrangement with the copyright owners - Canon Information Systems Research Australia, Tim Long, the University of Cambridge (ICI uses the PCRE regular expression package) and, potentially, others.
- Who uses it? I've never heard of any ICI language.
ICI is actually used in far more places than you'd think and it's used a lot more than the developers realised! It is the core implementation language or basis for a number of products from several large multi-national companies and is used by numerous people as a general purpose scripting and programming language. It is also used in niche products in industries such as energy transmission, astronomy, CAD and printing, and has been used in a number of embedded devices. Some people use it for custom web-based applications and others as the control language for simulation systems. The lack of any licensing issues means people just pick it up and use it without telling anyone! Often ICI just works and without need for assistance these users go on unnoticed. Often the developers are just as surprised as anyone with the uses ICI has been put to.
- What type of programs can I write in ICI?
All sorts of programs. ICI is especially suited to programs involving complex data structures - the inbuilt types and garbage collection make data structure handling simple compared to many other languages. ICI's support for strings and regular expressions make it a good choice for CGI programming and string processing tasks that many people would attack using Perl or awk.
- Is ICI eight bit clean?
Unfortunately no. ICI's makes much use of the C library and many of the underlying routines will not cope withASCII NUL characters within strings. ICI strings may contain NULs however many of ICI's builtin functions use the C library and will not work correctly. It is hoped this will be corrected in a future version of the interpreter.- How do I embed ICI in my application?
There are a number of ways ICI may be embedded within an application, this answer presents two common methods.The most common scenario is using ICI as an extension or macro language within an application. In this case we want to call on ICI to parse arbitrary (or not so arbitrary) code at run-time. There are two ways we can do this. The first uses ICI's parse_file() function to invoke the ICI parser on a data stream. The second method does this somewhat indirectly by calling ICI's own parse() function to parse code stored as a string. With both methods the ICI interpreter must be initialized prior to using any other ICI functions. The ici_init() function does this.
The parse_file() method lets us parse and execute ICI code from any source that can be represented by an ICI file object. That is a normal operating-system file (aka stdio file), a string, TCP socket or ICI mem object. To call parse_file() we need the file's handle for whatever type of source it is and the ICI ftype structure for that source type. For instance for a stdio file we use stdio_ftype. To parse code from C's stdin,
The code in icimain.c is the best reference as it has portions that invoke the parser on both files and strings.if (parse_file("<stdin>", (char *)stdin, &stdio_ftype))
printf("An error occurred: %s\n", error);
If you only want to execute code already in memory the second method calling on the ICI parse() function may be simpler. ICI provides a number of functions for performing function calls directly. One, ici_call(), is passed strings naming the function to call and defining its parameters and result. This makes it quite easy to call ICI. ICI has an intrinsic function, parse(), that invokes the ICI parser. The function may be passed a string or file object as the source of parser input. This is exactly what we want.
The ici_call() function uses a format string to define the parameters and result of the function. In this case we're passing a string and are not interested in the result, the format string is simply "s". We also need to pass a pointer to the character buffer storing the code to be parsed. The resulting code looks like,
Another way to use ICI within an application is to write the application in ICI and use modules to implement the functional portions of the application. This way allows applications themselves to use the features of ICI. The flexible nature of ICI's dynamic loading mechanism means applications can easily be structured into components as required by design. This method of application development also automatically allows ICI to be used as the application's extension language it being an application decision whether or not to load code at run-time.char *err; err = ici_call("parse", "s", codebuf); if (err != NULL) printf("An error occurred: %s\n", err);