ftp.nice.ch/users/chris/Studium/psopt-0.01.tar.gz#/psopt-0.01/src/idents.c

This is idents.c in view mode; [Download] [Up]

/* -*-C-*-
 ******************************************************************************
 *
 * File:         idents.c
 * RCS:          $Header: /home/chris/Psopt/cvs/psopt/src/idents.c,v 1.3 1997/08/25 20:57:54 chris Exp $
 * Description:  
 * Author:       Christian Limpach <chris@nice.ch>
 * Created:      Mon Jun 16 14:14:54 1997
 * Modified:     Mon Aug 25 22:57:22 1997 (Christian Limpach) chris@nice.ch
 * Language:     C
 * Package:      N/A
 * Status:       Experimental (Do Not Distribute)
 *
 * (C) Copyright 1997, Christian Limpach, all rights reserved.
 *            
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *            
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *            
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, a copy can be obtained from this
 * program's author (send electronic mail to chris@nice.ch) or from
 * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
 * 02139, USA.
 *
 ******************************************************************************
 */

#include "psopt.h"
#include <stdio.h>
#include <string.h>

static Identifier *head, *tail;
static Identifier *reserved;

void
identifiers_init ()
{
  head = (Identifier *)malloc (sizeof (Identifier));
  tail = (Identifier *)malloc (sizeof (Identifier));
  head->refs = 2 << 30 - 1;
  tail->refs = -1;
  head->prev = NULL;
  head->next = tail;
  tail->prev = head;
  tail->next = NULL;

#include "resident.h"
}

Identifier *
count_identifier (name)
     char *name;
{
  Identifier *i = find_identifier (name);

  if (i == NULL)
    {
      i = (Identifier *)malloc (sizeof (Identifier));
      
      i->name = strdup (name);
      i->refs = 1;
      i->next = tail;
      i->prev = tail->prev;
      tail->prev = i;
      i->prev->next = i;
    }
  else
    {
      Identifier *prev = i->prev;
      i->refs++;
      if (i->refs > prev->refs)
        {
          prev->next = i->next;
          i->next->prev = prev;
          while (i->refs > prev->refs)
            prev = prev->prev;
          i->next = prev->next;
          prev->next = i;
          i->prev = prev;
          i->next->prev = i;
        }
    }

  return i;
}

Identifier *
find_identifier (name)
     char *name;
{
  Identifier *i = head->next;
  
  while (i != tail)
    {
      if (!strcmp (i->name, name))
        break;
      i = i->next;
    }
  if (i == tail)
    return (NULL);
  else
    return (i);
}

void
identifier_histogramm ()
{
  Identifier *i = head->next;
  
  while (i != tail)
    {
      fprintf (stderr, "%3d: %30s %s\n", i->refs, i->name, i->newname);
      i = i->next;
    }
}

static char *first_chars = "zabcdefghijklmnopqrstuvwxy"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"; /* +-_*&^@'\":`~="; */
static char *second_chars = "abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"; /* +-_*&^@'\":`~="; */

static int
next_char (p, chars)
     char *p;
     char *chars;
{
  char *i = p[0] == '\0' ? chars - 1 : strchr (chars, p[0]);
  if (i == NULL || i[1] == '\0')
    {
      p[0] = chars[0];
      return (0);
    }
  else
    {
      p[0] = i[1];
      return (1);
    }
}

void next_newname (newname)
     char *newname;
{
  do {
    char *p = newname;
    if (next_char (p, first_chars) == 0)
      {
        while (next_char (++p, second_chars) == 0)
          {
          }
      }
  } while (find_identifier (newname));
}

static char *load_def, *def;

void
fold_identifiers ()
{
  static char *newname = NULL;
  Identifier *i = head->next;
  char *p;

  if (newname == NULL)
    {
      newname = (char *)malloc (30);
      bzero (newname, 30);
      newname[0] = first_chars[0];
      newname[1] = second_chars[0];
    }
  
  load_def = strdup (newname);
  next_newname (newname);
  def = strdup (newname);
  next_newname (newname);

  while (i != tail)
    {
      if (find_reserved_identifier (i->name))
        {
          i->newname = i->name;
        }
      else if (5 + strlen (newname) + strlen (i->name) +
               i->refs * strlen (newname)
               < i->refs * strlen (i->name))
        {
          i->newname = strdup(newname);

          next_newname (newname);
        }
      else
        {
          i->newname = i->name;
        }
      
      i = i->next;
    }
}

void
output_folding ()
{
  Identifier *i = head->next;
  
  outstringf (1 + 2 + 18, "/%s{load def}bind def",
              load_def);
  outstringf (1 + 2 + 18, "/%s/def %s",
              def, load_def);

  while (i != tail)
    {
      if (strcmp (i->newname, i->name))
        {
          if (find_ps_op (i->name))
            {
              outstringf (3 + strlen (i->newname) + strlen (i->name) +
                          2,
                          "/%s/%s %s", i->newname, i->name,
                          load_def);
            }
          else if (strspn (i->name, "0123456789.-+") ==
                   strlen (i->name))
            {
              outstringf (3 + strlen (i->newname) + strlen (i->name) +
                          2,
                          "/%s %s %s", i->newname, i->name,
                          def);
            }
        }
      
      i = i->next;
    }
}

Identifier *
find_reserved_identifier (name)
     char *name;
{
  Identifier *i = reserved;

  while (i != NULL)
    {
      if (! strcmp (name, i->name))
        break;
      i = i->next;
    }
  return (i);
}

void
add_reserved_identifier (name)
     char *name;
{
  Identifier *i = (Identifier *)malloc (sizeof (Identifier));

  i->name = strdup (name);
  i->next = reserved;
  reserved = i;
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.