summaryrefslogtreecommitdiffstats
path: root/src/misc/util/utilNam.c
blob: 5fb38c51250a1b6befe312ef15021c16fa31dbff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
pre { line-height: 125%; margin: 0; }
td.linenos pre { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
span.linenos { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight { background: #ffffff; }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
<html><head>
	<title>YosysJS Example Application #01</title>
	<script type="text/javascript" src="yosysjs.js"></script>
</head><body onload="document.getElementById('command').focus()">
	<h1>YosysJS Example Application #01</h1>
	<table width="100%"><tr><td><div id="tabs"></div></td><td align="right"><tt>[ <span onclick="load_example()">load example</span> ]</tt></td></tr></table>
	<svg id="svg" style="display: none; position: absolute; padding: 10px; width: calc(100% - 40px); height: 480px;"></svg>
	<div><textarea id="output" style="width: 100%; height: 500px"></textarea></div>
	<div id="wait" style="display: block"><br/><b><span id="waitmsg">Loading...</span></b></div>
	<div id="input" style="display: none"><form onsubmit="window.setTimeout(run_command); return false"><br/><tt><span id="prompt">
			</span></tt><input id="command" type="text" onkeydown="history(event)" style="font-family: monospace; font-weight: bold;" 
/**CFile****************************************************************

  FileName    [utilNam.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Manager for character strings.]

  Synopsis    [Manager for character strings.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - June 20, 2005.]

  Revision    [$Id: utilNam.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]

***********************************************************************/


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>

#include "abc_global.h"
#include "misc/vec/vec.h"
#include "utilNam.h"

ABC_NAMESPACE_IMPL_START


////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

// this package maps non-empty character strings into natural numbers and back

// name manager
struct Abc_Nam_t_
{
    // info storage for names
    int              nStore;       // the size of allocated storage
    int              iHandle;      // the current free handle
    char *           pStore;       // storage for name objects
    // internal number mappings
    Vec_Int_t *      vInt2Handle;  // mapping integers into handles
    Vec_Int_t *      vInt2Next;    // mapping integers into nexts
    // hash table for names
    int *            pBins;        // the hash table bins 
    int              nBins;        // the number of bins 
    // manager recycling
    int              nRefs;        // reference counter for the manager
};

static inline char * Abc_NamHandleToStr( Abc_Nam_t * p, int h )        { return (char *)(p->pStore + h);                         }
static inline int    Abc_NamIntToHandle( Abc_Nam_t * p, int i )        { return Vec_IntEntry(p->vInt2Handle, i);                 }
static inline char * Abc_NamIntToStr( Abc_Nam_t * p, int i )           { return Abc_NamHandleToStr(p, Abc_NamIntToHandle(p,i));  }
static inline int    Abc_NamIntToNext( Abc_Nam_t * p, int i )          { return Vec_IntEntry(p->vInt2Next, i);                   }
static inline int *  Abc_NamIntToNextP( Abc_Nam_t * p, int i )         { return Vec_IntEntryP(p->vInt2Next, i);                  }

////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

/**Function*************************************************************

  Synopsis    [Creates manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Nam_t * Abc_NamStart( int nObjs, int nAveSize )
{
    Abc_Nam_t * p;
    if ( nObjs == 0 )
        nObjs = 16;
    p = ABC_CALLOC( Abc_Nam_t, 1 );
    p->nStore      = ((nObjs * (nAveSize + 1) + 16) / 4) * 4;
    p->pStore      = ABC_ALLOC( char, p->nStore );
    p->nBins       = Abc_PrimeCudd( nObjs );
    p->pBins       = ABC_CALLOC( int, p->nBins );
    // 0th object is unused
    p->vInt2Handle = Vec_IntAlloc( nObjs );  Vec_IntPush( p->vInt2Handle, -1 );
    p->vInt2Next   = Vec_IntAlloc( nObjs );  Vec_IntPush( p->vInt2Next,   -1 );
    p->iHandle     = 4;
    memset( p->pStore, 0, 4 );
//Abc_Print( 1, "Starting nam with %d bins.\n", p->nBins );
    // start reference counting
    p->nRefs       = 1;
    return p;
}

/**Function*************************************************************

  Synopsis    [Deletes manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_NamStop( Abc_Nam_t * p )
{
//Abc_Print( 1, "Starting nam with %d bins.\n", p->nBins );
    Vec_IntFree( p->vInt2Handle );
    Vec_IntFree( p->vInt2Next );
    ABC_FREE( p->pStore );
    ABC_FREE( p->pBins );
    ABC_FREE( p );
}

/**Function*************************************************************

  Synopsis    [Prints manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_NamPrint( Abc_Nam_t * p )
{
    int h, i;
    Vec_IntForEachEntryStart( p->vInt2Handle, h, i, 1 )
        Abc_Print( 1, "%d=\n%s\n", i, Abc_NamHandleToStr(p, h) );
//    Abc_Print( 1, "\n" );
}

/**Function*************************************************************

  Synopsis    [References the manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Nam_t * Abc_NamRef( Abc_Nam_t * p )
{
    p->nRefs++;
    return p;
}

/**Function*************************************************************

  Synopsis    [Dereferences the manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_NamDeref( Abc_Nam_t * p )
{
    if ( p == NULL )
        return;
    if ( --p->nRefs == 0 )
        Abc_NamStop( p );
}

/**Function*************************************************************

  Synopsis    [Returns the number of used entries.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Abc_NamObjNumMax( Abc_Nam_t * p )
{
    return Vec_IntSize(p->vInt2Handle);
}

/**Function*************************************************************

  Synopsis    [Reports memory usage of the manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Abc_NamMemUsed( Abc_Nam_t * p )
{
    if ( p == NULL )
        return 0;
    return sizeof(Abc_Nam_t) + p->iHandle + sizeof(int) * p->nBins + 
        sizeof(int) * (p->vInt2Handle->nSize + p->vInt2Next->nSize);
}

/**Function*************************************************************

  Synopsis    [Reports memory usage of the manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Abc_NamMemAlloc( Abc_Nam_t * p )
{
    if ( p == NULL )
        return 0;
    return sizeof(Abc_Nam_t) + p->nStore + sizeof(int) * p->nBins + 
        sizeof(int) * (p->vInt2Handle->nCap + p->vInt2Next->nCap);
}

/**Function*************************************************************

  Synopsis    [Computes hash value of the C-string.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Abc_NamStrHash( const char * pStr, int nTableSize )
{
    static int s_FPrimes[128] = { 
        1009, 1049, 1093, 1151, 1201, 1249, 1297, 1361, 1427, 1459, 
        1499, 1559, 1607, 1657, 1709, 1759, 1823, 1877, 1933, 1997, 
        2039, 2089, 2141, 2213, 2269, 2311, 2371, 2411, 2467, 2543, 
        2609, 2663, 2699, 2741, 2797, 2851, 2909, 2969, 3037, 3089, 
        3169, 3221, 3299, 3331, 3389, 3461, 3517, 3557, 3613, 3671, 
        3719, 3779, 3847, 3907, 3943, 4013, 4073, 4129, 4201, 4243, 
        4289, 4363, 4441, 4493, 4549, 4621, 4663, 4729, 4793, 4871, 
        4933, 4973, 5021, 5087, 5153, 5227, 5281, 5351, 5417, 5471, 
        5519, 5573, 5651, 5693, 5749, 5821, 5861, 5923, 6011, 6073, 
        6131, 6199, 6257, 6301, 6353, 6397, 6481, 6563, 6619, 6689, 
        6737, 6803, 6863, 6917, 6977, 7027, 7109, 7187, 7237, 7309, 
        7393, 7477, 7523, 7561, 7607, 7681, 7727, 7817, 7877, 7933, 
        8011, 8039, 8059, 8081, 8093, 8111, 8123, 8147
    };
    unsigned i, uHash;
    for ( uHash = 0, i = 0; pStr[i]; i++ )
        if ( i & 1 ) 
            uHash *= pStr[i] * s_FPrimes[i & 0x7F];
        else
            uHash ^= pStr[i] * s_FPrimes[i & 0x7F];
    return uHash % nTableSize;
}

/**Function*************************************************************

  Synopsis    [Returns place where this string is, or should be.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
static inline int * Abc_NamStrHashFind( Abc_Nam_t * p, const char * pStr )
{
    char * pThis;
    int * pPlace = (int *)(p->pBins + Abc_NamStrHash( pStr, p->nBins ));
    assert( *pStr );
    for ( pThis = (*pPlace)? Abc_NamIntToStr(p, *pPlace) : NULL; 
          pThis;    pPlace = Abc_NamIntToNextP(p, *pPlace), 
          pThis = (*pPlace)? Abc_NamIntToStr(p, *pPlace) : NULL )
              if ( !strcmp( pStr, pThis ) )
                  break;
    return pPlace;
}

/**Function*************************************************************

  Synopsis    [Resizes the hash table.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_NamStrHashResize( Abc_Nam_t * p )
{
    Vec_Int_t * vInt2HandleOld;
    char * pThis;
    int * piPlace, * pBinsOld, iHandleOld, i;//, clk = Abc_Clock();
    assert( p->pBins != NULL );
//    Abc_Print( 1, "Resizing names manager hash table from %6d to %6d. ", p->nBins, Abc_PrimeCudd( 3 * p->nBins ) );
    // replace the table
    pBinsOld = p->pBins;
    p->nBins = Abc_PrimeCudd( 3 * p->nBins ); 
    p->pBins = ABC_CALLOC( int, p->nBins );
    // replace the handles array
    vInt2HandleOld = p->vInt2Handle;
    p->vInt2Handle = Vec_IntAlloc( 2 * Vec_IntSize(vInt2HandleOld) ); 
    Vec_IntPush( p->vInt2Handle, -1 );
    Vec_IntClear( p->vInt2Next );    Vec_IntPush( p->vInt2Next, -1 );
    // rehash the entries from the old table
    Vec_IntForEachEntryStart( vInt2HandleOld, iHandleOld, i, 1 )
    {
        pThis   = Abc_NamHandleToStr( p, iHandleOld );
        piPlace = Abc_NamStrHashFind( p, pThis );
        assert( *piPlace == 0 );
        *piPlace = Vec_IntSize( p->vInt2Handle );
        assert( Vec_IntSize( p->vInt2Handle ) == i );
        Vec_IntPush( p->vInt2Handle, iHandleOld );
        Vec_IntPush( p->vInt2Next,   0 );
    }
    Vec_IntFree( vInt2HandleOld );
    ABC_FREE( pBinsOld );
//    Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
}

/**Function*************************************************************

  Synopsis    [Returns the index of the string in the table.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Abc_NamStrFind( Abc_Nam_t * p, char * pStr )
{
    return *Abc_NamStrHashFind( p, pStr );
}

/**Function*************************************************************

  Synopsis    [Finds or adds the given name to storage.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Abc_NamStrFindOrAdd( Abc_Nam_t * p, char * pStr, int * pfFound )
{
    int i, iHandleNew;
    int *piPlace;
    if ( !(pStr[0] != '\\' || pStr[strlen(pStr)-1] == ' ') )
    {
        for ( i = strlen(pStr) - 1; i >= 0; i-- )
            if ( *pStr == ' ' )
                break;
        assert( i < (int)strlen(pStr) );
    }
    piPlace = Abc_NamStrHashFind( p, pStr );
    if ( *piPlace )
    {
        if ( pfFound )
            *pfFound = 1;
        return *piPlace;
    }
    if ( pfFound )
        *pfFound = 0;
    iHandleNew = p->iHandle + strlen(pStr) + 1;
    while ( p->nStore < iHandleNew )
    {
        p->nStore *= 3;
        p->nStore /= 2;
        p->pStore  = ABC_REALLOC( char, p->pStore, p->nStore );
    }
    assert( p->nStore >= iHandleNew );
    // create new handle
    *piPlace = Vec_IntSize( p->vInt2Handle );
    strcpy( Abc_NamHandleToStr( p, p->iHandle ), pStr );
    Vec_IntPush( p->vInt2Handle, p->iHandle );
    Vec_IntPush( p->vInt2Next, 0 );
    p->iHandle = iHandleNew;
    // extend the hash table
    if ( Vec_IntSize(p->vInt2Handle) > 2 * p->nBins )
        Abc_NamStrHashResize( p );
    return Vec_IntSize(p->vInt2Handle) - 1;
}

/**Function*************************************************************

  Synopsis    [Returns name from name ID.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
char * Abc_NamStr( Abc_Nam_t * p, int NameId )
{
    return NameId? Abc_NamIntToStr(p, NameId) : NULL;
}

/**Function*************************************************************

  Synopsis    [For each ID of the first manager, gives ID of the second one.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Vec_Int_t * Abc_NamComputeIdMap( Abc_Nam_t * p1, Abc_Nam_t * p2 )
{
    Vec_Int_t * vMap;
    char * pThis;
    int * piPlace, iHandle1, i;
    if ( p1 == p2 )
        return Vec_IntStartNatural( Abc_NamObjNumMax(p1) );
    vMap = Vec_IntStart( Abc_NamObjNumMax(p1) );
    Vec_IntForEachEntryStart( p1->vInt2Handle, iHandle1, i, 1 )
    {
        pThis = Abc_NamHandleToStr( p1, iHandle1 );
        piPlace = Abc_NamStrHashFind( p2, pThis );
        Vec_IntWriteEntry( vMap, i, *piPlace );
//        Abc_Print( 1, "%d->%d  ", i, *piPlace );
    }
    return vMap;
}

/**Function*************************************************************

  Synopsis    [Returns the number of common names in the array.]

  Description [The array contains name IDs in the first manager.
  The procedure returns the number of entries that correspond to names
  in the first manager that appear in the second manager.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Abc_NamReportCommon( Vec_Int_t * vNameIds1, Abc_Nam_t * p1, Abc_Nam_t * p2 )
{
    int i, Entry, Counter = 0;
    Vec_IntForEachEntry( vNameIds1, Entry, i )
    {
        assert( Entry > 0 && Entry < Abc_NamObjNumMax(p1) );
        Counter += (Abc_NamStrFind(p2, Abc_NamStr(p1, Entry)) > 0);
//        if ( Abc_NamStrFind(p2, Abc_NamStr(p1, Entry)) == 0 )
//            Abc_Print( 1, "unique name <%s>\n", Abc_NamStr(p1, Entry) );
    }
    return Counter;
}

/**Function*************************************************************

  Synopsis    [Returns the name that appears in p1 does not appear in p2.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
char * Abc_NamReportUnique( Vec_Int_t * vNameIds1, Abc_Nam_t * p1, Abc_Nam_t * p2 )
{
    int i, Entry;
    Vec_IntForEachEntry( vNameIds1, Entry, i )
    {
        assert( Entry > 0 && Entry < Abc_NamObjNumMax(p1) );
        if ( Abc_NamStrFind(p2, Abc_NamStr(p1, Entry)) == 0 )
            return Abc_NamStr(p1, Entry);
    }
    return NULL;
}

////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


ABC_NAMESPACE_IMPL_END