[SparForte][Banner]
[Top Main Menu] Intro | Tutorials | Reference | Packages | Examples | Contributors   [Back Page]      [Next Page]  

Interpreter Directives

Pragmas, or interpreter directives, provide additional instructions to AdaScript. This section also contains information on importing variables to and exporting variables from other software, such as the operating system environment.

The Pragmas

  pragma ada_95
  pragma annotate( [type,]"text" )
  pragma assert( condition )
  pragma debug( `commands` )
  pragma depreciated/deprecated( "newscript" )
  pragma export( shell | local_memcache | memcache , var )
  pragma export_json( shell | local_memcache | memcache , var )
  pragma gcc_errors
  pragma import( shell | cgi | local_memcache | memcache, var )
  pragma import_json( shell | cgi | local_memcache | memcache, var )
  pragma inspect( var )
  pragma inspection_peek
  pragma inspection_point
  pragma license( license_name [, extra] )
  pragma no_command_hash
  pragma prompt_script( `commands` )
  pragma restriction( annotations_not_optional )
  pragma restriction( no_annotate_todos )
  pragma restriction( no_auto_declarations )
  pragma restriction( no_external_commands )
  pragma restriction( no_memcache )
  pragma restriction( no_mysql_database )
  pragma restriction( no_postgresql_database )
  pragma software_model( model_name )
  pragma template( css|html|js|json|text|wml|xml [, path] )
  pragma test( `commands` )
  pragma test_result( condition )
  pragma unchecked_import( shell | cgi | local_memcache | memcache, var )
  pragma uninspect( var )
  pragma unrestricted_template( css|html|js|json|text|wml|xml [, path] )
  pragma volatile( var )

 
Help Command: The List of Pragmas

The name of the pragma, and any argument identifier not in quote marks, are not treated as constants and do not have to be declared. The arguments are specific to the pragmas they refer to.

If a pragma is not recognized, it is treated as an error.

Ada: If a pragma is not recognized, it is ignored by Ada.

pragma annotate( summary, "arraysum" );
pragma annotate( description, "Compute the sum and product of an array of integers." );
pragma annotate( see_also, "http://rosettacode.org/wiki/Sum_and_product_of_an_array" );
pragma annotate( author, "Ken O. Burtch" );

pragma license( unrestricted );

pragma software_model( shell_script );
pragma restriction( no_external_commands );
 

Example: An example of pragmas

Architectural Pragmas

