implicit

implicit

part of shnell – a source to source compiler enhancement tool

© Jens Gustedt, 2019

A tool to import headers from other TU implicitly.

Usage:

#pragma CMOD amend implicit [LPREFIX] [ : [ PREFIX0 PREFIX1 ...] ]

This directive will seek for all composed identifiers that are neither derived from the short nor the long prefix. These composed identifiers are used to extract the names of all TU that are implicitly used. Then it will look for a .h or .o file to include. The base name of such files is formed from the TU’s prefix where the separators are replaced by -.

For the role of the parameters and identifier naming conventions see export. Both are best used indirectly through the dialect TRADE and even better through the command line prefix trade.

Functionality

An identifier A0::...::AN::AN1 that is encountered by scanning the source could come from two different other TU: A0::...::AN::AN1 itself (if it represents the main feature of that TU) or A0::...::AN (if it is a secondary feature of that) . Both are searched in the current directory and SHNELL_INCLUDE if such a file exists.

A list of legacy pseudo-TU can be kept for which it is assumed that they use top level identifiers for their symbols. Use this feature only if you must, notably for legacy interfaces that you can’t change. The stdc prefix for the standard C library is always included in that list. Identifiers found in such a legacy realm are translated back to that toplevel form by a set of macros that is put in front of the source code. You may add legacy realms to the list by using the legacy directive in a scan of the source that preceeds the scan for implicit.

It is the responsibility of the code using this feature to ensure that the symbols that are used in this way are really declared by the header file. A typical example would be stdc::printf which would trigger the integration of an include line

`#include "stdc.h"`

This include file then gives access to all the C library headers, where a function printf should indeed be provided.

main is special

With all of this you would never be able to produce a function with the bare name main, and thus you would never be able to produce a working executable. In fact, the name main itself is reserved by the C standard for the entry point of the program, and so you should define such a function as stdc::main instead of main. This guarantees that we do not rewrite that name, and that the compiler sees bare main as he should.

startup and atexit handlers

TU that use some resources in the backgroung may need to enable such resources at startup (e.g open a log file) or release them at exit time (e.g print a time stamp to a log file). This can be achived by instauring startup and atexit handlers, respectively.

Makefile

If the environment variables SHNELL_MAKEFILE is set to a directory name, this directive places a makefile, there, that reflects all the implicit dependencies that were found. If the file exist, it is only modified if there was a change in the dependencies.

Implementation considerations

We use sorting to have unique lists of symbols. Therefore we must ensure that the collating sequence of the locale is ignored.

export LC_COLLATE=C
SORT="${SORT:-sort}"
SORTUNIQ="${SORTUNIQ:--u}"

Coding and configuration

The following code is needed to enable the sh-module framework.

SRC="$_" . "${0%%/${0##*/}}/import.sh"

Imports

The following sh-modules are imported:

Details

Declared functions

implicit: The actual work of this shnell-module is done here.