Visión general del procesador de macros m4

Este tema proporciona información sobre el procesador de macros m4 , que es un procesador frontal para cualquier lenguaje de programación que se utilice en el entorno del sistema operativo.

Al principio de un programa, puede definir un nombre simbólico o una constante simbólica como una serie concreta de caracteres. A continuación, puede utilizar el procesador de macros m4 para sustituir las apariciones sin comillas del nombre simbólico por la serie correspondiente. Además de sustituir una serie de texto por otra, el procesador de macros m4 proporciona las características siguientes:

  • Prestaciones aritméticas
  • Manipulación de archivos
  • Expansión de macro condicional
  • Funciones de serie y subserie

El procesador de macros m4 procesa series de letras y dígitos denominadas señales. El procesador de macros m4 lee cada símbolo alfanumérico y determina si es el nombre de una macro. A continuación, el programa sustituye el nombre de la macro por su texto de definición y devuelve la serie resultante a la entrada que se va a volver a explorar. Puede llamar a macros con argumentos, en cuyo caso los argumentos se recopilan y se sustituyen en los lugares correctos del texto de definición antes de que se vuelva a escanear el texto de definición.

El procesador de macros m4 proporciona macros incorporadas como define. También puede crear nuevas macros. Las macros incorporadas y definidas por el usuario funcionan de la misma manera.

Utilización del procesador de macros m4

Para utilizar el procesador de macros m4 , especifique el mandato siguiente:

m4 [file]

El procesador de macros m4 procesa cada argumento en orden. Si no hay argumentos o si un argumento es - (guión), el procesador de macros m4 lee la entrada estándar como su archivo de entrada. El procesador de macros m4 graba sus resultados en la salida estándar. Por lo tanto, para redirigir la salida a un archivo para su uso posterior, utilice un mandato como el siguiente:

m4 [file] >outputfile

Creación de una macro definida por el usuario

Macro Descripción
define (MacroName, Replacement) Define la nueva macro MacroName con un valor de Replacement.

Por ejemplo, si la sentencia siguiente está en un programa:

define(name, stuff)

El procesador de macros m4 define la serie name comostuff.Cuando la serie name aparece en un archivo de programa, el procesador de macros m4 la sustituye por la seriestuff.La serienamedebe ser alfanumérico ASCII y debe empezar por una letra o un subrayado. La seriestuffes cualquier texto, pero si el texto contiene paréntesis, el número de paréntesis abiertos o izquierdos debe ser igual al número de paréntesis cerrados o derecho. Utilice el carácter / (barra inclinada) para dispersar el texto parastuffen varias líneas.

El paréntesis de apertura (izquierda) debe ir inmediatamente después de la palabra define. Por ejemplo:

define(N, 100)
 . . . 
if (i > N)

defineNpara ser100y utiliza la constante simbólica N en una sentencia if posterior.

Las llamadas de macro de un programa tienen el formato siguiente:

name(arg1,arg2, . . . argn)
Un nombre de macro sólo se reconoce si está rodeado por caracteres no alfanuméricos. En el ejemplo siguiente, la variableNNNno está relacionado con la macro definidaN.
define(N, 100)
 . . . 
if (NNN > 100)

Puede definir macros en términos de otros nombres. Por ejemplo:

define(N, 100)
define(M, N)

define ambosMyNpara ser100. Si más adelante cambia la definición deNy asignarle un nuevo valor,Mretiene el valor de100, noN.

El procesador de macros m4 expande los nombres de macro en su texto de definición lo antes posible. La serieNse sustituye por100. A continuación, la serieMtambién se sustituye por100. El resultado global es el mismo que utilizar la siguiente entrada inicialmente.

define(M, 100)

El orden de las definiciones se puede intercambiar de la forma siguiente:

define(M, N)
define(N, 100)

AhoraMse ha definido para que sea la serieN, por lo tanto, cuando el valor deMse solicita más tarde, el resultado es el valor deNen ese momento (porque el M se sustituye porN, que se sustituye por100).

