Next: , Previous: Lists, Up: Library Reference


3.2 Characters and Strings

If a C program is to interact with a virtual code application by exchanging text, it uses the representation for characters described in Character Table. This convention would be inconvenient without a suitable API, so the functions in this section address the need. These functions are declared in the header file chrcodes.h.

Some of these functions have two forms, with one of them having the word standard as part of its name. The reason is to cope with multiple character encodings. Versions of avram prior to 0.1.0 used a different character encoding than the one documented in Character Table. The functions described in Version Management can be used to select backward compatible operation with the older character encoding. The normal forms of the functions in this section will use the older character set if a backward compatibility mode is indicated, whereas the standard forms will use the character encoding documented in Character Table regardless.

Standard encodings should always be assumed for library and function names associated with the library combinator (Calling existing library functions), and for values of lists defined by avm_list_of_value (Primitive types), but version dependent encodings should be used for all other purposes such as error messages. Alternatively, the normal version dependent forms of the functions below can be used safely in any case if backward compatibility is not an issue. This distinction is viewed as a transitional feature of the API that will be discontinued eventually when support for the old character set is withdrawn and the standard forms are be removed.

— Function: list avm_character_representation (int character)
— Function: list avm_standard_character_representation (int character)

This function takes an integer character code and returns a copy of the list representing it, as per the table in Character Table. Because the copy is shared, no memory is allocated by this function so there is no possibility of overflow. Nevertheless, it is the responsibility of the caller dispose of the list when it is no longer needed by avm_dispose, just as if the copy were not shared (Simple Operations). For performance reasons, this function is implemented as a macro. If the argument is outside the range of zero to 255, it is masked into that range.

— Function: int avm_character_code (list operand)
— Function: int avm_standard_character_code (list operand)

This function takes a list as an argument and returns the corresponding character code, as per Character Table. If the argument does not represent any character, a value of -1 is returned.

— Function: list avm_strung (char *string)
— Function: list avm_standard_strung (char *string)

This function takes a pointer to a null terminated character string and returns the list obtained by translating each character into its list representation and enqueuing them together. Memory needs to be allocated for the result, and if there isn't enough available, an error message is written to standard error and the process is terminated. This function is useful to initialize lists from hard coded strings at the beginning of a run, as in this example.

          hello_string = avm_strung("hello");

This form initializes a single string, but to initialize a one line message suitable for writing to a file, it would have to be a list of strings, as in this example.

          hello_message = avm_join(avm_strung("hello"),NULL);

The latter form is used internally by the library for initializing most of the various error messages that can be returned by other functions.

— Function: list avm_recoverable_strung (char *string, int *fault);
— Function: list avm_recoverable_standard_strung (char *string, int *fault);

This function is like avm_strung except that if it runs out of memory it sets the integer referenced by fault to a non-zero value and returns instead of terminating the process.

— Function: char *avm_unstrung (list string, list *message, int *fault)
— Function: char *avm_standard_unstrung (list string, list *message, int *fault)

This function performs an inverse operation to avm_recoverable_strung, taking a list representing a character string to the character string in ASCII null terminated form as per the standard C representation. Memory is allocated for the result by this function which should be freed by the caller.

In the event of an exception, the integer referenced by fault is assigned a non-zero value and an error message represented as a list is assigned to the list referenced by message. The error message should be reclaimed by the caller with avm_dispose (Simple Operations if it is non-empty. Possible error messages are <'memory overflow'>, <'counter overflow'>, and <'invalid text format'>.

— Function: list avm_scanned_list (char *string)

An application that makes use of virtual code snippets or data that are known at compile time can use this function to initialize them. The argument is a string in the format described in Concrete Syntax, and the result is the list representing it. For example, the program discussed in Example Script could be hard coded into a C program by pasting the data from its virtual code file into an expression of this form.

          cat_program = avm_scanned_list("sKYQNTP\\");

Note that the backslash character in the original data has to be preceded by an extra backslash in the C source, because backslashes usually mean something in C character constants.

The avm_scanned_list function needs to allocate memory. If there isn't enough memory available, it writes a message to standard error and causes the process to exit.

— Function: list avm_multiscanned (char **strings)

Sometimes it may be useful to initialize very large lists from strings, but some C compilers impose limitations on the maximum length of a string constant, and the ISO standard for C requires only 512 bytes. This function serves a similar purpose to avm_scanned_list, but allows the argument to be a pointer to a null terminated array of strings instead of one long string, thereby circumventing this limitation in the compiler.

          char *code[] = {"sKYQ","NTP\\",NULL};
          ...
          cat_program = avm_multiscanned(code);

If there is insufficient memory to allocate the list this function needs to create, it causes an error message to be written to standard error, and then kills the process.

— Function: char* avm_prompt (list prompt_strings)

This function takes a list representing a list of character strings, and returns its translation to a character string with the sequence 13 10 used as a separator. For example, given a tree of this form

          some_message = avm_join(
             avm_strung("hay"),
             avm_join(
                avm_strung("you"),
                NULL));

the result returned by prompt_strings(some_message) would be a pointer to a null terminated character string equivalent to the C constant "hay\13\10you".

Error messages are printed and the process terminated in the event of either a memory overflow or an invalid character representation.

This function is used by avram in the evaluation of interactive virtual code applications, whose output has to be compared to the output from a shell command in this format. The separator is chosen to be compatible with the expect library.

— Function: char* avm_recoverable_prompt (list prompt_strings, list *message, int *fault)

This function performs the same operation as avm_prompt but allows the caller to handle exceptional conditions. If an exception such as a memory overflow occurs, the integer referenced by fault is assigned a non-zero value and a representation of the error message as a list of strings is assigned to the list referenced by message.

This function is used to by avram to evaluate the interact combinator (Interaction combinator), when terminating in the event of an error would be inappropriate.

— Function: void avm_initialize_chrcodes ()

This function has to be called before any of the other character conversion functions in this section, or else their results are undefined. It performs the initialization of various internal data structures.

— Function: void avm_count_chrcodes ()

This function can be called at the end of a run, after the last call to any of the other functions in this section, but before avm_count_lists if that function is also being used. The purpose of this function is to detect and report memory leaks. If any memory associated with any of these functions has not been reclaimed by the client program, a message giving the number of unreclaimed lists will be written to standard error.