# Scripting - User Intro

This document is an introduction to fungw for pcb-rnd users. It focuses on scripting pcb-rnd and doesn't discuss fungw deeper than the minimum necessary. Fungw is more generic than shown here.

## 1.1. Stored scripts

Stored scripts are typically larger piece of works that register actions, may create menus, GUI dialog boxes. Their role is to introduce new functionality to pcb-rnd - functionality written and shared by users, using their favorite script language.

Loading a script using the CLI: run action

    	LoadScript(id, filename, language)

where id is an arbitrary text ID. The ID is used for referencing the script once it is loaded. The filename should be a full path (CWD is pcb-rnd's CWD). Language must be one of the languages configured in fungw.

Once the script is loaded, it is accessible by calling the actions it registered using the standard fgw_func_reg() mechanism.

Scripts can be unloaded using the action

    	UnloadScript(id)

## 1.2. Oneliners

Note: examples in this section assume pcb-rnd is configured and compiled with system installed fungw, and libmawk is also installed and the libmawk binding is compiled in fungw.

pcb-rnd also offers script one-liners. A one-liner is a short script intended to do one thing at the moment of execution. It is typically not saved in a file and is not recalled later. One-liners are invoked by the Oneliner action:

    	OneLiner(awk, 'message("hello")')

Alternatively the language-specific shorthand action can be used; the following example is equivalent to the above example:

    	awk('message("hello")')

A third approach, most convenient for experimenting, is switching the command line interpreter to the given script lagnuage temporarily. For this the shorthand action (e.g. "awk", "python", "perl") should be exected without arguments. The promp of the cli changes to reflect the language that will interpret all the following command lines entered. To leave the script mode, type "/exit".

For example:

- open the command line (pressing ':' with the default menu config)
- enter awk and press enter - this will switch to awk mode
- enter for(y=1; y < 10; y += 3) { createtext("#1", 0, "1 mm", y " mm", 0, 100, "foo:" y) }
- either enter more awk one-liners or leave the awk mode by typing /exit

The one-liner mode can be used to get a better command interpreter. After all, any pcb-rnd action is accessible from any scripting language. For example the user may choose to switch to awk mode and issue normal pcb-rnd actions using the awk syntax. The default mode can even be configured through the conf system, by setting rc/cli_backend to the language name. However, the CPU and memory footprint of executing a full script interpreter for each command entered should be noted.

Limitations: each command line is a separate script context, there are no script states (e.g. variables) preserved between lines entered. Actions defined in one-liners are also discarded after the one-liner finished. For such use cases, stored script shall be written.

# Scripting - Developer Intro

## 2.1. The big picture

The main interface between pcb-rnd internals and the outside world (e.g. user interface, scripts) is called actions. An action is typically a function with a few arguments that executes a smallish task. The actions implemented by pcb-rnd are all functions written in C; some of the actions are part of core pcb-rnd, others are implemented in plugins.

GUI operations, menu items, clicking on buttons all call these actions. The advantage of this system is that the actions are accessible in an user-interface-independent way: the same operations can be done with and without GUI, initiated by an user with a mouse or by a script.

Thus the two main aspects of pcb-rnd scripting are:

- defining new actions in script; actions that then can be called from the user interface or from other scripts
- calling pcb-rnd actions from within the script to execute the actual task

## 2.2. Defining actions

With fungw, every action is just a native function - the syntax varies from scripting language to scripting language (see the rosetta hello world example). The arguments of the function are the arguments of the action. The return value of the function is the return value of the action.

For the arguments, new actions should try to follow the conventions that can be found in already existing core actions for similar purpose.

The return value depends on the purpose of the action. If the action is used to calculate something, typically not changing any global state (e.g. the board), it should return the value calculated, in whatever scalar native data type the scripting language supports. If the action is not called to get a value but to perform some changes, the return value should be an integer: 0 means success, anything else means error.

## 2.3. Calling actions

The script may call any action available at a given time, independently of whether the action is defined in pcb-rnd core, in plugins or in other scripts. In most scripting languages the action call looks like a simple function call: function arguments are the action's arguments, the return value of the function is the return value generated by the action. The calls are all single threaded, blocking calls. The script may use any scalar native data type for action arguments without conversion, fungw will take care of the conversions automatically.

## 2.4. Action names

All action names are registered in lowercase version. The script shall register lower case function names and action (function) calls should be spelled lowercase too.