Utilización de los caracteres de comillas

Para retrasar la expansión de los argumentos de define, enciérrelos entre comillas. Si no los cambia, los caracteres de comillas son ` y ' (comillas simples izquierda y derecha). Cualquier texto entre comillas no se expande inmediatamente, pero se eliminan los caracteres de comillas. El valor de una serie entrecomillada es la serie con los caracteres de comillas eliminados. Si la entrada es:

define(N, 100)
define(M, `N')

Los caracteres de comillas alrededor delNse eliminan a medida que se recopila el argumento. El resultado de utilizar caracteres de comillas es definirMcomo la serieN,no100. La regla general es que el procesador de macros m4 siempre elimina un nivel de comillas cuando evalúa algo. Esto es cierto incluso fuera de macros. Para hacer la palabradefineaparecen en la salida, escriba la palabra entre comillas, como se indica a continuación:

`define' = 1;

Otro ejemplo de uso de caracteres de comillas es la redefiniciónN. Para redefinirN, retrasar la evaluación poniendoNentre comillas. Por ejemplo:

define(N, 100)
. . . 
define(`N', 200)

Para evitar que se produzcan problemas, cite el primer argumento de una macro. Por ejemplo, el fragmento siguiente no redefineN:

define(N, 100)
. . . 
define(N, 200)

Los 2Nen la segunda definición se sustituye por 100. El resultado es el mismo que la sentencia siguiente:

define(100, 200)

El procesador de macros m4 ignora esta sentencia porque sólo puede definir nombres, no números.

Cambio de los caracteres de comillas

Los caracteres de comillas son normalmente ` y ' (comillas simples izquierda o derecha). Si estos caracteres no son convenientes, cambie los caracteres de comillas con la siguiente macro incorporada:

Macro Descripción
changequote (l, r ) Cambia los caracteres de comilla izquierda y derecha a los caracteres representados por las variables l y r .

Para restaurar los caracteres de comillas originales, utilice changequote sin argumentos como se indica a continuación:

changequote

Argumentos

La forma más simple del proceso de macro es sustituir una serie por otra serie (fija). Sin embargo, las macros también pueden tener argumentos, de modo que puede utilizar la macro en diferentes lugares con resultados diferentes. Para indicar dónde se va a utilizar un argumento dentro del texto de sustitución para una macro (el segundo argumento de su definición), utilice el símbolo $n para indicar el argumento n. Cuando se utiliza la macro, el procesador de macros m4 sustituye el símbolo por el valor del argumento indicado. Por ejemplo, el siguiente símbolo:

$2

Se refiere al segundo argumento de una macro. Por lo tanto, si define una macro denominadabumpcomo:

define(bump, $1 = $1 + 1)

El procesador de macros m4 genera código para incrementar el primer argumento en 1. Los 2bump(x)la sentencia es equivalente a x = x + 1.

Una macro puede tener tantos argumentos como sea necesario. Sin embargo, sólo puede acceder a nueve argumentos utilizando el símbolo $n ($1a$9). Para acceder a los argumentos más allá del noveno argumento, utilice la macro shift .

Macro Descripción
shift (ParameterList) Devuelve todo menos el primer elemento de ParameterList para realizar un desplazamiento a la izquierda destructivo de la lista.

Esta macro descarta el primer argumento y reasigna los argumentos restantes a los símbolos $n (segundo argumento a$1, tercer argumento para$2... décimo argumento para$9). El uso de la macro shift más de una vez permite acceder a todos los argumentos utilizados con la macro.

La macro $0 devuelve el nombre de la macro. Los argumentos que no se proporcionan se sustituyen por series nulas, de modo que puede definir una macro que concatene sus argumentos como se indica a continuación:

define(cat, $1$2$3$4$5$6$7$8$9)

Así:

cat(x, y, z)

es el mismo que:

xyz

Argumentos$4a$9en este ejemplo son nulos porque no se han proporcionado los argumentos correspondientes.

El procesador de macros m4 descarta los espacios en blanco sin comillas iniciales, tabuladores o caracteres de nueva línea en los argumentos, pero mantiene el resto de espacios en blanco. Así:

define(a, b c)

defineapara serb c.

Los argumentos están separados por comas. Utilice paréntesis para encerrar los argumentos que contienen comas, para que la coma no termine el argumento. Por ejemplo:

define(a, (b,c))

tiene sólo dos argumentos. El primer argumento esa, y el segundo es (b,c). Para utilizar una coma o un paréntesis simple, enciérrela entre comillas.

Utilización de una macro m4 predefinida

El procesador de macros m4 proporciona un conjunto de macros predefinidas. Esta sección explica muchas de las macros y sus usos.

Eliminación de una definición de macro

Macro Descripción
undefine (`MacroName') Elimina la definición de una macro definida por el usuario o incorporada (`NombreMacro')

