Back to index

tetex-bin  3.0
Classes | Typedefs | Functions | Variables
macro.c File Reference
#include "system.h"
#include "cmds.h"
#include "files.h"
#include "macro.h"
#include "makeinfo.h"
#include "insertion.h"

Go to the source code of this file.

Classes

struct  alias_struct
struct  enclose_struct
struct  enclosure_stack_struct

Typedefs

typedef struct alias_struct alias_type
typedef struct enclose_struct enclosure_type
typedef struct
enclosure_stack_struct 
enclosure_stack_type

Functions

int array_len (char **array)
void free_array (char **array)
MACRO_DEFfind_macro (char *name)
static void add_macro (char *name, char **arglist, char *body, char *source_file, int source_lineno, int flags)
char ** get_brace_args (int quote_single)
static char ** get_macro_args (MACRO_DEF *def)
static char * apply (char **named, char **actuals, char *body)
char * expand_macro (MACRO_DEF *def)
void execute_macro (MACRO_DEF *def)
static void define_macro (char *mactype, int recursive)
void cm_macro (void)
void cm_rmacro (void)
static MACRO_DEFdelete_macro (char *name)
void cm_unmacro (void)
ITEXTremember_itext (char *pointer, int offset)
void forget_itext (char *pointer)
void me_append_before_this_command (void)
void me_execute_string (char *execution_string)
void me_execute_string_keep_state (char *execution_string, char *append_string)
void append_to_expansion_output (int offset)
void maybe_write_itext (char *pointer, int offset)
void write_region_to_macro_output (char *string, int start, int end)
void cm_alias (void)
char * alias_expand (char *tok)
void cm_definfoenclose (void)
int enclosure_command (char *tok)
void enclosure_expand (int arg, int start, int end)

Variables

FILEmacro_expansion_output_stream = NULL
char * macro_expansion_filename
int me_executing_string = 0
int only_macro_expansion = 0
static ITEXT ** itext_info = NULL
static int itext_size = 0
int braces_required_for_macro_args = 0
MACRO_DEF ** macro_list = NULL
int macro_list_len = 0
int macro_list_size = 0
static alias_typealiases
static enclosure_typeenclosures
static enclosure_stack_typeenclosure_stack

Class Documentation

struct alias_struct

Definition at line 982 of file macro.c.

Collaboration diagram for alias_struct:
Class Members
char * alias
char * mapto
struct alias_struct * next
struct enclose_struct

Definition at line 1033 of file macro.c.

Collaboration diagram for enclose_struct:
Class Members
char * after
char * before
char * enclose
struct enclose_struct * next
struct enclosure_stack_struct

Definition at line 1043 of file macro.c.

Collaboration diagram for enclosure_stack_struct:
Class Members
enclosure_type * current
struct enclosure_stack_struct * next

Typedef Documentation

typedef struct alias_struct alias_type

Function Documentation

static void add_macro ( char *  name,
char **  arglist,
char *  body,
char *  source_file,
int  source_lineno,
int  flags 
) [static]

Definition at line 103 of file macro.c.