Interpreter directives addressing business concerns, data design, application design, technical design / use-of-hardware or the overall vision of a project. This includes portability, standards compliance, licensing and feature restriction.

  • pragma ada_95 - requires the script syntax be as close to Ada 95 as possible, otherwise errors will occur.
  • pragma deprecated( "newscript" ) - another name for pragma depreciated.
  • pragma depreciated( "newscript" ) - when script finishes execution, SparForte will warn that the script is obsolete and has been superceded for "newscript".
  • pragma license( license_name [, "extra"] ) - declare the license for the script. license_name can be:
    • agpl - Affero GPL
    • apache - Apache Software License v1.0
    • apache_2 - Apache Software License v2.0
    • artistic - Artistic License
    • bsd_original - BSD License (Original)
    • bsd_revised - BSD License (Revised)
    • commercial - A commercial license
    • freeware- A freeware license
    • gpl - GNU General Public License
    • gplv2 - GNU General Public License v2.0
    • gplv3 - GNU General Public License v3.0
    • mit - MIT License
    • public_domain - Public Domain
    • restricted - An restricted license
    • shareware - A shareware license
    • unrestricted - An unrestricted license
    If extra exists, it is a string further describing the license (for example, commercial/"trial license" or commercial/"15 users". The extra string can also be a URL to a complex license. Only one license is permitted. The name can be read from the System package.
    GCC Ada: unrestricted, gpl and unrestricted are recognized by Ada. It doesn't support the extra string. It treats these as levels and will try to validate license compatibility where possible.
  • pragma restriction( annotations_not_options ) - if no pragma annotate's are in the script, report an error after the script runs. This is indended as a way to require developers to write documentation.
  • pragma restriction( no_annotate_todos ) - if pragma annotate todo is used, report an error after the script runs. This is intended for use in UAT or production environments where all "todo" work should be completed earlier.
  • pragma restriction( no_auto_declarations ) - disable automatic declaration at the command prompt
  • pragma restriction( no_external_commands ) - disable operating system commands. Provides portability by ensuring no commands besides SparForte's built-in commands are executed. Useful for applications using SparForte as a run-time scripting language and not for shell scripting.
  • pragma restriction( no_memcache ) - disable connections to memcached. Doesn't prevent other programs from using Memcache.
  • pragma restriction( no_mysql_database ) - disable connections to a MySQL database. Doesn't prevent the mysql client or other programs from using MySQL.
  • pragma restriction( no_postgresql_database ) - disable connections to a PostgreSQL database. Doesn't prevent the psql client or other programs from using PostgreSQL.
  • pragma software_model( model_name ) - declare the general software pattern or model best describing this script. model_name can be:
    • application_desktop - a mouse-and-windows application
    • application_mobile - application for a small device
    • application_realtime - an application with strict time constraints
    • application_realtime_ravenscar - an application with strict time constraints adhering to the Ravenscar model
    • daemon - a server that is not an HTTP server
    • daemon_proxy - a server proxy that is not an HTTP proxy
    • http_framework - a web development library
    • http_service_external - public facing web service
    • http_service_internal - private web service
    • http_site_external - public facing web site or page
    • http_site_internal - private/intranet web site or page
    • http_proxy - a web service to direct or cache requests
    • http_form - a web script to do data entry
    • package - a library
    • shell_batch - a script to control a process
    • shell_filter_script - a script that uses standard input and output to transform data
    • shell_report_script - a script generating text reports
    • shell_script - that is, a command script
    • multimedia - media players or games
    • etl - extract, transform, load. that is, data conversion
    • monitor - a service that monitors activity
    • driver - a device driver
Only one software model is permitted. The name can be read from the System package.

Debugging Pragmas

Interpreter directives used to investigate problems in the source code or used with SparForte's breakout prompt.

  • pragma assert( expression ) - evaluates the expression. If it isn't true, the program stops and "assertion failed" is displayed. Use this to check the expected results during development. Requires --debug or --test options or asserts will have no effect.
  • pragma debug( `commands` ) - these are a set of debugging commands to run when debugging mode (the --debug option) is turned on with --debug.  Make sure the final command ends with a semi-colon. Without a parameter, same as --debug (turn on debugging). The debugging commands are run in restricted shell mode. Because this is a pragma, it can be placed in variable declarations or other places executable statements are not normally allowed.
  • pragma gcc_errors - same as --gcc-errors.  Show simplified gcc-style errors.
  • pragma inspect( var ) - show a variable's description (as if 'env var' was used) whenever a user breaks to a command prompt. Has no effect if --break option isn't used.
  • pragma inspection_peek - like inspection_point, displaying inspect variables, except it doesn't break to a command prompt.
  • pragma inspection_point - break to a command prompt as if SIGINT (control-C) was received, displaying the call stack and any variables marked for inspection with pragma inspect. Has no effect if --break option isn't used. A "breakpoint".
  • pragma test( `commands` ) - these are a set of testing commands to run when test mode (the --test option) is used. For example, this can be used to help with unit testing. Because this is a pragma, it can be placed in variable declarations or other places executable statements are not normally allowed. Make sure the final command ends with a semi-colon.
  • pragma test_result( expression ) - evaluates the expression. If it isn't true, a "test failed" message is written to standard error. (The format of the message is affected by --gcc-errors.) Use this to check the results in automated tests. Requires --test option or asserts will have no effect.
  • pragma uninspect( var ) - undo a pragma inspect. Don't show a variable's description whenever a user breaks to a command prompt. Has no effect if --break option isn't used.

Documentation Pragmas

Interpreter directives used to describe a project, particularily real world concerns that are not expressed in the source code.

  • pragma annotate( [type,] "text" ) - embed a comment. The contents of any or all annotate pragmas are shown when you use the help command on a script. Type type of annotation field can be:
    • author - who wrote the script
    • bugs - known bugs
    • created - when the script was first released
    • description - a detailed description of what the script does
    • errors - errors returned from the script
    • modified - when the script was last modified
    • param - description of a parameter to the script
    • return - return value
    • see_also - a reference to another document or script
    • summary - a short description of what the script does
    • todo - unfinished work
    • version - the version of the script

Annotations are used by the help command to produce documentation.

Interfacing Pragmas

Interpreter directives that affect SparForte's environment or how it interacts with other software.

  • pragma export( shell | local_memcache | memcache, var ) - export a string variable to the O/S environment or memcached.
  • pragma export_json( shell | local_memcache | memcache, var ) - export a string, numeric, enumerated item, array or record variable as a JSON string to the O/S environment or memcached.
  • pragma import( shell | cgi | local_memcache | memcache, var ) - import a variable. For shell, from the O/S environment. For cgi and if pragma template/unrestricted_template was used previously, a HTTP CGI variable from the O/S environment. For local_memcache, get the value of the variable from a memcached server running on locahost port 11211. Put the value in the SparForte variable. If the environment variable doesn't exist, then the SparForte will report an error (see unchecked_import).
  • pragma import_json( shell | cgi | local_memcache | memcache, var ) - import a JSON string, converting it to a string, numeric, enumerated item, array or record variable.
  • pragma no_command_hash - Bush normally remembers the location of a command once it has found it.  This pragma forces Bush to search for the location of the command, ignoring the previous location.
  • pragma register_memcache_server( host, port ) - add a memcache server which will be used with memcache method imports/exports
  • pragma template( css|html|js|json|text|wml|xml [, template] ) - SparForte will act like a template processor (like PHP). When the script finishes executing, SparForte will open a file called "file.tmpl" where file is the name of the script. If an alternate file path is included in the pragma, that file is used as the template instead. A HTTP header is written and SparForte parses the template along with any embedded scripts. For security, the embedded scripts in the template will be run in a restricted shell and with the no_external_commands restriction. Errors are shown in --gcc-errors format using the line number in the template as the line number for the error. The first parameter is the template type: "css" (a style sheet), "html" (HTML web page), "js" (Javascript script), "json" (JSON encoded text), "text" (plain text), "wml" (WML text) or "xml" (XML text).
  • pragma unchecked_import( shell | cgi | local_memcache | memcache, var ) - import a variable. For shell, from the O/S environment. For cgi and if pragma template/unrestricted_template was used previously, a HTTP CGI variable from the O/S environment. For local_memcache, get the value of the variable from a memcached server running on locahost port 11211. Put the value in the SparForte variable. If the import variable doesn't exist, then the SparForte variable is unchanged.
  • pragma unchecked_import_json( shell | cgi | local_memcache | memcache, var ) - the same as import_json execpt that there is no existence check. If the import variable doesn't exist, then the SparForte variable is unchanged.
  • pragma unrestricted_template( css|html|js|json|text|wml|xml [, template] ) - SparForte will act like a template processor (like PHP). This pragma is the same as pragma template except that the embedded scripts are executed in a normal shell with no security restrictions. The type parameter is described under pragma template.
  • pragma volatile( var ) - the variable is assumed to be an variable which may change unexpectedly during the script's execution. The variable's value will be updated each time it is referenced in an expression. Has no effect unless the variable is imported as well.

Miscellaneous Pragmas

Interpreter directives that don't fit in any other category.

  • pragma prompt_script( `commands` ) - commands to draw the command prompt.  If the string is an empty string, the default "=>" prompt is used.  Make sure the final command ends with a semi-colon.  Changing your prompt will also change the title of your terminal window.

Shell Variables

UNIX-like operating systems have environment variables. These are variables that the operating system assign to your running program.

You can also read environment variables using the command_line package.

Importing Shell Environment Variables

Normally, SparForte will not copy your environment variables into SparForte. Instead, you request the variables using pragma import. SparForte will examine the environment variables and, if it finds one with the same name, the SparForte variable will have the same value as the environment variable.

=> JAVA_HOME : string
=> pragma import( shell, JAVA_HOME )
=> ? JAVA_HOME
/usr/lib64/jvm/java
 

Example: Importing an environment variable on the command line

A few variables are automatically imported when SparForte runs. These variables are needed for the proper functioning of the shell (for example, HOME). You can also use the --import-all command line option to import all the environment variables. However, --import-all is meant to be a convenience or debugging tool: it is a better technique to import only what your script needs to run.

You can examine a variable with env to see if it is imported or exported.

=> env HOME
HOME := "/home/ken"; -- imported shell environment identifier of the type string

If the variable doesn't exist, SparForte will report an error. This behaviour can be overridden using pragma unchecked_import: if the variable doesn't exist in the environment, the value will be unchanged. It is a good idea to assign a default value.

If you are using SparForte as your login shell, there is nothing to import: there's no previous shell to import variable from to put them into SparForte.

Exporting Shell Environment Variables

To make your Sparforte variables visble to other programs, such as external commands, you must export the variable into the operating system environment variables with pragma export. This exporting process occurs whenever an external command is executed, the standard technique in shells.

=> JAVA_HOME : string := "/usr/lib64/jvm/java"
=> pragma export( shell, JAVA_HOME )
=> eclipse & -- a command that needs JAVA_HOME

If you use SparForte as your login shell, variables like JAVA_HOME can be set up in your SparForte profile file so they are created and exported whenever you log in.

Both Importing and Exporting, and Volatile Shell Environment Variables

Environment variables can be both imported and exported by using both pragmas.

=> DISPLAY : string;
=> pragma import( shell, DISPLAY )
=> pragma export( shell, DISPLAY )
=> env DISPLAY
DISPLAY := ":0.0"; -- imported exported shell environment identifier of the type string
 

Example: Importing and Exporting the X Windows DISPLAY variable

Pragma volatile will mark a variable as "volatile", meaning that its value can change unexpectedly and SparForte should reload the value from the environment whenever it is referenced. Although you can make volatile environment variables, it probably won't be useful: these variables are owned by the running process, which is SparForte, so it is virtually impossible to change their values except using the SparForte itself.

CGI Variables

CGI variables are the HTTP FORM tag variables submitted from a web page. If you are in a web template (if you used pragma template or pragma unrestricted_template), you can read the variables using pragma import.

If the variable doesn't exist, SparForte will report an error. This behaviour can be overridden using pragma unchecked_import: if the variable doesn't exist in the environment, the value will be unchanged. It is a good idea to assign a default value.

You cannot export CGI variables: there's nowhere to export the values to.

Pragma volatile can be used, but like shell variables, it has no meaningful effect: the CGI variables will not change while in a template.

You can also read CGI variables using the CGI package.

Local Memcache Variables

Memcached (or the Memcache Daemon) is a general-purpose networked memory caching system that was originally developed by Danga Interactive for LiveJournal, but is now used by many other sites. It is often used to speed up dynamic database-driven websites by caching data and objects in RAM to reduce the number of times an external data source (such as a database or API) must be read. Memcached has been used by web sites including YouTube, Facebook and Twitter.

SparForte supports memcached natively (that is, you don't need to use a special package to access memcached.) The memcached support is built on the PegaSoft PegaSock socket library, which supports local memcached caching as well as distributed, redundant memcached caching clusters.

One important rule: PegaSock expects a non-empty string for all variable values (it uses an empty string to represent a cache miss.)

When importing or exporting to local_memcache, the variables will be imported or exported from your local machine. SparForte expects to find a memcached server running on localhost and port 11211 (the default memcached port).

All SparForte scripts running on the same server can access the memcache variables.

=> s : string := "test"
=> pragma export( local_memcache, s )
=> env s
s := "test"; -- exported local memcache identifier of the type string
=> unset s
=> s : string := "not test"
=> pragma import( local_memcache, s )
=> ? s
test
 

Example: A simple command line example of local_memcache

Importing with Memcache

When importing, The variable will be read from memcache when pragma import is used.

=> user_count : string
=> pragma import( local_memcache, user_count )
=> env user_count
user_count := " 3"; -- imported local memcache identifier of the type string
 

Example: Importing a memcached variable on the command line

(For example, if you import a variable named "user_count", SparForte will request the value of "user_count" from memcached hash table on the localhost using a memcached GET command.)

If the variable doesn't exist, SparForte will report an error. This behaviour can be overridden using pragma unchecked_import: if the variable doesn't exist in the environment, the value will be unchanged. It is a good idea to assign a default value.

The variable will normally be read at the time of importing, though this behaviour can be changed with pragam volatile (see below).

You can use a declare block to get the value at your discretion by using an imported variable.

declare
  -- Get current value from memcached
  status : string;
  pragma import( local_memcache, status );
begin
  -- do something with status
end;
 

Example: Using declare to import on demand

Exporting with Memcache

When exporting, the variable's final value will be stored in memcache with the memcache SET command when the varible goes out of scope or is destroyed with unset.

You can update the value at any time using a declare block and an exported variable:

new_status_value := "good";
declare
  -- Push out new value to memcached
  status : string := new_status_value;
  pragma export( local_memcache, status );
begin
  null; -- do nothing
end; -- before discarding status, write it to memcached
 

Example: Using declare to export on demand

Importing, Exporting and Volatile with Memcache

It is possible to declare a variable as both imported and exported using both import/export pragmas.

Pragma volatile will mark a variable as "volatile", meaning that its value can change unexpectedly and SparForte should reload the value from the memcached whenever it is referenced.

You can declare a variable as import, export and volatile. For example:

declare
  user_count : string;
  pragma import( local_memcache, user_count );
  pragma export( local_memcache, user_count );
  pragma volatile( user_count );
begin
-- do some other work here
  user_count := strings.image( integer( numerics.value( @ ) + 1 ) );
end;
 

Example: Using import, export and volatile

In this example, the assignment statement will get the latest value for user_count, convert it to a number, add 1 and convert the result back to a string. When the declare block ends, the value of user_count will be stored in memcached.

Bear in mind that this kind of operation is not atomic: another script could try to update user_count in memcache before the first script can write the result. If you want to lock access to the variable to guarantee exclusive access, you will need to use the lock_file package or a similar approach.

Handling Server Failures

PegaSock uses a countdown system when a memcache server cannot be found. If it cannot connect, it marks the server as off-line and will return cache misses for several commands. After enough commands have passed, it will attempt to reconnect to memcached. These "back offs" are escallating: each failed reconnect attempt will result in a longer backoff period. This is done for performance reasons: establishing new network connections is a very slow operation.

If you don't have memcached running on your local machine, it will have the same effect.

You'll periodically see warning messages from PegaSock because it is unable to establish a connection.

=> s : string
=> pragma import( local_memcache, s )
pegasock-memcache.adb:81: server localhost 11211 error - backing off for 8 tries
 

Example: The memcached server is not running or cannot be accessed

Distributed Memcache Variables

If you have memcached running on two or more servers, you can create a redundant distributed cache using the "memcache" method instead of "local_memcache". In order to use a distributed cache, inform SparForte of what servers to use with pragma register_memcache_server.

=> pragma register_memcache_server( "cachehost1", 11211 );
=> pragma register_memcache_server( "cachehost2", 11211 );
=> company_name : string
=> pragma import( memcache, company_name )
=> ? company_name
PegaSoft Canada
=> env company_name
company_name := "PegaSoft Canada"; -- imported memcache identifier of the type string
 

Example: Importing a variable stored on two hosts

With more than one server, SparForte will store the variable on two servers. If one server should fail, it wil retrieve the variable value from the other.

Managing Script Licenses

Tracking and keeping accurate information about licenses is important for large companies and organizations. Such groups may run third-party license management software which scans source code and tries to guess at what license applies. However, typos and copying errors putting license info into comments makes this an imperfect task. Software may be bundled together with multiple licenses. Licenses are further qualified by server limits, user limits, evaluation periods or other real world or legal concerns.

SparForte can help manage licenses with the license pragma. This pragma declares the license for a script in a structured way. This approach assists in automating license compliance, helps to make the best use of licenses while reducing the risk from a license audit. Since there are thousands of licenses, SparForte doesn't attempt to know, enforce or reconcile every license—it leaves these concerns for specialized license software. However, many of the most popular licenses are known by SparForte.

For example, if myscript.sp contains this pragma:

pragma license( public_domain );

then you can use the help command to see the license without running the script.

$ spar -e "help -l myscript.sp;"
public_domain

If you use license management software, configure it to run the spar help command to get an accurate license name.

If you have a commercial license, declare it as commercial and include more details in the second parameter, or use the second parameter as a URL to the text of the license.

pragma license( commercial, "bogodb license" );

The help command will show the license with the additional text.

$ spar -e "help -l myscript.sp;"
commercial: bogodb license

A script may only have one license pragma.

Other examples:

pragma license( gpl );
pragma license( freeware, "2 week evaluation" );
pragma license( gplv2, "LGPL" );
pragma license( commercial, "bogodb license: 15 users" );

Running scripts may check the license string with System.Script_License.

=> pragma license(bsd_original)
=> ? System.Script_License
bsd_original
 
[Right Submenu]

 AdaScript versus GCC

 Case Sensitivity

 Reserved Words

 Comments

 Literals

 Bourne Shell Word Expansions

 Fundamental Types

 User-defined Types

 Enumerated Types

 Arrays

 Records

 Basic Assignment

 The @ and % Operands

 Command Argument Shortcuts

 Redirection and Pipelines

 Command Line Interaction

 Built-in Shell Commands

 The Current Directory

 Database Commands

 Flow of Control

 Other Statements/ Subprograms

 External Commands

 Block Statements and Subprograms

 TCP/IP Sockets

 Numeric Formatting with Put

 Interpreter Directives

 Command Line Options

 Command Reference

 ASCII and Latin_1 Character Sets

 Common Error Messages

 Common PHP Functions and the SparForte Equivalent

[Back to Top] Back To Top [Small Forte Symbol]