Por ejemplo:

undefine(`N')

elimina la definición de N. Después de eliminar una macro incorporada con la macro undefine , como se indica a continuación:

undefine(`define')

No puede volver a utilizar la definición de la macro incorporada.

En este caso, se necesitan comillas simples para evitar la sustitución.

Comprobación de una macro definida

Macro Descripción
ifdef (`NombreMacro', Argument1, Argument2) Si la macro MacroName está definida y no está definida en cero, devuelve el valor de Argument1. De lo contrario, devuelve Argument2.

La macro ifdef permite tres argumentos. Si se define el primer argumento, el valor de ifdef es el segundo argumento. Si el primer argumento no está definido, el valor de ifdef es el tercer argumento. Si no hay ningún tercer argumento, el valor de ifdef es nulo.

Utilización de aritmética de enteros

El procesador de macros m4 proporciona las siguientes funciones incorporadas para realizar la aritmética sólo en enteros:

Macro Descripción
incr (Número) Devuelve el valor de Número + 1.
decr (Número) Devuelve el valor de Número -1.
eval Evalúa una expresión aritmética.

Por lo tanto, para definir una variable como una más que el valor Número , utilice lo siguiente:

define(Number, 100)
define(Number1, `incr(Number)')

Esto defineNumber1como uno más que el valor actual deNumber.

La función eval puede evaluar expresiones que contienen los siguientes operadores (listados en orden descendente de prioridad):
  • unary + y -
  • ** o ^ (exponenciación)
  • */% (módulo)
  • + -
  • == != < <= > >=
  • !(no)
  • & o & & (AND lógico)
  • | o | | (OR lógico)

Utilice paréntesis para agrupar operaciones cuando sea necesario. Todos los operandos de una expresión deben ser numéricos. El valor numérico de una relación verdadera (por ejemplo, 1 > 0) es 1 y false es 0. La precisión de la función eval es de 32 bits.

Por ejemplo, definaMpara ser2==N+1utilizando la función eval como se indica a continuación:

define(N, 3)
define(M, `eval(2==N+1)')

A menos que el texto sea muy simple, utilice caracteres de comillas alrededor del texto que define una macro

Manipulación de archivos

Para fusionar un archivo nuevo en la entrada, utilice la función include incorporada.

Macro Descripción
include (Archivo) Devuelve el contenido del archivo Archivo.

Por ejemplo:

include(FileName)

inserta el contenido deFileNameen lugar del mandato include .

Se produce un error muy grave si no se puede acceder al archivo especificado en la macro include . Para evitar un error muy grave, utilice el formato alternativo, la macro sinclude (inclusión silenciosa).

Macro Descripción
sinclude (Archivo ) Devuelve el contenido del archivo Archivo, pero no informa de un error si no puede acceder a Archivo.

La macro sinclude (inclusión silenciosa) no escribe un mensaje, pero continúa si no se puede acceder al archivo especificado.

Redirigir la salida

La salida del procesador de macros m4 se puede redirigir de nuevo a archivos temporales durante el proceso, y el material recopilado se puede generar tras el mandato. El procesador de macros m4 mantiene nueve posibles archivos temporales, numerados del 1 al 9. Si utiliza la macro divert incorporada.

Macro Descripción
divert (Número) Cambia la corriente de salida al archivo temporal Número.

El procesador de macros m4 graba toda la salida del programa después de la función divert al final del archivo temporal, Número. Para devolver la salida a la pantalla de visualización, utilice la función divert o divert(0) , que reanuda el proceso de salida normal.

El procesador de macros m4 graba toda la salida redirigida en los archivos temporales en orden numérico al final del proceso. El procesador de macros m4 descarta la salida si redirige la salida a un archivo temporal distinto de 0 a 9.

Para devolver los datos de todos los archivos temporales en orden numérico, utilice la macro undivert incorporada.

Macro Descripción
undivert (Number1, Number2... ) Añade el contenido de los archivos temporales indicados al archivo temporal actual.

Para devolver los archivos temporales seleccionados en un orden especificado, utilice la macro incorporada undivert con argumentos. Cuando se utiliza la macro undivert , el procesador de macros m4 descarta los archivos temporales que se recuperan y no busca macros en los datos recuperados.

El valor de la macro undivert no es el texto desviado.

Puede utilizar la macro divnum para determinar qué archivo temporal se está utilizando actualmente.

Macro Descripción
núm_divm Devuelve el valor del archivo temporal activo actualmente.

Si no cambia el archivo de salida con la macro divert , el procesador de macros m4 coloca toda la salida en un archivo temporal denominado 0.

Utilización de programas del sistema en un programa

Puede ejecutar cualquier programa en el sistema operativo desde un programa utilizando la macro syscmd incorporada. Por ejemplo, la sentencia siguiente ejecuta el programa date :

syscmd(date)

Utilización de nombres de archivo exclusivos

Utilice la macro maketemp incorporada para crear un nombre de archivo exclusivo a partir de un programa.

Macro Descripción
maketemp (Serie ... nnnnn ...Serie) Crea un nombre de archivo exclusivo sustituyendo los caracteres nnnnn en la serie de argumento con el ID de proceso actual.

Por ejemplo, para la sentencia:

maketemp(myfilennnnn)

el procesador de macros m4 devuelve una serie que esmyfileconcatenado con el ID de proceso. Utilice esta serie para nombrar un archivo temporal.

Utilización de expresiones condicionales

La evaluación de expresiones condicionales permite la determinación del tiempo de proceso de las expresiones de macro.

Expresión Descripción
ifelse (String1, String2, Argument1, Argument2) Si String1 coincide con String2, devuelve el valor de Argument1. De lo contrario, devuelve Argument2.

La macro ifelse incorporada realiza pruebas condicionales. En la forma más sencilla:

ifelse(a, b, c, d)

compara las dos seriesayb.

Siaybson idénticos, la macro ifelse incorporada devuelve la seriec. Si no son idénticos, devuelve una seried. Por ejemplo, puede definir una macro denominadacomparepara comparar dos series y devolveryessi son iguales, onosi son diferentes, como se indica a continuación:

define(compare, `ifelse($1, $2, yes, no)')

Los caracteres de comillas impiden que la evaluación de la macro ifelse se produzca demasiado pronto. Si falta el cuarto argumento, se trata como vacío.

La macro ifelse puede tener cualquier número de argumentos y, por lo tanto, proporciona una forma limitada de capacidad de decisión de varias vías de acceso. Por ejemplo:

ifelse(a, b, c, d, e, f, g)

Esta sentencia es lógicamente la misma que el fragmento siguiente:

if(a == b) x = c;
else if(d == e) x = f;
else x = g;
return(x);

Si se omite el argumento final, el resultado es nulo, por lo que:

ifelse(a, b, c)

escifacoincidenciasb, y nulo en caso contrario.

Manipulación de series

Las macros de esta sección le permiten convertir series de entrada en series de salida.

Macro Descripción
lon Devuelve la longitud de byte de la serie que compone su argumento

Así:

len(abcdef)

es 6, y:

len((a,b))

5.

Macro Descripción
DLEN Devuelve la longitud de los caracteres visualizables en una serie

Los caracteres constitutivos de códigos de 2 bytes se visualizan como un carácter. Por lo tanto, si la serie contiene caracteres internacionales de 2 bytes, los resultados de dlen diferirán de los resultados de len.

Macro Descripción
substr (Serie, Posición, Longitud) Devuelve una subserie de Serie que empieza en el número de carácter Posición y tiene una longitud de Longitud caracteres.

Utilizando entrada, substr (s, i, n) devuelve la subserie de s que empieza en la posición ith (origen cero) y tiene una longitud de n caracteres. Si se omite n , se devuelve el resto de la serie. Por ejemplo, la función:

substr(`now is the time',1)

devuelve la serie siguiente:

ow is the time
Macro Descripción
índice (String1, String2) Devuelve la posición del carácter en String1 donde comienza String2 (empezando por el carácter número 0), o -1 si String1 no contiene String2.

Al igual que con la macro substr incorporada, el origen de las series es 0.

Macro Descripción
translit (Serie, Set1, Set2) Busca en Serie los caracteres que se encuentran en Set1. Si encuentra alguno, cambia (translitera) esos caracteres a los caracteres correspondientes en Set2.

Tiene la forma general:

translit(s, f, t)

que modificassustituyendo cualquier carácter encontrado enfpor el carácter correspondiente det. Por ejemplo, la función:

translit(`little', aeiou, 12345)
sustituye las vocales por los dígitos correspondientes y devuelve lo siguiente:
l3ttl2

Sites más corto quef, caracteres que no tienen una entrada entse suprimen. Sitno está presente en absoluto, caracteres defse suprimen des. Así:

translit(`little', aeiou)
suprime vocales de serielittley devuelve lo siguiente:
lttl
Macro Descripción
dnl Suprime todos los caracteres que le siguen, hasta el carácter de nueva línea incluido.

Utilice esta macro para deshacerse de las líneas vacías. Por ejemplo, la función:

define(N, 100)
define(M, 200)
define(L, 300)

da como resultado una nueva línea al final de cada línea que no forma parte de la definición. Estos caracteres de nueva línea se pasan a la salida. Para deshacerse de las nuevas líneas, añada la macro dnl incorporada a cada una de las líneas.

define(N, 100) dnl
define(M, 200) dnl
define(L, 300) dnl

Depuración de macros M4

Las macros de esta sección le permiten notificar errores e información de proceso.

Macro Descripción
errprint (Serie) Escribe su argumento (String) en el archivo de errores estándar

Por ejemplo:

errprint (`error')
Macro Descripción
dumpdef (`MacroName'... ) Vuelca los nombres y definiciones actuales de los elementos nombrados como argumentos (`MacroName'...)

Si no proporciona argumentos, la macro dumpdef imprime todos los nombres y definiciones actuales. Recuerde que debe citar los nombres.

Macros m4 adicionales

A continuación se muestra una lista de macros m4 adicionales, con una breve explicación de cada una de ellas:

Macro Descripción
changecom (l, r ) Cambia los caracteres de comentario izquierdo y derecho a los caracteres representados por las variables l y r .
defn (MacroName) Devuelve la definición entre comillas de MacroName
en (Serie) Devuelve el número de caracteres en Serie.
m4exit (Código) Sale del procesador de macros m4 con un código de retorno de Código.
m4wrap (MacroName) Ejecuta la macro MacroName al final del procesador de macros m4 .
popdef (MacroName) Sustituye la definición actual de MacroName por la definición anterior guardada con la macro pushdef .
pushdef (MacroName, Replacement) Guarda la definición actual de MacroName y, a continuación, define MacroName para que sea Replacement.
sysval Obtiene el código de retorno del último uso de la macro syscmd .
traceoff (MacroList) Desactiva el rastreo para cualquier macro en MacroList. Si MacroList es nulo, desactiva todo el rastreo.
traceon (MacroName) Activa el rastreo para la macro MacroName. Si MacroName es nulo, activa el rastreo para todas las macros.