{
  MACRO_DEF *def;

  def = find_macro (name);

  if (!def)
    {
      if (macro_list_len + 2 >= macro_list_size)
        macro_list = xrealloc
          (macro_list, ((macro_list_size += 10) * sizeof (MACRO_DEF *)));

      macro_list[macro_list_len] = xmalloc (sizeof (MACRO_DEF));
      macro_list[macro_list_len + 1] = NULL;

      def = macro_list[macro_list_len];
      macro_list_len += 1;
      def->name = name;
    }
  else
    {
      char *temp_filename = input_filename;
      int temp_line = line_number;

      warning (_("macro `%s' previously defined"), name);

      input_filename = def->source_file;
      line_number = def->source_lineno;
      warning (_("here is the previous definition of `%s'"), name);

      input_filename = temp_filename;
      line_number = temp_line;

      if (def->arglist)
        {
          int i;

          for (i = 0; def->arglist[i]; i++)
            free (def->arglist[i]);

          free (def->arglist);
        }
      free (def->source_file);
      free (def->body);
    }

  def->source_file = xstrdup (source_file);
  def->source_lineno = source_lineno;
  def->body = body;
  def->arglist = arglist;
  def->inhibited = 0;
  def->flags = flags;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* alias_expand ( char *  tok)

Definition at line 1012 of file macro.c.

{
  alias_type *findit = aliases;

  while (findit)
    if (strcmp (findit->alias, tok) == 0)
      {
       free (tok);
       return alias_expand (xstrdup (findit->mapto));
      }
    else
      findit = findit->next;

  return tok;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 930 of file macro.c.

{
  int i;
  ITEXT *itext = NULL;

  for (i = 0; i < itext_size; i++)
    if (itext_info[i] && itext_info[i]->pointer == input_text)
      {
        itext = itext_info[i];
        break;
      }

  if (!itext)
    return;

  if (offset > itext->offset)
    {
      write_region_to_macro_output (input_text, itext->offset, offset);
      remember_itext (input_text, offset);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* apply ( char **  named,
char **  actuals,
char *  body 
) [static]

Definition at line 294 of file macro.c.

{
  int i;
  int new_body_index, new_body_size;
  char *new_body, *text;
  int length_of_actuals;

  length_of_actuals = array_len (actuals);
  new_body_size = strlen (body);
  new_body = xmalloc (1 + new_body_size);

  /* Copy chars from BODY into NEW_BODY. */
  i = 0;
  new_body_index = 0;

  while (body[i])
    { /* Anything but a \ is easy.  */
      if (body[i] != '\\')
        new_body[new_body_index++] = body[i++];
      else
        { /* Snarf parameter name, check against named parameters. */
          char *param;
          int param_start, len;

          param_start = ++i;
          while (body[i] && body[i] != '\\')
            i++;

          len = i - param_start;
          param = xmalloc (1 + len);
          memcpy (param, body + param_start, len);
          param[len] = 0;

          if (body[i]) /* move past \ */
            i++;

          if (len == 0)
            { /* \\ always means \, even if macro has no args.  */
              len++;
              text = xmalloc (1 + len);
              sprintf (text, "\\%s", param);
            }
          else
            {
              int which;
              
              /* Check against named parameters. */
              for (which = 0; named && named[which]; which++)
                if (STREQ (named[which], param))
                  break;

              if (named && named[which])
                {
                  text = which < length_of_actuals ? actuals[which] : NULL;
                  if (!text)
                    text = "";
                  len = strlen (text);
                  text = xstrdup (text);  /* so we can free it */
                }
              else
                { /* not a parameter, so it's an error.  */
                  warning (_("\\ in macro expansion followed by `%s' instead of parameter name"),
                             param); 
                  len++;
                  text = xmalloc (1 + len);
                  sprintf (text, "\\%s", param);
                }
            }

          if (strlen (param) + 2 < len)
            {
              new_body_size += len + 1;
              new_body = xrealloc (new_body, new_body_size);
            }

          free (param);

          strcpy (new_body + new_body_index, text);
          new_body_index += len;

          free (text);
        }
    }

  new_body[new_body_index] = 0;
  return new_body;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int array_len ( char **  array)

Definition at line 58 of file macro.c.

{
  int i = 0;

  if (array)
    for (i = 0; array[i]; i++);

  return i;
}

Here is the caller graph for this function:

Definition at line 994 of file macro.c.

{
  alias_type *a = xmalloc (sizeof (alias_type));

  skip_whitespace ();
  get_until_in_line (0, "=", &(a->alias));
  canon_white (a->alias);

  discard_until ("=");
  skip_whitespace ();
  get_until_in_line (0, " ", &(a->mapto));

  a->next = aliases;
  aliases = a;
}

Here is the call graph for this function:

Definition at line 1053 of file macro.c.

{
  enclosure_type *e = xmalloc (sizeof (enclosure_type));

  skip_whitespace ();
  get_until_in_line (1, ",", &(e->enclose));
  discard_until (",");
  get_until_in_line (0, ",", &(e->before));
  discard_until (",");
  get_until_in_line (0, "\n", &(e->after));

  e->next = enclosures;
  enclosures = e;
}

Here is the call graph for this function:

Definition at line 703 of file macro.c.

{
  define_macro ("macro", 0);
}

Here is the call graph for this function:

Definition at line 709 of file macro.c.

{
  define_macro ("rmacro", 1);
}

Here is the call graph for this function:

Definition at line 738 of file macro.c.

{
  int i;
  char *line, *name;
  MACRO_DEF *def;

  if (macro_expansion_output_stream && !executing_string)
    me_append_before_this_command ();

  get_rest_of_line (0, &line);

  for (i = 0; line[i] && !whitespace (line[i]); i++);
  name = xmalloc (i + 1);
  memcpy (name, line, i);
  name[i] = 0;

  def = delete_macro (name);

  if (def)
    {
      free (def->source_file);
      free (def->name);
      free (def->body);

      if (def->arglist)
        {
          int i;

          for (i = 0; def->arglist[i]; i++)
            free (def->arglist[i]);

          free (def->arglist);
        }

      free (def);
    }

  free (line);
  free (name);

  if (macro_expansion_output_stream && !executing_string)
    remember_itext (input_text, input_text_offset);
}

Here is the call graph for this function:

static void define_macro ( char *  mactype,
int  recursive 
) [static]

Definition at line 455 of file macro.c.

{
  int i, start;
  char *name, *line;
  char *last_end = NULL;
  char *body = NULL;
  char **arglist = NULL;
  int body_size = 0, body_index = 0;
  int depth = 1;
  int flags = 0;
  int defining_line = line_number;

  if (macro_expansion_output_stream && !executing_string)
    me_append_before_this_command ();

  skip_whitespace ();

  /* Get the name of the macro.  This is the set of characters which are
     not whitespace and are not `{' immediately following the @macro. */
  start = input_text_offset;
  {
    int len;

    for (i = start; i < input_text_length && input_text[i] != '{'
                    && !cr_or_whitespace (input_text[i]);
         i++) ;

    len = i - start;
    name = xmalloc (1 + len);
    memcpy (name, input_text + start, len);
    name[len] = 0;
    input_text_offset = i;
  }

  skip_whitespace ();

  /* It is not required that the definition of a macro includes an arglist.
     If not, don't try to get the named parameters, just use a null list. */
  if (curchar () == '{')
    {
      int character;
      int arglist_index = 0, arglist_size = 0;
      int gathering_words = 1;
      char *word = NULL;

      /* Read the words inside of the braces which determine the arglist.
         These words will be replaced within the body of the macro at
         execution time. */

      input_text_offset++;
      skip_whitespace_and_newlines ();

      while (gathering_words)
        {
          int len;

          for (i = input_text_offset;
               (character = input_text[i]);
               i++)
            {
              switch (character)
                {
                case '\n':
                  line_number++;
                case ' ':
                case '\t':
                case ',':
                case '}':
                  /* Found the end of the current arglist word.  Save it. */
                  len = i - input_text_offset;
                  word = xmalloc (1 + len);
                  memcpy (word, input_text + input_text_offset, len);
                  word[len] = 0;
                  input_text_offset = i;

                  /* Advance to the comma or close-brace that signified
                     the end of the argument. */
                  while ((character = curchar ())
                         && character != ','
                         && character != '}')
                    {
                      input_text_offset++;
                      if (character == '\n')
                        line_number++;
                    }

                  /* Add the word to our list of words. */
                  if (arglist_index + 2 >= arglist_size)
                    {
                      arglist_size += 10;
                      arglist = xrealloc (arglist,
                                          arglist_size * sizeof (char *));
                    }

                  arglist[arglist_index++] = word;
                  arglist[arglist_index] = NULL;
                  break;
                }

              if (character == '}')
                {
                  input_text_offset++;
                  gathering_words = 0;
                  break;
                }

              if (character == ',')
                {
                  input_text_offset++;
                  skip_whitespace_and_newlines ();
                  i = input_text_offset - 1;
                }
            }
        }
      
      /* If we have exactly one argument, do @quote-arg implicitly.  Not
         only does this match TeX's behavior (which can't feasibly be
         changed), but it's a good idea.  */
      if (arglist_index == 1)
        flags |= ME_QUOTE_ARG;
    }

  /* Read the text carefully until we find an "@end macro" which
     matches this one.  The text in between is the body of the macro. */
  skip_whitespace_and_newlines ();

  while (depth)
    {
      if ((input_text_offset + 9) > input_text_length)
        {
          file_line_error (input_filename, defining_line,
                        _("%cend macro not found"), COMMAND_PREFIX);
          return;
        }

      get_rest_of_line (0, &line);

      /* Handle commands only meaningful within a macro. */
      if ((*line == COMMAND_PREFIX) && (depth == 1) &&
          (strncmp (line + 1, "allow-recursion", 15) == 0) &&
          (line[16] == 0 || whitespace (line[16])))
        {
          for (i = 16; whitespace (line[i]); i++);
          strcpy (line, line + i);
          flags |= ME_RECURSE;
          if (!*line)
            {
              free (line);
              continue;
            }
        }

      if ((*line == COMMAND_PREFIX) && (depth == 1) &&
          (strncmp (line + 1, "quote-arg", 9) == 0) &&
          (line[10] == 0 || whitespace (line[10])))
        {
          for (i = 10; whitespace (line[i]); i++);
          strcpy (line, line + i);

          if (arglist && arglist[0] && !arglist[1])
            {
              flags |= ME_QUOTE_ARG;
              if (!*line)
                {
                  free (line);
                  continue;
                }
            }
          else
           line_error (_("@quote-arg only useful for single-argument macros"));
        }

      if (*line == COMMAND_PREFIX
          && (strncmp (line + 1, "macro ", 6) == 0
              || strncmp (line + 1, "rmacro ", 7) == 0))
        depth++;

      /* Incorrect implementation of nesting -- just check that the last
         @end matches what we started with.  Since nested macros don't
         work in TeX anyway, this isn't worth the trouble to get right.  */
      if (*line == COMMAND_PREFIX && strncmp (line + 1, "end macro", 9) == 0)
        {
          depth--;
          last_end = "macro";
        }
      if (*line == COMMAND_PREFIX && strncmp (line + 1, "end rmacro", 10) == 0)
        {
          depth--;
          last_end = "rmacro";
        }

      if (depth)
        {
          if ((body_index + strlen (line) + 3) >= body_size)
            body = xrealloc (body, body_size += 3 + strlen (line));
          strcpy (body + body_index, line);
          body_index += strlen (line);
          body[body_index++] = '\n';
          body[body_index] = 0;
        }
      free (line);
    }

  /* Check that @end matched the macro command.  */
  if (!STREQ (last_end, mactype))
    warning (_("mismatched @end %s with @%s"), last_end, mactype);

  /* If it was an empty macro like
     @macro foo
     @end macro
     create an empty body.  (Otherwise, the macro is not expanded.)  */
  if (!body)
    {
      body = (char *)malloc(1);
      *body = 0;
    }

  /* We now have the name, the arglist, and the body.  However, BODY
     includes the final newline which preceded the `@end macro' text.
     Delete it. */
  if (body && strlen (body))
    body[strlen (body) - 1] = 0;

  if (recursive)
    flags |= ME_RECURSE;
    
  add_macro (name, arglist, body, input_filename, defining_line, flags);

  if (macro_expansion_output_stream && !executing_string)
    {
      /* Remember text for future expansions.  */
      remember_itext (input_text, input_text_offset);

      /* Bizarrely, output the @macro itself.  This is so texinfo.tex
         will have a chance to read it when texi2dvi calls makeinfo -E.
         The problem is that we don't really expand macros in all
         contexts; a @table's @item is one.  And a fix is not obvious to
         me, since it appears virtually identical to any other internal
         expansion.  Just setting a variable in cm_item caused other
         strange expansion problems.  */
      write_region_to_macro_output ("@", 0, 1);
      write_region_to_macro_output (mactype, 0, strlen (mactype));
      write_region_to_macro_output (" ", 0, 1);
      write_region_to_macro_output (input_text, start, input_text_offset);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static MACRO_DEF* delete_macro ( char *  name) [static]

Definition at line 719 of file macro.c.

{
  int i;
  MACRO_DEF *def;

  def = NULL;

  for (i = 0; macro_list && (def = macro_list[i]); i++)
    if (strcmp (def->name, name) == 0)
      {
        memmove (macro_list + i, macro_list + i + 1,
               ((macro_list_len + 1) - i) * sizeof (MACRO_DEF *));
        macro_list_len--;
        break;
      }
  return def;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int enclosure_command ( char *  tok)

Definition at line 1072 of file macro.c.

{
  enclosure_type *findit = enclosures;

  while (findit)
    if (strcmp (findit->enclose, tok) == 0)
      {
        enclosure_stack_type *new = xmalloc (sizeof (enclosure_stack_type));
        new->current = findit;
        new->next = enclosure_stack;
        enclosure_stack = new;

        return 1;
      }
    else
      findit = findit->next;

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void enclosure_expand ( int  arg,
int  start,
int  end 
)

Definition at line 1094 of file macro.c.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 415 of file macro.c.

{
  char *execution_string;
  int start_line = line_number, end_line;

  if (macro_expansion_output_stream && !executing_string && !me_inhibit_expansion)
    me_append_before_this_command ();

  execution_string = expand_macro (def);
  if (!execution_string)
    return;

  if (def->body)
    {
      /* Reset the line number to where the macro arguments began.
         This makes line numbers reported in error messages correct in
         case the macro arguments span several lines and the expanded
         arguments invoke other commands.  */
      end_line = line_number;
      line_number = start_line;

      if (macro_expansion_output_stream
          && !executing_string && !me_inhibit_expansion)
        {
          remember_itext (input_text, input_text_offset);
          me_execute_string (execution_string);
        }
      else
        execute_string ("%s", execution_string);

      free (execution_string);
      line_number = end_line;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* expand_macro ( MACRO_DEF def)

Definition at line 385 of file macro.c.

{
  char **arglist;
  int num_args;
  char *execution_string = NULL;
  int start_line = line_number;

  /* Find out how many arguments this macro definition takes. */
  num_args = array_len (def->arglist);

  /* Gather the arguments present on the line if there are any. */
  arglist = get_macro_args (def);

  if (num_args < array_len (arglist))
    {
      free_array (arglist);
      line_error (_("Macro `%s' called on line %d with too many args"),
                  def->name, start_line);
      return execution_string;
    }

  if (def->body)
    execution_string = apply (def->arglist, arglist, def->body);

  free_array (arglist);
  return execution_string;
}

Here is the call graph for this function:

Here is the caller graph for this function:

MACRO_DEF* find_macro ( char *  name)

Definition at line 83 of file macro.c.

{
  int i;
  MACRO_DEF *def;

  def = NULL;
  for (i = 0; macro_list && (def = macro_list[i]); i++)
    {
      if ((!def->inhibited) && (strcmp (def->name, name) == 0))
        break;
    }
  return def;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void forget_itext ( char *  pointer)

Definition at line 840 of file macro.c.

{
  int i;

  for (i = 0; i < itext_size; i++)
    if (itext_info[i] && (itext_info[i]->pointer == pointer))
      {
        free (itext_info[i]);
        itext_info[i] = NULL;
        break;
      }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void free_array ( char **  array)

Definition at line 69 of file macro.c.

{
  if (array)
    {
      int i;
      for (i = 0; array[i]; i++)
        free (array[i]);

      free (array);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

char** get_brace_args ( int  quote_single)

Definition at line 160 of file macro.c.

{
  char **arglist, *word;
  int arglist_index, arglist_size;
  int character, escape_seen, start;
  int depth = 1;

  /* There is an arglist in braces here, so gather the args inside of it. */
  skip_whitespace_and_newlines ();
  input_text_offset++;
  arglist = NULL;
  arglist_index = arglist_size = 0;

 get_arg:
  skip_whitespace_and_newlines ();
  start = input_text_offset;
  escape_seen = 0;

  while ((character = curchar ()))
    {
      if (character == '\\')
        {
          input_text_offset += 2;
          escape_seen = 1;
        }
      else if (character == '{')
        {
          depth++;
          input_text_offset++;
        }
      else if ((character == ',' && !quote_single) ||
               ((character == '}') && depth == 1))
        {
          int len = input_text_offset - start;

          if (len || (character != '}'))
            {
              word = xmalloc (1 + len);
              memcpy (word, input_text + start, len);
              word[len] = 0;

              /* Clean up escaped characters. */
              if (escape_seen)
                {
                  int i;
                  for (i = 0; word[i]; i++)
                    if (word[i] == '\\')
                      memmove (word + i, word + i + 1,
                               1 + strlen (word + i + 1));
                }

              if (arglist_index + 2 >= arglist_size)
                arglist = xrealloc
                  (arglist, (arglist_size += 10) * sizeof (char *));

              arglist[arglist_index++] = word;
              arglist[arglist_index] = NULL;
            }

          input_text_offset++;
          if (character == '}')
            break;
          else
            goto get_arg;
        }
      else if (character == '}')
        {
          depth--;
          input_text_offset++;
        }
      else
        {
          input_text_offset++;
          if (character == '\n') line_number++;
        }
    }
  return arglist;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char** get_macro_args ( MACRO_DEF def) [static]

Definition at line 240 of file macro.c.

{
  int i;
  char *word;

  /* Quickly check to see if this macro has been invoked with any arguments.
     If not, then don't skip any of the following whitespace. */
  for (i = input_text_offset; i < input_text_length; i++)
    if (!cr_or_whitespace (input_text[i]))
      break;

  if (input_text[i] != '{')
    {
      if (braces_required_for_macro_args)
        {
          return NULL;
        }
      else
        {
          /* Braces are not required to fill out the macro arguments.  If
             this macro takes one argument, it is considered to be the
             remainder of the line, sans whitespace. */
          if (def->arglist && def->arglist[0] && !def->arglist[1])
            {
              char **arglist;

              get_rest_of_line (0, &word);
              if (input_text[input_text_offset - 1] == '\n')
                {
                  input_text_offset--;
                  line_number--;
                }
              /* canon_white (word); */
              arglist = xmalloc (2 * sizeof (char *));
              arglist[0] = word;
              arglist[1] = NULL;
              return arglist;
            }
          else
            {
              /* The macro either took no arguments, or took more than
                 one argument.  In that case, it must be invoked with
                 arguments surrounded by braces. */
              return NULL;
            }
        }
    }
  return get_brace_args (def->flags & ME_QUOTE_ARG);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maybe_write_itext ( char *  pointer,
int  offset 
)

Definition at line 954 of file macro.c.

{
  int i;
  ITEXT *itext = NULL;

  for (i = 0; i < itext_size; i++)
    if (itext_info[i] && (itext_info[i]->pointer == pointer))
      {
        itext = itext_info[i];
        break;
      }

  if (itext && (itext->offset < offset))
    {
      write_region_to_macro_output (itext->pointer, itext->offset, offset);
      remember_itext (pointer, offset);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 856 of file macro.c.

{
  int i;

  for (i = input_text_offset; i && (input_text[i] != COMMAND_PREFIX); i--)
    ;
  maybe_write_itext (input_text, i);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void me_execute_string ( char *  execution_string)

Definition at line 868 of file macro.c.

{
  int saved_escape_html = escape_html;
  int saved_in_paragraph = in_paragraph;
  escape_html = me_executing_string == 0;
  in_paragraph = 0;
  
  pushfile ();
  input_text_offset = 0;
  /* The following xstrdup is so we can relocate input_text at will.  */
  input_text = xstrdup (execution_string);
  input_filename = xstrdup (input_filename);
  input_text_length = strlen (execution_string);

  remember_itext (input_text, 0);

  me_executing_string++;
  reader_loop ();
  free (input_text);
  free (input_filename);
  popfile ();
  me_executing_string--;

  in_paragraph = saved_in_paragraph;
  escape_html = saved_escape_html;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void me_execute_string_keep_state ( char *  execution_string,
char *  append_string 
)

Definition at line 900 of file macro.c.

{
  int op_orig, opcol_orig, popen_orig;
  int fill_orig, newline_orig, indent_orig, meta_pos_orig;

  remember_itext (input_text, input_text_offset);
  op_orig = output_paragraph_offset;
  meta_pos_orig = meta_char_pos;
  opcol_orig = output_column;
  popen_orig = paragraph_is_open;
  fill_orig = filling_enabled;
  newline_orig = last_char_was_newline;
  filling_enabled = 0;
  indent_orig = no_indent;
  no_indent = 1;
  me_execute_string (execution_string);
  if (append_string)
    write_region_to_macro_output (append_string, 0, strlen (append_string));
  output_paragraph_offset = op_orig;
  meta_char_pos = meta_pos_orig;
  output_column = opcol_orig;
  paragraph_is_open = popen_orig;
  filling_enabled = fill_orig;
  last_char_was_newline = newline_orig;
  no_indent = indent_orig;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ITEXT* remember_itext ( char *  pointer,
int  offset 
)

Definition at line 786 of file macro.c.

{
  int i;
  ITEXT *itext = NULL;

  /* If we have no info, initialize a blank list. */
  if (!itext_info)
    {
      itext_info = xmalloc ((itext_size = 10) * sizeof (ITEXT *));
      for (i = 0; i < itext_size; i++)
        itext_info[i] = NULL;
    }

  /* If the pointer is already present in the list, then set the offset. */
  for (i = 0; i < itext_size; i++)
    if ((itext_info[i]) &&
        (itext_info[i]->pointer == pointer))
      {
        itext = itext_info[i];
        itext_info[i]->offset = offset;
        break;
      }

  if (i == itext_size)
    {
      /* Find a blank slot (or create a new one), and remember the
         pointer and offset. */
      for (i = 0; i < itext_size; i++)
        if (itext_info[i] == NULL)
          break;

      /* If not found, then add some slots. */
      if (i == itext_size)
        {
          int j;

          itext_info = xrealloc
            (itext_info, (itext_size += 10) * sizeof (ITEXT *));

          for (j = i; j < itext_size; j++)
            itext_info[j] = NULL;
        }

      /* Now add the pointer and the offset. */
      itext_info[i] = xmalloc (sizeof (ITEXT));
      itext_info[i]->pointer = pointer;
      itext_info[i]->offset = offset;
      itext = itext_info[i];
    }
  return itext;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void write_region_to_macro_output ( char *  string,
int  start,
int  end 
)

Definition at line 974 of file macro.c.

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

alias_type* aliases [static]

Definition at line 989 of file macro.c.

Definition at line 48 of file macro.c.

Definition at line 1049 of file macro.c.

Definition at line 1041 of file macro.c.

ITEXT** itext_info = NULL [static]

Definition at line 43 of file macro.c.

int itext_size = 0 [static]

Definition at line 44 of file macro.c.

Definition at line 34 of file macro.c.

Definition at line 31 of file macro.c.

Definition at line 51 of file macro.c.

Definition at line 53 of file macro.c.

Definition at line 54 of file macro.c.

Definition at line 37 of file macro.c.

Definition at line 41 of file macro.c.