URL
https://opencores.org/ocsvn/sc2v/sc2v/trunk
Subversion Repositories sc2v
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 13 to Rev 14
- ↔ Reverse comparison
Rev 13 → Rev 14
/trunk/ChangeLog
1,3 → 1,7
03-02-2005 Version 0.3 |
|
Lists implementation completely rewrite using sglib library |
|
26-01-2005 Version 0.2.5 |
|
Solved bug in nested switchs |
/trunk/src/list.c
File deleted
/trunk/src/list.h
File deleted
/trunk/src/sc2v_step1.h
0,0 → 1,54
/* ----------------------------------------------------------------------------- |
* |
* SystemC to Verilog Translator v0.3 |
* Provided by OpenSoc Design |
* |
* www.opensocdesign.com |
* |
* ----------------------------------------------------------------------------- |
* 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 Library General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program; if not, write to the Free Software |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
*/ |
|
#include "sglib.h" |
|
#define MAX_NAME_LENGTH 256 |
|
typedef struct _DefineNode |
{ |
char name[MAX_NAME_LENGTH]; |
struct _DefineNode *next; |
} DefineNode; |
|
typedef struct _RegNode |
{ |
char name[MAX_NAME_LENGTH]; |
char name2[MAX_NAME_LENGTH]; |
struct _RegNode *next; |
} RegNode; |
|
/* Global var to store Regs */ |
RegNode *regslist; |
/* Global var to store Defines */ |
DefineNode *defineslist; |
|
/* Functions for defines list*/ |
DefineNode *InsertDefine(DefineNode *list,char *name); |
int IsDefine(DefineNode *list,char *name); |
|
/* Functions for registers list*/ |
RegNode *InsertReg(RegNode *list, char *name, char *name2); |
char *IsReg (RegNode *list,char *name); |
|
|
/trunk/src/sc2v_step1.y
1,6 → 1,6
/* ----------------------------------------------------------------------------- |
* |
* SystemC to Verilog Translator v0.2 |
* SystemC to Verilog Translator v0.3 |
* Provided by OpenSoc Design |
* |
* www.opensocdesign.com |
26,14 → 26,8
#include <stdio.h> |
#include <string.h> |
|
#include "list.h" |
#include "sc2v_step1.h" |
|
/* Global var to store Regs */ |
RegsList *regslist; |
/* Global var to store Defines */ |
DefinesList *defineslist; |
|
|
int processfound = 0; |
int switchfound = 0; |
int switchparenthesis[256]; |
82,27 → 76,27
main () |
{ |
int i; |
|
defineslist=NULL; |
regslist=NULL; |
|
regslist = (RegsList *) malloc (sizeof (RegsList)); |
InitializeRegsList (regslist); |
defineslist = (DefinesList *) malloc (sizeof (DefinesList)); |
InitializeDefinesList (defineslist); |
fprintf(stderr,"\nSystemC to Verilog Translator v0.3"); |
fprintf(stderr,"\nProvided by OpenSoc http://www.opensocdesign.com\n\n"); |
fprintf(stderr,"Parsing implementation file.......\n\n"); |
|
processname = (char *) malloc (256 * sizeof (int)); |
processname2 = (char *) malloc (256 * sizeof (int)); |
fileregs = (char *) malloc (256 * sizeof (int)); |
processname = (char *) malloc (256 * sizeof (char)); |
processname2 = (char *) malloc (256 * sizeof (char)); |
fileregs = (char *) malloc (256 * sizeof (char)); |
|
file_defines = (char *) malloc (256 * sizeof (int)); |
file_defines = (char *) malloc (256 * sizeof (char)); |
strcpy (file_defines, (char *) "file_defines.sc2v"); |
FILE_DEFINES = fopen (file_defines, (char *) "w"); |
|
file_writes = (char *) malloc (256 * sizeof (int)); |
|
file_writes = (char *) malloc (256 * sizeof (char)); |
strcpy (file_writes, (char *) "file_writes.sc2v"); |
FILE_WRITES = fopen (file_writes, (char *) "w"); |
if (FILE_WRITES != NULL) |
printf ("\nopening file => filename = %s\n", file_writes); |
|
lastword = malloc (sizeof (char) * 256); |
lastword = (char *)malloc (sizeof (char) * 256); |
|
for (i = 0; i < 256; i++) |
switchparenthesis[i] = 0; |
110,10 → 104,12
translate = 1; |
verilog = 0; |
writemethod = 0; |
|
|
yyparse (); |
fclose (FILE_WRITES); |
fclose (FILE_DEFINES); |
|
fprintf(stderr,"\nDone\n\n"); |
} |
|
%} |
279,6 → 275,7
defineword: |
DEFINE WORD WORD |
{ |
|
defineparenthesis = 0; |
if (translate == 1 && verilog == 0) |
{ |
285,12 → 282,12
if (processfound) |
{ |
fprintf (file, "`define %s %s\n", (char *) $2, (char *) $3); |
InsertDefine (defineslist, (char *) $2); |
defineslist=InsertDefine(defineslist,(char *)$2); |
} |
else |
{ |
fprintf (FILE_DEFINES, "`define %s %s\n", (char *) $2, (char *) $3); |
InsertDefine (defineslist, (char *) $2); |
defineslist=InsertDefine(defineslist,(char *)$2); |
} |
} |
else if (verilog == 1) |
301,6 → 298,7
definenumber: |
DEFINE WORD NUMBER |
{ |
|
defineparenthesis = 0; |
if (translate == 1 && verilog == 0) |
{ |
307,12 → 305,12
if (processfound) |
{ |
fprintf (file, "`define %s %d\n", (char *) $2, (int) $3); |
InsertDefine (defineslist, (char *) $2); |
defineslist=InsertDefine(defineslist,(char *)$2); |
} |
else |
{ |
fprintf (FILE_DEFINES, "`define %s %d\n", (char *) $2, (int) $3); |
InsertDefine (defineslist, (char *) $2); |
defineslist=InsertDefine(defineslist,(char *)$2); |
} |
} |
else if (verilog == 1) |
324,11 → 322,14
definemacro: |
DEFINE WORD OPENPAR CLOSEPAR |
{ |
|
|
defineparenthesis = 0; |
//Macro found |
if (translate == 1 && verilog == 0) |
{ |
InsertDefine (defineslist, (char *) $2); |
defineslist=InsertDefine(defineslist,(char *)$2); |
|
definefound = 1; |
if (processfound) |
fprintf (file, "`define %s ", (char *) $2); |
491,6 → 492,7
word: |
WORD |
{ |
|
defineparenthesis = 0; |
if (translate == 1 && verilog == 0) |
{ |
512,17 → 514,17
if (reg_found) |
{ |
|
regname = malloc (sizeof (char) * (strlen ((char *) $1) + 1)); |
regname2 = |
malloc (sizeof (char) * |
(strlen ((char *) $1) + strlen (processname)) + 1); |
regname = (char *)malloc (sizeof (char) * (strlen ((char *) $1) + 1)); |
regname2 =(char *)malloc (sizeof (char) *(strlen ((char *) $1) + strlen (processname)) + 1); |
|
strcpy (regname, (char *) $1); |
strcpy (regname2, (char *) $1); |
strcat (regname2, processname); |
fprintf (regs_file, "%s", regname2); |
InsertReg (regslist, regname, regname2); |
free (regname); |
|
regslist=InsertReg(regslist,regname,regname2); |
|
free (regname); |
free (regname2); |
} |
else |
532,10 → 534,11
for (i = 0; i < openedkeys; i++) |
fprintf (file, " "); |
} |
regname2 = IsReg (regslist, (char *) $1); |
regname2 = IsReg (regslist,(char *) $1); |
if (regname2 == NULL) |
{ |
if (IsDefine (defineslist, (char *) $1)) |
|
if (IsDefine(defineslist,(char *)$1)) |
{ |
if (ifdeffound == 0) |
{ |
562,7 → 565,8
} |
else if (definefound) |
{ |
if (IsDefine (defineslist, (char *) $1)) |
|
if (IsDefine(defineslist,(char *)$1)) |
{ |
|
fprintf (FILE_DEFINES, "`%s", (char *) $1); |
811,14 → 815,11
{ |
if (openedkeys == 1) |
{ |
printf ("opening file => filename = %s\n", processname2); |
printf ("Found process %s\n", processname); |
file = fopen (processname2, (char *) "w"); |
printf ("opening file => filename = %s\n", fileregs); |
regs_file = fopen (fileregs, (char *) "w"); |
processfound = 1; |
regslist = (RegsList *) malloc (sizeof (RegsList)); |
InitializeRegsList (regslist); |
} |
} |
if (processfound) |
if (openedkeys != switchparenthesis[switchfound]) |
{ |
853,7 → 854,7
default_found = 0; |
} |
for (i = 0; i < openedkeys - 1; i++) |
fprintf (file, " "); |
fprintf (file, " "); |
fprintf (file, "endcase\n"); |
newline = 1; |
switchparenthesis[switchfound] = 0; |
864,7 → 865,7
{ |
fprintf (file, "\n"); |
for (i = 0; i < openedkeys; i++) |
fprintf (file, " "); |
fprintf (file, " "); |
fprintf (file, "end\n"); |
newline = 1; |
} |
883,7 → 884,6
{ |
fclose (file); |
fclose (regs_file); |
free (regslist); |
processfound = 0; |
} |
} |
/trunk/src/sc2v_step2.h
0,0 → 1,151
/* ----------------------------------------------------------------------------- |
* |
* SystemC to Verilog Translator v0.3 |
* Provided by OpenSoc Design |
* |
* www.opensocdesign.com |
* |
* ----------------------------------------------------------------------------- |
* 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 Library General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program; if not, write to the Free Software |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
*/ |
|
#include "sglib.h" |
|
#define MAX_NAME_LENGTH 256 |
|
typedef struct _write_node |
{ |
char name[MAX_NAME_LENGTH]; |
struct _write_node *next; |
} WriteNode; |
|
typedef struct _port_node |
{ |
char name[MAX_NAME_LENGTH]; |
char tipo[MAX_NAME_LENGTH]; |
int size; |
struct _port_node *next; |
} PortNode; |
|
typedef struct _signal_node |
{ |
char name[MAX_NAME_LENGTH]; |
int size; |
struct _signal_node *next; |
} SignalNode; |
|
typedef struct _bind_node |
{ |
char nameport[MAX_NAME_LENGTH]; |
char namebind[MAX_NAME_LENGTH]; |
struct _bind_node *next; |
} BindNode; |
|
typedef struct _instance_node |
{ |
char nameinstance[MAX_NAME_LENGTH]; |
char namemodulo[MAX_NAME_LENGTH]; |
BindNode *bindslist; |
struct _instance_node *next; |
} InstanceNode; |
|
typedef struct _sensibility_node |
{ |
char tipo[MAX_NAME_LENGTH]; |
char name[MAX_NAME_LENGTH]; |
struct _sensibility_node *next; |
} SensibilityNode; |
|
|
typedef struct _process_node |
{ |
char name[MAX_NAME_LENGTH]; |
char tipo[MAX_NAME_LENGTH]; //comb or seq |
SensibilityNode *list; |
struct _process_node *next; |
} ProcessNode; |
|
typedef struct _enumerates_node |
{ |
char name[MAX_NAME_LENGTH]; |
struct _enumerates_node *next; |
} EnumeratesNode; |
|
typedef struct _enumlist_node |
{ |
char name[MAX_NAME_LENGTH]; |
int istype; |
EnumeratesNode *list; |
struct _enumlist_node *next; |
} EnumListNode; |
|
|
/*Global var to read from file_writes.sc2v*/ |
WriteNode *writeslist; |
/*Global var to store ports*/ |
PortNode *portlist; |
/* Global var to store signals*/ |
SignalNode *signalslist; |
/* Global var to store sensitivity list*/ |
SensibilityNode *sensibilitylist; |
/* Global var to store process list*/ |
ProcessNode *processlist; |
/* Global var to store instantiated modules*/ |
InstanceNode *instanceslist; |
/*List of enumerates*/ |
EnumeratesNode *enumerateslist; |
EnumListNode *enumlistlist; |
|
/* Functions for DEFINES list*/ |
void ShowDefines (char *filedefines); |
|
/* Functions for WRITES list*/ |
WriteNode *InsertWrite (WriteNode *list,char *name); |
int IsWrite (WriteNode *list,char *name); |
WriteNode *ReadWritesFile (WriteNode *list,char *name); |
|
/* Functions for ports list*/ |
PortNode *InsertPort (PortNode *list,char *name, char *tipo, int size); |
void ShowPortList (PortNode *list); |
void EnumeratePorts (PortNode *list); |
|
/* Functions for signals list*/ |
SignalNode *InsertSignal (SignalNode *list,char *name, int size); |
void ShowSignalsList (SignalNode *list); |
int IsWire (char *name, InstanceNode * list); |
|
/* Functions for sensitivity list*/ |
SensibilityNode *InsertSensibility (SensibilityNode * list, char *name, char *tipo); |
void ShowSensibilityList (SensibilityNode * list); |
|
/* Functions for process list*/ |
ProcessNode *InsertProcess (ProcessNode * list, char *name,SensibilityNode *SensibilityList, char *tipo); |
void ShowProcessList (ProcessNode *list); |
void ShowProcessCode (ProcessNode *list); |
|
/* Functions for instances and binds list*/ |
InstanceNode *InsertInstance (InstanceNode *list, char *nameInstance,char *namemodulo); |
BindNode *InsertBind (BindNode *list, char *namePort, char *namebind); |
void ShowInstancedModules (InstanceNode * list); |
|
/* Functions for enumerates list*/ |
EnumeratesNode *InsertEnumerates (EnumeratesNode * list, char *name); |
int ShowEnumeratesList (EnumeratesNode * list); |
|
/*Functions of list of enumerates list*/ |
EnumListNode *InsertEnumList (EnumListNode * list, EnumeratesNode * enumlist,char *name, int istype); |
void ShowEnumListList (EnumListNode * list); |
int findEnumList (EnumListNode * list, char *name); |
int findEnumerateLength (EnumListNode * list, int offset); |
/trunk/src/sc2v_step2.y
1,6 → 1,6
/* ----------------------------------------------------------------------------- |
* |
* SystemC to Verilog Translator v0.2 |
* SystemC to Verilog Translator v0.3 |
* Provided by OpenSoc Design |
* |
* www.opensocdesign.com |
27,38 → 27,9
#include <string.h> |
#include <math.h> |
|
#include "list.h" |
#include "sc2v_step2.h" |
|
|
/*Global var to read from file_writes.sc2v*/ |
WritesList *writeslist; |
|
|
/*Global var to store ports*/ |
PortList *portlist; |
|
|
/* Global var to store signals*/ |
SignalsList *signalslist; |
|
|
/* Global var to store sensitivity list*/ |
SensibilityList *sensibilitylist; |
|
|
/* Global var to store instantiated modules*/ |
InstancesList *instanceslist; |
|
|
/* Global var to store process list*/ |
ProcessList *processlist; |
|
|
/*List of enumerates*/ |
EnumeratesList *enumerateslist; |
|
EnumListList *enumlistlist; |
|
char *enumname; |
|
int reading_enumerates = 0; |
66,59 → 37,46
|
/*Multiple Declarations*/ |
int multipledec; |
|
char *storedtype; |
|
|
/* Global var to store process module name*/ |
char *module_name; |
|
int module_name_found = 0; |
|
|
/* Global var to store last port type*/ |
char *lastportkind; |
|
int lastportsize; |
|
int activeport = 0; // 1 -> reading port list |
|
/* Global var to store last signal type*/ |
int lastsignalsize; |
|
int signalactive = 0; |
|
|
/* Global var to store last SC_METHOD found*/ |
char *active_method; |
|
char *active_method_type; |
|
int method_found; |
|
|
/* Global var to store last sensitivity found*/ |
char *last_sensibility; |
|
int sensibility_active = 0; |
|
|
|
int translate; |
|
|
void yyerror (const char *str) |
{ |
|
fprintf (stderr, "error: %s\n", str); |
|
} |
|
int yywrap () |
{ |
|
return 1; |
|
} |
|
|
126,90 → 84,51
{ |
|
/*Initialize lists */ |
writeslist = NULL; |
portlist = NULL;; |
signalslist = NULL; |
sensibilitylist=NULL; |
processlist=NULL; |
instanceslist = NULL; |
enumlistlist = NULL; |
|
writeslist = (WritesList *) malloc (sizeof (WritesList)); |
|
InitializeWritesList (writeslist); |
|
|
portlist = (PortList *) malloc (sizeof (PortList)); |
|
InitializePortList (portlist); |
|
|
signalslist = (SignalsList *) malloc (sizeof (SignalsList)); |
|
InitializeSignalsList (signalslist); |
|
|
sensibilitylist = (SensibilityList *) malloc (sizeof (SensibilityList)); |
|
InitializeSensibilityList (sensibilitylist); |
|
|
instanceslist = (InstancesList *) malloc (sizeof (InstancesList)); |
|
InitializeInstancesList (instanceslist); |
|
|
processlist = (ProcessList *) malloc (sizeof (ProcessList)); |
|
InitializeProcessList (processlist); |
|
|
enumlistlist = (EnumListList *) malloc (sizeof (EnumListList)); |
|
InitializeEnumListList (enumlistlist); |
|
|
translate = 1; |
|
|
fprintf(stderr,"\nSystemC to Verilog Translator v0.3\n\n"); |
fprintf(stderr,"Parsing header file.......\n\n"); |
|
yyparse (); |
|
|
printf ("module %s(", module_name); |
|
EnumeratePorts (portlist); |
|
printf (");\n"); |
|
|
ShowPortList (portlist); |
|
printf ("\n"); |
|
RegOutputs (portlist); |
|
printf ("\n"); |
|
|
ShowEnumListList (enumlistlist); |
|
writeslist=ReadWritesFile (writeslist,(char *) "file_writes.sc2v"); |
|
ReadWritesFile (writeslist, (char *) "file_writes.sc2v"); |
|
|
ShowSignalsList (signalslist, writeslist); |
|
ShowSignalsList (signalslist); |
printf ("\n"); |
|
|
ShowInstancedModules (instanceslist); |
|
printf ("\n"); |
|
|
ShowDefines ((char *) "file_defines.sc2v"); |
|
|
ShowProcessCode (processlist); |
|
printf ("\n"); |
|
|
printf ("endmodule\n"); |
|
fprintf(stderr,"\nDone\n"); |
} |
|
%} |
222,8 → 141,6
%% commands: /* empty */ |
|commands command; |
|
|
|
command: |
module |
| |
515,9 → 432,9
|
{ |
|
InsertProcess (processlist, active_method, sensibilitylist, |
processlist=InsertProcess (processlist, active_method, sensibilitylist, |
active_method_type); |
|
|
} |
|
active_method = (char *) $3; |
525,10 → 442,8
method_found = 1; |
|
/* New sensitivity list */ |
sensibilitylist = (SensibilityList *) malloc (sizeof (SensibilityList)); |
|
InitializeSensibilityList (sensibilitylist); |
|
sensibilitylist = NULL; |
|
} |
|
}; |
543,7 → 458,7
{ |
|
active_method_type = (char *) "seq"; //comb |
InsertSensibility (sensibilitylist, (char *) $3, "negedge"); |
sensibilitylist=InsertSensibility (sensibilitylist, (char *) $3, "negedge"); |
|
} |
|
559,7 → 474,7
{ |
|
active_method_type = (char *) "seq"; //comb |
InsertSensibility (sensibilitylist, (char *) $3, "posedge"); |
sensibilitylist=InsertSensibility (sensibilitylist, (char *) $3, "posedge"); |
|
} |
|
629,7 → 544,7
{ |
|
active_method_type = (char *) "comb"; //comb |
InsertSensibility (sensibilitylist, (char *) $3, " "); |
sensibilitylist=InsertSensibility (sensibilitylist, (char *) $3, " "); |
|
} |
|
645,7 → 560,7
if (translate == 1) |
{ |
|
InsertSensibility (sensibilitylist, (char *) $2, |
sensibilitylist=InsertSensibility (sensibilitylist, (char *) $2, |
(char *) last_sensibility); |
|
} |
661,7 → 576,7
if (translate == 1) |
{ |
|
InsertSensibility (sensibilitylist, (char *) $2, |
sensibilitylist=InsertSensibility (sensibilitylist, (char *) $2, |
(char *) last_sensibility); |
|
if (sensibility_active) |
676,8 → 591,6
|
}; |
|
|
|
closekey: |
CLOSEKEY |
{ |
691,7 → 604,7
|
method_found = 0; |
|
InsertProcess (processlist, active_method, sensibilitylist, |
processlist=InsertProcess (processlist, active_method, sensibilitylist, |
active_method_type); |
|
} |
713,7 → 626,7
|
{ |
|
InsertPort (portlist, (char *) $1, lastportkind, lastportsize); |
portlist=InsertPort (portlist,(char *) $1, lastportkind, lastportsize); |
|
activeport = 0; |
|
723,7 → 636,7
|
{ |
|
InsertSignal (signalslist, (char *) $1, lastsignalsize); |
signalslist=InsertSignal (signalslist,(char *) $1, lastsignalsize); |
|
signalactive = 0; |
|
747,9 → 660,9
length = findEnumerateLength (enumlistlist, list_pos); |
|
|
InsertSignal (signalslist, (char *) $1, length); |
signalslist=InsertSignal (signalslist,(char *) $1, length); |
|
InsertWrite (writeslist, (char *) $1); |
writeslist=InsertWrite (writeslist,(char *) $1); |
|
free (storedtype); |
|
784,7 → 697,7
|
{ |
|
InsertPort (portlist, (char *) $1, lastportkind, lastportsize); |
portlist=InsertPort (portlist,(char *) $1, lastportkind, lastportsize); |
|
} |
|
792,7 → 705,7
|
{ |
|
InsertSignal (signalslist, (char *) $1, lastsignalsize); |
signalslist=InsertSignal (signalslist,(char *) $1, lastsignalsize); |
|
} |
|
800,7 → 713,7
|
{ |
|
InsertEnumerates (enumerateslist, (char *) $1); |
enumerateslist=InsertEnumerates (enumerateslist, (char *) $1); |
|
|
} |
823,9 → 736,9
length = findEnumerateLength (enumlistlist, list_pos); |
|
|
InsertSignal (signalslist, (char *) $1, length); |
signalslist=InsertSignal (signalslist,(char *) $1, length); |
|
InsertWrite (writeslist, (char *) $1); |
writeslist=InsertWrite (writeslist,(char *) $1); |
|
multipledec = 1; |
|
859,9 → 772,9
|
{ |
|
InsertEnumerates (enumerateslist, (char *) $1); |
enumerateslist=InsertEnumerates (enumerateslist, (char *) $1); |
|
InsertEnumList (enumlistlist, enumerateslist, (char *) $4, 0); //Insert also the variable name |
enumlistlist=InsertEnumList (enumlistlist, enumerateslist, (char *) $4, 0); //Insert also the variable name |
reading_enumerates = 0; |
|
} |
884,9 → 797,9
|
{ |
|
InsertEnumerates (enumerateslist, (char *) $1); |
enumerateslist=InsertEnumerates (enumerateslist, (char *) $1); |
|
InsertEnumList (enumlistlist, enumerateslist, enumname, 1); //Insert also the variable name |
enumlistlist=InsertEnumList (enumlistlist, enumerateslist, enumname, 1); //Insert also the variable name |
reading_enumerates = 0; |
|
} |
905,7 → 818,7
if (translate == 1) |
{ |
|
InsertInstance (instanceslist, (char *) $1, (char *) $4); |
instanceslist=InsertInstance (instanceslist, (char *) $1, (char *) $4); |
|
} |
|
920,69 → 833,25
if (translate == 1) |
{ |
|
if (instanceslist->last == NULL) |
|
{ |
|
fprintf (stderr, "error: no instances found\n"); |
|
} |
|
else |
|
{ |
|
InstanceNode *aux; |
|
aux = instanceslist->first; |
|
while (1) |
|
{ |
|
if (strcmp (aux->nameinstance, (char *) $1) == 0) |
|
{ |
|
break; |
|
} |
|
else |
|
{ |
|
if (aux->next == NULL) |
|
{ |
|
fprintf (stderr, "error: instance %s not found\n", $1); |
|
exit (1); |
|
} |
|
else |
|
{ |
|
aux = aux->next; |
|
} |
|
} |
|
if (instanceslist == NULL){ |
fprintf (stderr, "error: no instances found\n"); |
}else{ |
|
InstanceNode *ill; |
SGLIB_LIST_MAP_ON_ELEMENTS (InstanceNode, instanceslist, ill, next, |
{ |
if (strcmp (ill->nameinstance, (char *) $1) == 0){ |
ill->bindslist=InsertBind (ill->bindslist, (char *) $3, (char *) $5); |
break; |
} |
} |
|
InsertBind (aux->bindslist, (char *) $3, (char *) $5); |
|
} |
); |
} |
|
} |
}; |
|
|
|
sc_ctor: |
SC_CTOR OPENPAR WORD CLOSEPAR OPENKEY |
{ |
1023,10 → 892,8
{ |
|
//New enumerate list |
enumerateslist = (EnumeratesList *) malloc (sizeof (EnumeratesList)); |
enumerateslist = NULL; |
|
InitializeEnumeratesList (enumerateslist); |
|
reading_enumerates = 1; |
|
} |
1043,12 → 910,10
{ |
|
//In this case we define type e.g. enum state_t {S0,S1,S2}; |
enumerateslist = (EnumeratesList *) malloc (sizeof (EnumeratesList)); |
enumerateslist = NULL; |
|
InitializeEnumeratesList (enumerateslist); |
enumname = (char *)malloc (sizeof (char) * strlen ((char *) $2)); |
|
enumname = malloc (sizeof (char) * strlen ((char *) $2)); |
|
strcpy (enumname, (char *) $2); |
|
reading_enumerates = 1; |
1082,9 → 947,9
length = findEnumerateLength (enumlistlist, list_pos); |
|
|
InsertSignal (signalslist, (char *) $2, length); |
signalslist=InsertSignal (signalslist,(char *) $2, length); |
|
InsertWrite (writeslist, (char *) $2); |
writeslist=InsertWrite (writeslist,(char *) $2); |
|
} |
else |
1125,9 → 990,9
length = findEnumerateLength (enumlistlist, list_pos); |
|
|
InsertSignal (signalslist, (char *) $5, length); |
signalslist=InsertSignal (signalslist,(char *) $5, length); |
|
InsertWrite (writeslist, (char *) $5); |
writeslist=InsertWrite (writeslist,(char *) $5); |
|
} |
else |
1167,13 → 1032,13
//Calculate the number of bits needed to represent the enumerate |
length = findEnumerateLength (enumlistlist, list_pos); |
|
storedtype = malloc (sizeof (char) * strlen ((char *) $1)); |
storedtype = (char *)malloc (sizeof (char) * strlen ((char *) $1)); |
|
strcpy (storedtype, (char *) $1); |
|
InsertSignal (signalslist, (char *) $2, length); |
signalslist=InsertSignal (signalslist,(char *) $2, length); |
|
InsertWrite (writeslist, (char *) $2); |
writeslist=InsertWrite (writeslist,(char *) $2); |
|
multipledec = 1; |
|
1199,11 → 1064,8
|
if (translate == 1) |
{ |
|
int length, list_pos; |
|
length = 0; |
|
list_pos = 0; |
|
//Look in the enumerated list if it was declared e.j state_t state; |
1210,18 → 1072,18
list_pos = findEnumList (enumlistlist, (char *) $3); |
|
if (list_pos > -1) |
{ |
{ |
|
//Calculate the number of bits needed to represent the enumerate |
length = findEnumerateLength (enumlistlist, list_pos); |
|
storedtype = malloc (sizeof (char) * strlen ((char *) $3)); |
storedtype = (char *)malloc (sizeof (char) * strlen ((char *) $3)); |
|
strcpy (storedtype, (char *) $3); |
|
InsertSignal (signalslist, (char *) $5, length); |
signalslist=InsertSignal (signalslist,(char *) $5, length); |
|
InsertWrite (writeslist, (char *) $5); |
writeslist=InsertWrite (writeslist,(char *) $5); |
|
multipledec = 1; |
|
/trunk/src/sc2v_step3.y
1,6 → 1,6
/* ----------------------------------------------------------------------------- |
* |
* SystemC to Verilog Translator v0.2 |
* SystemC to Verilog Translator v0.3 |
* Provided by OpenSoc Design |
* |
* www.opensocdesign.com |
/trunk/src/sc2v_step1.l
1,6 → 1,6
/* ----------------------------------------------------------------------------- |
* |
* SystemC to Verilog Translator v0.2 |
* SystemC to Verilog Translator v0.3 |
* Provided by OpenSoc Design |
* |
* www.opensocdesign.com |
/trunk/src/sc2v_step2.l
1,6 → 1,6
/* ----------------------------------------------------------------------------- |
* |
* SystemC to Verilog Translator v0.2 |
* SystemC to Verilog Translator v0.3 |
* Provided by OpenSoc Design |
* |
* www.opensocdesign.com |
/trunk/src/sc2v_step3.l
1,6 → 1,6
/* ----------------------------------------------------------------------------- |
* |
* SystemC to Verilog Translator v0.2 |
* SystemC to Verilog Translator v0.3 |
* Provided by OpenSoc Design |
* |
* www.opensocdesign.com |
/trunk/src/sglib.h
0,0 → 1,1946
/* |
|
This is SGLIB version 1.0.1 |
|
(C) by Marian Vittek, Bratislava, http://www.xref-tech.com/sglib, 2003,2004 |
|
License Conditions: You can use this software: |
- freely for non-commercial purposes, |
- or under the terms of the Open Source Software License, |
- or under the terms of the GNU Public License. |
If you wish to receive it under other (commercial) license conditions, |
contact the author. |
|
*/ |
|
|
#ifndef _SGLIB__h_ |
#define _SGLIB__h_ |
|
/* the assert is used exclusively to write unexpected error messages */ |
#include <assert.h> |
|
|
/* ---------------------------------------------------------------------------- */ |
/* ---------------------------------------------------------------------------- */ |
/* - LEVEL - 0 INTERFACE - */ |
/* ---------------------------------------------------------------------------- */ |
/* ---------------------------------------------------------------------------- */ |
|
|
/* ---------------------------------------------------------------------------- */ |
/* ------------------------------ STATIC ARRAYS ------------------------------- */ |
/* ---------------------------------------------------------------------------- */ |
|
/* |
|
Basic algorithms for sorting arrays. Multiple depending arrays can |
be rearranged using user defined 'elem_exchangers' |
|
*/ |
|
/* HEAP - SORT (level 0) */ |
|
#define SGLIB_ARRAY_SINGLE_HEAP_SORT(type, a, max, comparator) {\ |
SGLIB_ARRAY_HEAP_SORT(type, a, max, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\ |
} |
|
#define SGLIB_ARRAY_HEAP_SORT(type, a, max, comparator, elem_exchanger) {\ |
int _k_;\ |
for(_k_=(max)/2; _k_>=0; _k_--) {\ |
SGLIB___ARRAY_HEAP_DOWN(type, a, _k_, max, comparator, elem_exchanger);\ |
}\ |
for(_k_=(max)-1; _k_>=0; _k_--) {\ |
elem_exchanger(type, a, 0, _k_);\ |
SGLIB___ARRAY_HEAP_DOWN(type, a, 0, _k_, comparator, elem_exchanger);\ |
}\ |
} |
|
#define SGLIB___ARRAY_HEAP_DOWN(type, a, ind, max, comparator, elem_exchanger) {\ |
type _t_;\ |
int _m_, _l_, _r_, _i_;\ |
_i_ = (ind);\ |
_m_ = _i_;\ |
do {\ |
_i_ = _m_; \ |
_l_ = 2*_i_+1;\ |
_r_ = _l_+1;\ |
if (_l_ < (max)){\ |
if (comparator(((a)[_m_]), ((a)[_l_])) < 0) _m_ = _l_;\ |
if (_r_ < (max)) {\ |
if (comparator(((a)[_m_]), ((a)[_r_])) < 0) _m_ = _r_;\ |
}\ |
}\ |
if (_m_ != _i_) {\ |
elem_exchanger(type, a, _i_, _m_);\ |
}\ |
} while (_m_ != _i_);\ |
} |
|
|
/* QUICK - SORT (level 0) */ |
|
#define SGLIB_ARRAY_SINGLE_QUICK_SORT(type, a, max, comparator) {\ |
SGLIB_ARRAY_QUICK_SORT(type, a, max, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\ |
} |
|
#define SGLIB_ARRAY_QUICK_SORT(type, a, max, comparator, elem_exchanger) {\ |
int _i_, _j_, _p_, _stacki_, _start_, _end_;\ |
/* can sort up to 2^64 elements */\ |
int _startStack_[64]; \ |
int _endStack_[64];\ |
type _tmp_;\ |
_startStack_[0] = 0;\ |
_endStack_[0] = (max);\ |
_stacki_ = 1;\ |
while (_stacki_ > 0) {\ |
_stacki_ --;\ |
_start_ = _startStack_[_stacki_];\ |
_end_ = _endStack_[_stacki_];\ |
while (_end_ - _start_ > 2) {\ |
_p_ = _start_;\ |
_i_ = _start_ + 1;\ |
_j_ = _end_ - 1;\ |
while (_i_<_j_) {\ |
for(; _i_<=_j_ && comparator(((a)[_i_]),((a)[_p_]))<=0; _i_++) ;\ |
if (_i_ > _j_) {\ |
/* all remaining elements lesseq than pivot */\ |
elem_exchanger(type, a, _j_, _p_);\ |
_i_ = _j_;\ |
} else {\ |
for(; _i_<=_j_ && comparator(((a)[_j_]),((a)[_p_]))>=0; _j_--) ;\ |
if (_i_ > _j_) {\ |
/* all remaining elements greater than pivot */\ |
elem_exchanger(type, a, _j_, _p_);\ |
_i_ = _j_;\ |
} else if (_i_ < _j_) {\ |
elem_exchanger(type, a, _i_, _j_);\ |
if (_i_+2 < _j_) {_i_++; _j_--;}\ |
else if (_i_+1 < _j_) _i_++;\ |
}\ |
}\ |
}\ |
/* O.K. i==j and pivot is on a[i] == a[j] */\ |
/* handle recursive calls without recursion */\ |
if (_i_-_start_ > 1 && _end_-_j_ > 1) {\ |
/* two recursive calls, use array-stack */\ |
if (_i_-_start_ < _end_-_j_-1) {\ |
_startStack_[_stacki_] = _j_+1;\ |
_endStack_[_stacki_] = _end_;\ |
_stacki_ ++;\ |
_end_ = _i_;\ |
} else {\ |
_startStack_[_stacki_] = _start_;\ |
_endStack_[_stacki_] = _i_;\ |
_stacki_ ++;\ |
_start_ = _j_+1;\ |
}\ |
} else {\ |
if (_i_-_start_ > 1) {\ |
_end_ = _i_;\ |
} else {\ |
_start_ = _j_+1;\ |
}\ |
}\ |
}\ |
if (_end_ - _start_ == 2) {\ |
if (comparator(((a)[_start_]),((a)[_end_-1])) > 0) {\ |
elem_exchanger(type, a, _start_, _end_-1);\ |
}\ |
}\ |
}\ |
} |
|
/* BINARY SEARCH (level 0) */ |
|
#define SGLIB_ARRAY_BINARY_SEARCH(type, a, start_index, end_index, key, comparator, found, result_index) {\ |
int _kk_, _cc_, _ii_, _jj_, _ff_;\ |
_ii_ = (start_index); \ |
_jj_ = (end_index);\ |
_ff_ = 0;\ |
while (_ii_ <= _jj_ && _ff_==0) {\ |
_kk_ = (_jj_+_ii_)/2;\ |
_cc_ = comparator(((a)[_kk_]), (key));\ |
if (_cc_ == 0) {\ |
(result_index) = _kk_; \ |
_ff_ = 1;\ |
} else if (_cc_ < 0) {\ |
_ii_ = _kk_+1;\ |
} else {\ |
_jj_ = _kk_-1;\ |
}\ |
}\ |
if (_ff_ == 0) {\ |
/* not found, but set its resulting place in the array */\ |
(result_index) = _jj_+1;\ |
}\ |
(found) = _ff_;\ |
} |
|
/* -------------------------------- queue (in an array) ------------------ */ |
/* queue is a quadruple (a,i,j,dim) such that: */ |
/* a is the array storing values */ |
/* i is the index of the first used element in the array */ |
/* j is the index of the first free element in the array */ |
/* dim is the size of the array a */ |
/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */ |
|
#define SGLIB_QUEUE_INIT(type, a, i, j) { i = j = 0; } |
#define SGLIB_QUEUE_IS_EMPTY(type, a, i, j) ((i)==(j)) |
#define SGLIB_QUEUE_IS_FULL(type, a, i, j, dim) ((i)==((j)+1)%(dim)) |
#define SGLIB_QUEUE_FIRST_ELEMENT(type, a, i, j) (a[i]) |
#define SGLIB_QUEUE_ADD_NEXT(type, a, i, j, dim) {\ |
if (SGLIB_QUEUE_IS_FULL(type, a, i, j, dim)) assert(0 && "the queue is full");\ |
(j) = ((j)+1) % (dim);\ |
} |
#define SGLIB_QUEUE_ADD(type, a, elem, i, j, dim) {\ |
a[j] = (elem);\ |
SGLIB_QUEUE_ADD_NEXT(type, a, i, j, dim);\ |
} |
#define SGLIB_QUEUE_DELETE_FIRST(type, a, i, j, dim) {\ |
if (SGLIB_QUEUE_IS_EMPTY(type, a, i, j)) assert(0 && "the queue is empty");\ |
(i) = ((i)+1) % (dim);\ |
} |
#define SGLIB_QUEUE_DELETE(type, a, i, j, dim) {\ |
SGLIB_QUEUE_DELETE_FIRST(type, a, i, j, dim);\ |
} |
|
/* ----------------- priority queue (heap) (in an array) -------------------- */ |
/* heap is a triple (a,i,dim) such that: */ |
/* a is the array storing values */ |
/* i is the index of the first free element in the array */ |
/* dim is the size of the array a */ |
/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */ |
|
#define SGLIB_HEAP_INIT(type, a, i) { i = 0; } |
#define SGLIB_HEAP_IS_EMPTY(type, a, i) ((i)==0) |
#define SGLIB_HEAP_IS_FULL(type, a, i, dim) ((i)==(dim)) |
#define SGLIB_HEAP_FIRST_ELEMENT(type, a, i) (a[0]) |
#define SGLIB_HEAP_ADD_NEXT(type, a, i, dim, comparator, elem_exchanger) {\ |
int _i_;\ |
if (SGLIB_HEAP_IS_FULL(type, a, i, dim)) assert(0 && "the heap is full");\ |
_i_ = (i)++;\ |
while (_i_ > 0 && comparator(a[_i_/2], a[_i_]) < 0) {\ |
elem_exchanger(type, a, (_i_/2), _i_);\ |
_i_ = _i_/2;\ |
}\ |
} |
#define SGLIB_HEAP_ADD(type, a, elem, i, dim, comparator) {\ |
if (SGLIB_HEAP_IS_FULL(type, a, i, dim)) assert(0 && "the heap is full");\ |
a[i] = (elem);\ |
SGLIB_HEAP_ADD_NEXT(type, a, i, dim, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\ |
} |
#define SGLIB_HEAP_DELETE_FIRST(type, a, i, dim, comparator, elem_exchanger) {\ |
if (SGLIB_HEAP_IS_EMPTY(type, a, i)) assert(0 && "the heap is empty");\ |
(i)--;\ |
a[0] = a[i];\ |
SGLIB___ARRAY_HEAP_DOWN(type, a, 0, i, comparator, elem_exchanger);\ |
} |
#define SGLIB_HEAP_DELETE(type, a, i, dim, comparator) {\ |
SGLIB_HEAP_DELETE_FIRST(type, a, i, dim, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\ |
} |
|
|
/* ----------------- hashed table of pointers (in an array) -------------------- */ |
|
/* |
|
This hashed table is storing pointers to objects (not containers). |
In this table there is a one-to-one mapping between 'objects' stored |
in the table and indexes where they are placed. Each index is |
pointing to exactly one 'object' and each 'object' stored in the |
table occurs on exactly one index. Once an object is stored in the |
table, it can be represented via its index. |
|
In case of collision while adding an object the index shifted |
by SGLIB_HASH_TAB_SHIFT_CONSTANT (constant can be redefined) |
|
You can NOT delete an element from such hash table. The only |
justification (I can see) for this data structure is an exchange |
file format, having an index table at the beginning and then |
refering objects via indexes. |
|
!!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! |
|
*/ |
|
#define SGLIB_HASH_TAB_INIT(type, table, dim) {\ |
int _i_;\ |
for(_i_ = 0; _i_ < (dim); _i_++) (table)[_i_] = NULL;\ |
} |
|
#define SGLIB_HASH_TAB_ADD_IF_NOT_MEMBER(type, table, dim, elem, hash_function, comparator, member){\ |
unsigned _pos_;\ |
type *_elem_;\ |
SGLIB_HASH_TAB_FIND_MEMBER(type, table, dim, elem, _pos_, _elem_);\ |
(member) = (table)[_pos_];\ |
if (_elem_ == NULL) {\ |
if ((table)[_pos_] != NULL) assert(0 && "the hash table is full");\ |
(table)[_pos_] = (elem);\ |
}\ |
} |
|
#define SGLIB_HASH_TAB_FIND_MEMBER(type, table, dim, elem, hash_function, comparator, resultIndex, resultMember) {\ |
unsigned _i_;\ |
int _count_;\ |
type *_e_;\ |
_count = 0;\ |
_i_ = hash_function(elem);\ |
_i_ %= (dim);\ |
while ((_e_=(table)[_i_])!=NULL && comparator(_e_, (elem))!=0 && _count_<(dim)) {\ |
_count_ ++;\ |
_i_ = (_i_ + SGLIB_HASH_TAB_SHIFT_CONSTANT) % (dim);\ |
}\ |
(resultIndex) = _i_;\ |
if (_count_ < (dim)) (resultMember) = _e_;\ |
else (resultMember) = NULL;\ |
} |
|
#define SGLIB_HASH_TAB_IS_MEMBER(type, table, dim, elem, hash_function, resultIndex) {\ |
unsigned _i_;\ |
int _c_;\ |
type *_e_;\ |
_count = 0;\ |
_i_ = hash_function(elem);\ |
_i_ %= (dim);\ |
while ((_e_=(table)[_i_])!=NULL && _e_!=(elem) && _c_<(dim)) {\ |
_c_ ++;\ |
_i_ = (_i_ + SGLIB_HASH_TAB_SHIFT_CONSTANT) % (dim);\ |
}\ |
if (_e_==(elem)) (resultIndex) = _i_;\ |
else (resultIndex) = -1;\ |
} |
|
#define SGLIB_HASH_TAB_MAP_ON_ELEMENTS(type, table, dim, iteratedIndex, iteratedVariable, command) {\ |
unsigned iteratedIndex;\ |
type *iteratedVariable;\ |
for(iteratedIndex=0; iteratedIndex < (dim); iteratedIndex++) {\ |
iteratedVariable = (table)[iteratedIndex];\ |
if (iteratedVariable != NULL) {command;}\ |
}\ |
} |
|
|
/* ---------------------------------------------------------------------------- */ |
/* ------------------------- DYNAMIC DATA STRUCTURES -------------------------- */ |
/* ---------------------------------------------------------------------------- */ |
|
/* ------------------------------------ lists (level 0) --------------------- */ |
|
#define SGLIB_LIST_ADD(type, list, elem, next) {\ |
(elem)->next = (list);\ |
(list) = (elem);\ |
} |
|
#define SGLIB_LIST_CONCAT(type, first, second, next) {\ |
if ((first)==NULL) {\ |
(first) = (second);\ |
} else {\ |
type *_p_;\ |
for(_p_ = (first); _p_->next!=NULL; _p_=_p_->next) ;\ |
_p_->next = (second);\ |
}\ |
} |
|
#define SGLIB_LIST_DELETE(type, list, elem, next) {\ |
type **_p_;\ |
for(_p_ = &(list); *_p_!=NULL && *_p_!=(elem); _p_= &(*_p_)->next) ;\ |
assert(*_p_!=NULL && "element is not member of the container, use DELETE_IF_MEMBER instead"!=NULL);\ |
*_p_ = (*_p_)->next;\ |
} |
|
#define SGLIB_LIST_ADD_IF_NOT_MEMBER(type, list, elem, comparator, next, member) {\ |
type *_p_;\ |
for(_p_ = (list); _p_!=NULL && comparator(_p_, (elem)) != 0; _p_= _p_->next) ;\ |
(member) = _p_;\ |
if (_p_ == NULL) {\ |
SGLIB_LIST_ADD(type, list, elem, next);\ |
}\ |
} |
|
#define SGLIB_LIST_DELETE_IF_MEMBER(type, list, elem, comparator, next, member) {\ |
type **_p_;\ |
for(_p_ = &(list); *_p_!=NULL && comparator((*_p_), (elem)) != 0; _p_= &(*_p_)->next) ;\ |
(member) = *_p_;\ |
if (*_p_ != NULL) {\ |
*_p_ = (*_p_)->next;\ |
}\ |
} |
|
#define SGLIB_LIST_IS_MEMBER(type, list, elem, next, result) {\ |
type *_p_;\ |
for(_p_ = (list); _p_!=NULL && _p_ != (elem); _p_= _p_->next) ;\ |
(result) = (_p_!=NULL);\ |
} |
|
#define SGLIB_LIST_FIND_MEMBER(type, list, elem, comparator, next, member) {\ |
type *_p_;\ |
for(_p_ = (list); _p_!=NULL && comparator(_p_, (elem)) != 0; _p_= _p_->next) ;\ |
(member) = _p_;\ |
} |
|
#define SGLIB_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, next, command) {\ |
type *_ne_;\ |
type *iteratedVariable;\ |
(iteratedVariable) = (list); \ |
while ((iteratedVariable)!=NULL) {\ |
_ne_ = (iteratedVariable)->next;\ |
{command;};\ |
(iteratedVariable) = _ne_;\ |
}\ |
} |
|
#define SGLIB_LIST_LEN(type, list, next, result) {\ |
type *_ce_;\ |
(result) = 0;\ |
SGLIB_LIST_MAP_ON_ELEMENTS(type, list, _ce_, next, (result)++);\ |
} |
|
#define SGLIB_LIST_REVERSE(type, list, next) {\ |
type *_list_,*_tmp_,*_res_;\ |
_list_ = (list);\ |
_res_ = NULL;\ |
while (_list_!=NULL) {\ |
_tmp_ = _list_->next; _list_->next = _res_;\ |
_res_ = _list_; _list_ = _tmp_;\ |
}\ |
(list) = _res_;\ |
} |
|
#define SGLIB_LIST_SORT(type, list, comparator, next) {\ |
/* a non-recursive merge sort on lists */\ |
type *_r_;\ |
type *_a_, *_b_, *_todo_, *_t_, **_restail_;\ |
int _i_, _n_, _contFlag_;\ |
_r_ = (list);\ |
_contFlag_ = 1;\ |
for(_n_ = 1; _contFlag_; _n_ = _n_+_n_) {\ |
_todo_ = _r_; _r_ = NULL; _restail_ = &_r_; _contFlag_ =0;\ |
while (_todo_!=NULL) {\ |
_a_ = _todo_;\ |
for(_i_ = 1, _t_ = _a_; _i_ < _n_ && _t_!=NULL; _i_++, _t_ = _t_->next) ;\ |
if (_t_ ==NULL) {\ |
*_restail_ = _a_;\ |
break;\ |
}\ |
_b_ = _t_->next; _t_->next=NULL;\ |
for(_i_ =1, _t_ = _b_; _i_<_n_ && _t_!=NULL; _i_++, _t_ = _t_->next) ;\ |
if (_t_ ==NULL) {\ |
_todo_ =NULL;\ |
} else {\ |
_todo_ = _t_->next; _t_->next=NULL;\ |
}\ |
/* merge */\ |
while (_a_!=NULL && _b_!=NULL) {\ |
if (comparator(_a_, _b_) < 0) {\ |
*_restail_ = _a_; _restail_ = &(_a_->next); _a_ = _a_->next;\ |
} else {\ |
*_restail_ = _b_; _restail_ = &(_b_->next); _b_ = _b_->next;\ |
}\ |
}\ |
if (_a_!=NULL) *_restail_ = _a_;\ |
else *_restail_ = _b_;\ |
while (*_restail_!=NULL) _restail_ = &((*_restail_)->next);\ |
_contFlag_ =1;\ |
}\ |
}\ |
(list) = _r_;\ |
} |
|
/* --------------------------------- sorted list (level 0) --------------------- */ |
/* |
All operations suppose that the list is sorted and they preserve |
this property. |
*/ |
|
|
#define SGLIB_SORTED_LIST_ADD(type, list, elem, comparator, next) {\ |
type **_e_;\ |
int _cmpres_;\ |
SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, _cmpres_, _e_);\ |
(elem)->next = *_e_;\ |
*_e_ = (elem);\ |
} |
|
#define SGLIB_SORTED_LIST_ADD_IF_NOT_MEMBER(type, list, elem, comparator, next, member) {\ |
type **_e_;\ |
int _cmp_res_;\ |
SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, _cmp_res_, _e_);\ |
if (_cmp_res_ != 0) {\ |
(elem)->next = *_e_;\ |
*_e_ = (elem);\ |
(member) = NULL;\ |
} else {\ |
(member) = *_e_;\ |
}\ |
} |
|
#define SGLIB_SORTED_LIST_DELETE(type, list, elem, next) {\ |
SGLIB_LIST_DELETE(type, list, elem, next);\ |
} |
|
#define SGLIB_SORTED_LIST_DELETE_IF_MEMBER(type, list, elem, comparator, next, member) {\ |
type **_e_;\ |
int _cmp_res_;\ |
SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, _cmp_res_, _e_);\ |
if (_cmp_res_ == 0) {\ |
(member) = *_e_;\ |
*_e_ = (*_e_)->next;\ |
} else {\ |
(member) = NULL;\ |
}\ |
} |
|
#define SGLIB_SORTED_LIST_FIND_MEMBER(type, list, elem, comparator, next, member) {\ |
type *_p_;\ |
int _cmpres_;\ |
for(_p_ = (list); _p_!=NULL && (_cmpres_=comparator(_p_, (elem))) < 0; _p_=_p_->next) ;\ |
if (_cmpres_ != 0) (member) = NULL;\ |
else (member) = _p_;\ |
} |
|
#define SGLIB_SORTED_LIST_IS_MEMBER(type, list, elem, comparator, next, result) {\ |
type *_p_;\ |
int _cmpres_;\ |
for(_p_ = (list); _p_!=NULL && (_cmpres_=comparator(_p_, (elem))) < 0; _p_=_p_->next) ;\ |
while (_p_ != NULL && _p_ != (elem) && (_cmpres_ = comparator(_p_, (elem))) == 0) _p_=_p_->next;\ |
(result) = (_p_ == (elem));\ |
} |
|
#define SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, comparator_result, member_ptr) {\ |
for((member_ptr) = &(list); \ |
*(member_ptr)!=NULL && ((comparator_result)=comparator((*member_ptr), (elem))) < 0; \ |
(member_ptr) = &(*(member_ptr))->next) ;\ |
if (*(member_ptr) == NULL) (comparator_result) = -1;\ |
} |
|
#define SGLIB_SORTED_LIST_LEN(type, list, next, result) {\ |
SGLIB_LIST_LEN(type, list, next, result);\ |
} |
|
#define SGLIB_SORTED_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, next, command) {\ |
SGLIB_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, next, command);\ |
} |
|
|
/* ------------------------------- double linked list (level 0) ------------------------- */ |
/* |
Lists with back pointer to previous element. Those lists implements deletion |
of an element in a constant time. |
*/ |
|
#define SGLIB___DL_LIST_CREATE_SINGLETON(type, list, elem, previous, next) {\ |
(list) = (elem);\ |
(list)->next = (list)->previous = NULL;\ |
} |
|
#define SGLIB_DL_LIST_ADD_AFTER(type, place, elem, previous, next) {\ |
if ((place) == NULL) {\ |
SGLIB___DL_LIST_CREATE_SINGLETON(type, place, elem, previous, next);\ |
} else {\ |
(elem)->next = (place)->next;\ |
(elem)->previous = (place);\ |
(place)->next = (elem);\ |
if ((elem)->next != NULL) (elem)->next->previous = (elem);\ |
}\ |
} |
|
#define SGLIB_DL_LIST_ADD_BEFORE(type, place, elem, previous, next) {\ |
if ((place) == NULL) {\ |
SGLIB___DL_LIST_CREATE_SINGLETON(type, place, elem, previous, next);\ |
} else {\ |
(elem)->next = (place);\ |
(elem)->previous = (place)->previous;\ |
(place)->previous = (elem);\ |
if ((elem)->previous != NULL) (elem)->previous->next = (elem);\ |
}\ |
} |
|
#define SGLIB_DL_LIST_ADD(type, list, elem, previous, next) {\ |
SGLIB_DL_LIST_ADD_BEFORE(type, list, elem, previous, next)\ |
} |
|
#define SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, the_add_operation) {\ |
type *_dlp_;\ |
for(_dlp_ = (list); _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->previous) ;\ |
if (_dlp_ == NULL && (list) != NULL) {\ |
for(_dlp_ = (list)->next; _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->next) ;\ |
}\ |
(member) = _dlp_;\ |
if (_dlp_ == NULL) {\ |
the_add_operation(type, list, elem, previous, next);\ |
}\ |
} |
|
#define SGLIB_DL_LIST_ADD_BEFORE_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member) {\ |
SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, SGLIB_DL_LIST_ADD_BEFORE);\ |
} |
|
#define SGLIB_DL_LIST_ADD_AFTER_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member) {\ |
SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, SGLIB_DL_LIST_ADD_AFTER);\ |
} |
|
#define SGLIB_DL_LIST_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member) {\ |
SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, SGLIB_DL_LIST_ADD);\ |
} |
|
#define SGLIB_DL_LIST_CONCAT(type, first, second, previous, next) {\ |
if ((first)==NULL) {\ |
(first) = (second);\ |
} else {\ |
type *_dlp_;\ |
for(_dlp_ = (first); _dlp_->next!=NULL; _dlp_=_dlp_->next) ;\ |
SGLIB_DL_LIST_ADD_AFTER(type, _dlp_, second, previous, next);\ |
}\ |
} |
|
#define SGLIB_DL_LIST_DELETE(type, list, elem, previous, next) {\ |
type *_l_;\ |
_l_ = (list);\ |
if (_l_ == (elem)) {\ |
if ((elem)->previous != NULL) _l_ = (elem)->previous;\ |
else _l_ = (elem)->next;\ |
}\ |
if ((elem)->next != NULL) (elem)->next->previous = (elem)->previous;\ |
if ((elem)->previous != NULL) (elem)->previous->next = (elem)->next;\ |
(list) = _l_;\ |
} |
|
#define SGLIB_DL_LIST_DELETE_IF_MEMBER(type, list, elem, comparator, previous, next, member) {\ |
type *_dlp_;\ |
for(_dlp_ = (list); _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->previous) ;\ |
if (_dlp_ == NULL && (list) != NULL) {\ |
for(_dlp_ = (list)->next; _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->next) ;\ |
}\ |
(member) = _dlp_;\ |
if (_dlp_ != NULL) {\ |
SGLIB_DL_LIST_DELETE(type, list, _dlp_, previous, next);\ |
}\ |
} |
|
#define SGLIB_DL_LIST_IS_MEMBER(type, list, elem, previous, next, result) {\ |
type *_dlp_;\ |
SGLIB_LIST_IS_MEMBER(type, list, elem, previous, result);\ |
if (result == 0 && (list) != NULL) {\ |
_dlp_ = (list)->next;\ |
SGLIB_LIST_IS_MEMBER(type, _dlp_, elem, next, result);\ |
}\ |
} |
|
#define SGLIB_DL_LIST_FIND_MEMBER(type, list, elem, comparator, previous, next, member) {\ |
type *_dlp_;\ |
SGLIB_LIST_FIND_MEMBER(type, list, elem, comparator, previous, member);\ |
if ((member) == NULL && (list) != NULL) {\ |
_dlp_ = (list)->next;\ |
SGLIB_LIST_FIND_MEMBER(type, _dlp_, elem, comparator, next, member);\ |
}\ |
} |
|
#define SGLIB_DL_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, previous, next, command) {\ |
type *_dl_;\ |
type *iteratedVariable;\ |
if ((list)!=NULL) {\ |
_dl_ = (list)->next;\ |
SGLIB_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, previous, command);\ |
SGLIB_LIST_MAP_ON_ELEMENTS(type, _dl_, iteratedVariable, next, command);\ |
}\ |
} |
|
#define SGLIB_DL_LIST_SORT(type, list, comparator, previous, next) {\ |
type *_dll_, *_dlp_, *_dlt_;\ |
_dll_ = (list);\ |
if (_dll_ != NULL) {\ |
for(; _dll_->previous!=NULL; _dll_=_dll_->previous) ;\ |
SGLIB_LIST_SORT(type, _dll_, comparator, next);\ |
SGLIB___DL_LIST_CREATE_FROM_LIST(type, _dll_, previous, next);\ |
(list) = _dll_;\ |
}\ |
} |
|
#define SGLIB_DL_LIST_GET_FIRST(type, list, previous, next, result) {\ |
type *_dll_;\ |
_dll_ = (list);\ |
if (_dll_ != NULL) {\ |
for(; _dll_->previous!=NULL; _dll_=_dll_->previous) ;\ |
}\ |
(result) = _dll_;\ |
} |
|
#define SGLIB_DL_LIST_GET_LAST(type, list, previous, next, result) {\ |
type *_dll_;\ |
_dll_ = (list);\ |
if (_dll_ != NULL) {\ |
for(; _dll_->next!=NULL; _dll_=_dll_->next) ;\ |
}\ |
(result) = _dll_;\ |
} |
|
#define SGLIB_DL_LIST_LEN(type, list, previous, next, result) {\ |
type *_dl_;\ |
int _r1_, _r2_;\ |
if ((list)==NULL) {\ |
(result) = 0;\ |
} else {\ |
SGLIB_LIST_LEN(type, list, previous, _r1_);\ |
_dl_ = (list)->next;\ |
SGLIB_LIST_LEN(type, _dl_, next, _r2_);\ |
(result) = _r1_ + _r2_;\ |
}\ |
} |
|
#define SGLIB_DL_LIST_REVERSE(type, list, previous, next) {\ |
type *_list_,*_nlist_,*_dlp_,*_dln_;\ |
_list_ = (list);\ |
if (_list_!=NULL) {\ |
_nlist_ = _list_->next;\ |
while (_list_!=NULL) {\ |
_dln_ = _list_->next; \ |
_dlp_ = _list_->previous; \ |
_list_->next = _dlp_;\ |
_list_->previous = _dln_;\ |
_list_ = _dlp_;\ |
}\ |
while (_nlist_!=NULL) {\ |
_dln_ = _nlist_->next; \ |
_dlp_ = _nlist_->previous; \ |
_nlist_->next = _dlp_;\ |
_nlist_->previous = _dln_;\ |
_nlist_ = _dln_;\ |
}\ |
}\ |
} |
|
#define SGLIB___DL_LIST_CREATE_FROM_LIST(type, list, previous, next) {\ |
type *_dlp_, *_dlt_;\ |
_dlp_ = NULL;\ |
for(_dlt_ = (list); _dlt_!=NULL; _dlt_ = _dlt_->next) {\ |
_dlt_->previous = _dlp_;\ |
_dlp_ = _dlt_;\ |
}\ |
} |
|
|
/* ------------------------------- binary tree traversal (level 0) -------------------- */ |
|
|
#define SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, iteratedVariable, order, left, right, command) {\ |
/* this is non-recursive implementation of tree traversal */\ |
/* it maintains the path to the current node in the array '_path_' */\ |
/* the _path_[0] contains the root of the tree; */\ |
/* the _path_[_pathi_] contains the _current_element_ */\ |
/* the macro does not use the _current_element_ after execution of command */\ |
/* command can destroy it, it can free the element for example */\ |
type *_path_[SGLIB_MAX_TREE_DEEP];\ |
type *_right_[SGLIB_MAX_TREE_DEEP];\ |
char _pass_[SGLIB_MAX_TREE_DEEP];\ |
type *_cn_;\ |
int _pathi_;\ |
type *iteratedVariable;\ |
_cn_ = (tree);\ |
_pathi_ = 0;\ |
while (_cn_!=NULL) {\ |
/* push down to leftmost innermost element */\ |
while(_cn_!=NULL) {\ |
_path_[_pathi_] = _cn_;\ |
_right_[_pathi_] = _cn_->right;\ |
_pass_[_pathi_] = 0;\ |
_cn_ = _cn_->left;\ |
if (order == 0) {\ |
iteratedVariable = _path_[_pathi_];\ |
{command;}\ |
}\ |
_pathi_ ++;\ |
if (_pathi_ >= SGLIB_MAX_TREE_DEEP) assert(0 && "the binary_tree is too deep");\ |
}\ |
do {\ |
_pathi_ --;\ |
if ((order==1 && _pass_[_pathi_] == 0)\ |
|| (order == 2 && (_pass_[_pathi_] == 1 || _right_[_pathi_]==NULL))) {\ |
iteratedVariable = _path_[_pathi_];\ |
{command;}\ |
}\ |
_pass_[_pathi_] ++;\ |
} while (_pathi_>0 && _right_[_pathi_]==NULL) ;\ |
_cn_ = _right_[_pathi_];\ |
_right_[_pathi_] = NULL;\ |
_pathi_ ++;\ |
}\ |
} |
|
#define SGLIB_BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, left, right, command) {\ |
SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, 1, left, right, command);\ |
} |
|
#define SGLIB_BIN_TREE_MAP_ON_ELEMENTS_PREORDER(type, tree, _current_element_, left, right, command) {\ |
SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, 0, left, right, command);\ |
} |
|
#define SGLIB_BIN_TREE_MAP_ON_ELEMENTS_POSTORDER(type, tree, _current_element_, left, right, command) {\ |
SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, 2, left, right, command);\ |
} |
|
#define SGLIB___BIN_TREE_FIND_MEMBER(type, tree, elem, left, right, comparator, res) {\ |
type *_s_;\ |
int _c_;\ |
_s_ = (tree);\ |
while (_s_!=NULL) {\ |
_c_ = comparator((elem), _s_);\ |
if (_c_ < 0) _s_ = _s_->left;\ |
else if (_c_ > 0) _s_ = _s_->right;\ |
else break;\ |
}\ |
(res) = _s_;\ |
} |
|
/* ---------------------------------------------------------------------------- */ |
/* ---------------------------------------------------------------------------- */ |
/* - LEVEL - 1 INTERFACE - */ |
/* ---------------------------------------------------------------------------- */ |
/* ---------------------------------------------------------------------------- */ |
|
|
|
/* ---------------------------------------------------------------------------- */ |
/* ------------------------------ STATIC ARRAYS ------------------------------- */ |
/* ---------------------------------------------------------------------------- */ |
|
/* ----------------------------- array sorting (level 1) ---------------------- */ |
|
#define SGLIB_DEFINE_ARRAY_SORTING_PROTOTYPES(type, comparator) \ |
extern void sglib_##type##_array_quick_sort(type *a, int max);\ |
extern void sglib_##type##_array_heap_sort(type *a, int max);\ |
|
|
#define SGLIB_DEFINE_ARRAY_SORTING_FUNCTIONS(type, comparator) \ |
void sglib_##type##_array_quick_sort(type *a, int max) {\ |
SGLIB_ARRAY_SINGLE_QUICK_SORT(type, a, max, comparator);\ |
}\ |
void sglib_##type##_array_heap_sort(type *a, int max) {\ |
SGLIB_ARRAY_SINGLE_HEAP_SORT(type, a, max, comparator);\ |
}\ |
|
|
/* ----------------------------- array queue (level 1) ------------------- */ |
/* sglib's queue is stored in a fixed sized array */ |
/* queue_type MUST be a structure containing fields: */ |
/* afield is the array storing elem_type */ |
/* ifield is the index of the first element in the queue */ |
/* jfield is the index of the first free element after the queue */ |
/* dim is the size of the array afield */ |
/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */ |
|
|
#define SGLIB_DEFINE_QUEUE_PROTOTYPES(queue_type, elem_type, afield, ifield, jfield, dim) \ |
extern void sglib_##queue_type##_init(queue_type *q); \ |
extern int sglib_##queue_type##_is_empty(queue_type *q); \ |
extern int sglib_##queue_type##_is_full(queue_type *q); \ |
extern elem_type sglib_##queue_type##_first_element(queue_type *q); \ |
extern elem_type *sglib_##queue_type##_first_element_ptr(queue_type *q); \ |
extern void sglib_##queue_type##_add_next(queue_type *q); \ |
extern void sglib_##queue_type##_add(queue_type *q, elem_type elem); \ |
extern void sglib_##queue_type##_delete_first(queue_type *q); \ |
extern void sglib_##queue_type##_delete(queue_type *q); |
|
|
#define SGLIB_DEFINE_QUEUE_FUNCTIONS(queue_type, elem_type, afield, ifield, jfield, dim) \ |
void sglib_##queue_type##_init(queue_type *q) {\ |
SGLIB_QUEUE_INIT(elem_type, q->afield, q->ifield, q->jfield);\ |
}\ |
int sglib_##queue_type##_is_empty(queue_type *q) {\ |
return(SGLIB_QUEUE_IS_EMPTY(elem_type, q->afield, q->ifield, q->jfield));\ |
}\ |
int sglib_##queue_type##_is_full(queue_type *q) {\ |
return(SGLIB_QUEUE_IS_FULL(elem_type, q->afield, q->ifield, q->jfield));\ |
}\ |
elem_type sglib_##queue_type##_first_element(queue_type *q) {\ |
return(SGLIB_QUEUE_FIRST_ELEMENT(elem_type, q->afield, q->ifield, q->jfield));\ |
}\ |
elem_type *sglib_##queue_type##_first_element_ptr(queue_type *q) {\ |
return(& SGLIB_QUEUE_FIRST_ELEMENT(elem_type, q->afield, q->ifield, q->jfield));\ |
}\ |
void sglib_##queue_type##_add_next(queue_type *q) {\ |
SGLIB_QUEUE_ADD_NEXT(elem_type, q->afield, q->ifield, q->jfield, dim);\ |
}\ |
void sglib_##queue_type##_add(queue_type *q, elem_type elem) {\ |
SGLIB_QUEUE_ADD(elem_type, q->afield, elem, q->ifield, q->jfield, dim);\ |
}\ |
void sglib_##queue_type##_delete_first(queue_type *q) {\ |
SGLIB_QUEUE_DELETE_FIRST(elem_type, q->afield, q->ifield, q->jfield, dim);\ |
}\ |
void sglib_##queue_type##_delete(queue_type *q) {\ |
SGLIB_QUEUE_DELETE_FIRST(elem_type, q->afield, q->ifield, q->jfield, dim);\ |
} |
|
|
/* ------------------------ array heap (level 1) ------------------------- */ |
/* sglib's heap is a priority queue implemented in a fixed sized array */ |
/* heap_type MUST be a structure containing fields: */ |
/* afield is the array of size dim storing elem_type */ |
/* ifield is the index of the first free element after the queue */ |
/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */ |
|
|
#define SGLIB_DEFINE_HEAP_PROTOTYPES(heap_type, elem_type, afield, ifield, dim, comparator, elem_exchanger) \ |
extern void sglib_##heap_type##_init(heap_type *q); \ |
extern int sglib_##heap_type##_is_empty(heap_type *q); \ |
extern int sglib_##heap_type##_is_full(heap_type *q); \ |
extern elem_type sglib_##heap_type##_first_element(heap_type *q); \ |
extern elem_type *sglib_##heap_type##_first_element_ptr(heap_type *q); \ |
extern void sglib_##heap_type##_add_next(heap_type *q); \ |
extern void sglib_##heap_type##_add(heap_type *q, elem_type elem); \ |
extern void sglib_##heap_type##_delete_first(heap_type *q); \ |
extern void sglib_##heap_type##_delete(heap_type *q) |
|
#define SGLIB_DEFINE_HEAP_FUNCTIONS(heap_type, elem_type, afield, ifield, dim, comparator, elem_exchanger) \ |
void sglib_##heap_type##_init(heap_type *q) {\ |
SGLIB_HEAP_INIT(elem_type, q->afield, q->ifield);\ |
}\ |
int sglib_##heap_type##_is_empty(heap_type *q) {\ |
return(SGLIB_HEAP_IS_EMPTY(elem_type, q->afield, q->ifield));\ |
}\ |
int sglib_##heap_type##_is_full(heap_type *q) {\ |
return(SGLIB_HEAP_IS_FULL(elem_type, q->afield, q->ifield));\ |
}\ |
elem_type sglib_##heap_type##_first_element(heap_type *q) {\ |
return(SGLIB_HEAP_FIRST_ELEMENT(elem_type, q->afield, q->ifield));\ |
}\ |
elem_type *sglib_##heap_type##_first_element_ptr(heap_type *q) {\ |
return(& SGLIB_HEAP_FIRST_ELEMENT(elem_type, q->afield, q->ifield));\ |
}\ |
void sglib_##heap_type##_add_next(heap_type *q) {\ |
SGLIB_HEAP_ADD_NEXT(elem_type, q->afield, q->ifield, dim, comparator, elem_exchanger);\ |
}\ |
void sglib_##heap_type##_add(heap_type *q, elem_type elem) {\ |
SGLIB_HEAP_ADD(elem_type, q->afield, elem, q->ifield, dim, comparator, elem_exchanger);\ |
}\ |
void sglib_##heap_type##_delete_first(heap_type *q) {\ |
SGLIB_HEAP_DELETE_FIRST(elem_type, q->afield, q->ifield, dim, comparator, elem_exchanger);\ |
}\ |
void sglib_##heap_type##_delete(heap_type *q) {\ |
SGLIB_HEAP_DELETE_FIRST(elem_type, q->afield, q->ifield, dim, comparator, elem_exchanger);\ |
} |
|
|
/* ------------------------ hashed table (level 1) ------------------------- */ |
/* |
|
sglib's hash table is an array storing directly pointers to objects (not containers). |
In this table there is a one-to-one mapping between 'objects' stored |
in the table and indexes where they are placed. Each index is |
pointing to exactly one 'object' and each 'object' stored in the |
table occurs on exactly one index. Once an object is stored in the |
table, it can be represented via its index. |
|
type - is the type of elements |
dim - is the size of the hash array |
hash_function - is a hashing function mapping type* to unsigned |
comparator - is a comparator on elements |
|
!!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! |
*/ |
|
#define SGLIB_DEFINE_HASHED_TABLE_PROTOTYPES(type, dim, hash_function, comparator) \ |
struct sglib_hashed_##type##_iterator {\ |
int currentIndex;\ |
int (*subcomparator)(type *, type *);\ |
type *equalto;\ |
};\ |
extern void sglib_hashed_##type##_init(type *table[dim]);\ |
extern int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member);\ |
extern int sglib_hashed_##type##_is_member(type *table[dim], type *elem);\ |
extern type * sglib_hashed_##type##_find_member(type *table[dim], type *elem);\ |
extern type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]); \ |
extern type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto); \ |
extern type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it); \ |
extern type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it); |
|
#define SGLIB_DEFINE_HASHED_TABLE_FUNCTIONS(type, dim, hash_function, comparator) \ |
struct sglib_hashed_##type##_iterator {\ |
int currentIndex;\ |
type **table;\ |
int (*subcomparator)(type *, type *);\ |
type *equalto;\ |
};\ |
void sglib_hashed_##type##_init(type *table[dim]) {\ |
SGLIB_HASH_TAB_INIT(type, table, dim);\ |
}\ |
int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member) {\ |
SGLIB_HASH_TAB_ADD_IF_NOT_MEMBER(type, table, dim, elem, hash_function, comparator, *member);\ |
}\ |
int sglib_hashed_##type##_is_member(type *table[dim], type *elem) {\ |
int ind;\ |
SGLIB_HASH_TAB_IS_MEMBER(type, table, dim, elem, hash_function, ind);\ |
return(ind != -1);\ |
}\ |
type * sglib_hashed_##type##_find_member(type *table[dim], type *elem) {\ |
type *mmb;\ |
int ind;\ |
SGLIB_HASH_TAB_FIND_MEMBER(type, table, dim, elem, hash_function, comparator, ind, mmb);\ |
return(mmb);\ |
}\ |
type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto) {\ |
int i;\ |
it->table = table;\ |
it->subcomparator = subcomparator;\ |
it->equalto = equalto;\ |
for(i=0; i<(dim) && table[i]==NULL; i++) ;\ |
it->currentIndex = i;\ |
if (i<(dim)) return(table[i]);\ |
return(NULL);\ |
}\ |
type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]) {\ |
sglib_hashed_##type##_it_init_on_equal(it, table, NULL, NULL);\ |
}\ |
type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it) {\ |
return(table[it->currentIndex]);\ |
}\ |
type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it) {\ |
i=it->currentIndex;\ |
if (i<(dim)) {\ |
for(i++; i<(dim) && table[i]==NULL; i++) ;\ |
}\ |
it->currentIndex = i;\ |
if (i<(dim)) return(table[i]);\ |
return(NULL);\ |
} |
|
|
/* ------------------- hashed container (only for level 1) -------------------- */ |
/* |
hashed container is a table of given fixed size containing another |
(dynamic) base container in each cell. Once an object should be |
inserted into the hashed container, a hash function is used to |
determine the cell where the object belongs and the object is |
inserted into the base container stored in this cell. Usually the |
base container is simply a list or a sorted list, but it can be a |
red-black tree as well. |
|
parameters: |
type - the type of the container stored in each cell. |
dim - the size of the hashed array |
hash_function - the hashing function hashing 'type *' to unsigned. |
|
*/ |
|
#define SGLIB_DEFINE_HASHED_CONTAINER_PROTOTYPES(type, dim, hash_function) \ |
struct sglib_hashed_##type##_iterator {\ |
struct sglib_##type##_iterator containerIt;\ |
type **table;\ |
int currentIndex;\ |
int (*subcomparator)(type *, type *);\ |
type *equalto;\ |
};\ |
extern void sglib_hashed_##type##_init(type *table[dim]);\ |
extern void sglib_hashed_##type##_add(type *table[dim], type *elem);\ |
extern int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member);\ |
extern void sglib_hashed_##type##_delete(type *table[dim], type *elem);\ |
extern int sglib_hashed_##type##_delete_if_member(type *table[dim], type *elem, type **memb);\ |
extern int sglib_hashed_##type##_is_member(type *table[dim], type *elem);\ |
extern type * sglib_hashed_##type##_find_member(type *table[dim], type *elem);\ |
extern type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]); \ |
extern type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto); \ |
extern type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it); \ |
extern type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it); |
|
#define SGLIB_DEFINE_HASHED_CONTAINER_FUNCTIONS(type, dim, hash_function) \ |
/*extern unsigned hash_function(type *elem);*/\ |
void sglib_hashed_##type##_init(type *table[dim]) {\ |
unsigned i;\ |
for(i=0; i<(dim); i++) table[i] = NULL;\ |
}\ |
void sglib_hashed_##type##_add(type *table[dim], type *elem) {\ |
unsigned i;\ |
i = ((unsigned)hash_function(elem)) % (dim);\ |
sglib_##type##_add(&(table)[i], elem);\ |
}\ |
int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member) {\ |
unsigned i;\ |
i = ((unsigned)hash_function(elem)) % (dim);\ |
return(sglib_##type##_add_if_not_member(&(table)[i], elem, member));\ |
}\ |
void sglib_hashed_##type##_delete(type *table[dim], type *elem) {\ |
unsigned i;\ |
i = ((unsigned)hash_function(elem)) % (dim);\ |
sglib_##type##_delete(&(table)[i], elem);\ |
}\ |
int sglib_hashed_##type##_delete_if_member(type *table[dim], type *elem, type **memb) {\ |
unsigned i;\ |
i = ((unsigned)hash_function(elem)) % (dim);\ |
return(sglib_##type##_delete_if_member(&(table)[i], elem, memb));\ |
}\ |
int sglib_hashed_##type##_is_member(type *table[dim], type *elem) {\ |
unsigned i;\ |
i = ((unsigned)hash_function(elem)) % (dim);\ |
return(sglib_##type##_is_member((table)[i], elem));\ |
}\ |
type * sglib_hashed_##type##_find_member(type *table[dim], type *elem) {\ |
unsigned i;\ |
i = ((unsigned)hash_function(elem)) % (dim);\ |
return(sglib_##type##_find_member((table)[i], elem));\ |
}\ |
type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto) {\ |
type *e;\ |
it->table = table;\ |
it->currentIndex = 0;\ |
it->subcomparator = subcomparator;\ |
it->equalto = equalto;\ |
e = sglib_##type##_it_init_on_equal(&it->containerIt, table[it->currentIndex], it->subcomparator, it->equalto);\ |
if (e==NULL) e = sglib_hashed_##type##_it_next(it);\ |
return(e);\ |
}\ |
type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]) {\ |
return(sglib_hashed_##type##_it_init_on_equal(it, table, NULL, NULL));\ |
}\ |
type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it) {\ |
return(sglib_##type##_it_current(&it->containerIt));\ |
}\ |
type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it) {\ |
type *e;\ |
e = sglib_##type##_it_next(&it->containerIt);\ |
while (e==NULL && (++(it->currentIndex))<(dim)) {\ |
e = sglib_##type##_it_init_on_equal(&it->containerIt, it->table[it->currentIndex], it->subcomparator, it->equalto);\ |
}\ |
return(e);\ |
} |
|
|
|
/* ---------------------------------------------------------------------------- */ |
/* ------------------------- DYNAMIC DATA STRUCTURES -------------------------- */ |
/* ---------------------------------------------------------------------------- */ |
|
|
|
/* ------------------------------------ list (level 1) -------------------------------- */ |
|
#define SGLIB_DEFINE_LIST_PROTOTYPES(type, comparator, next) \ |
struct sglib_##type##_iterator {\ |
type *currentelem;\ |
type *nextelem;\ |
int (*subcomparator)(type *, type *);\ |
type *equalto;\ |
};\ |
extern void sglib_##type##_add(type **list, type *elem);\ |
extern int sglib_##type##_add_if_not_member(type **list, type *elem, type **member);\ |
extern void sglib_##type##_concat(type **first, type *second);\ |
extern void sglib_##type##_delete(type **list, type *elem);\ |
extern int sglib_##type##_delete_if_member(type **list, type *elem, type **member);\ |
extern int sglib_##type##_is_member(type *list, type *elem);\ |
extern type *sglib_##type##_find_member(type *list, type *elem);\ |
extern void sglib_##type##_sort(type **list);\ |
extern int sglib_##type##_len(type *list);\ |
extern void sglib_##type##_reverse(type **list);\ |
extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list); \ |
extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto); \ |
extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \ |
extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it); |
|
|
#define SGLIB_DEFINE_LIST_FUNCTIONS(type, comparator, next) \ |
int sglib_##type##_is_member(type *list, type *elem) {\ |
int result;\ |
SGLIB_LIST_IS_MEMBER(type, list, elem, next, result);\ |
return(result);\ |
}\ |
type *sglib_##type##_find_member(type *list, type *elem) {\ |
type *result;\ |
SGLIB_LIST_FIND_MEMBER(type, list, elem, comparator, next, result);\ |
return(result);\ |
}\ |
int sglib_##type##_add_if_not_member(type **list, type *elem, type **member) {\ |
SGLIB_LIST_ADD_IF_NOT_MEMBER(type, *list, elem, comparator, next, *member);\ |
return(*member==NULL);\ |
}\ |
void sglib_##type##_add(type **list, type *elem) {\ |
SGLIB_LIST_ADD(type, *list, elem, next);\ |
}\ |
void sglib_##type##_concat(type **first, type *second) {\ |
SGLIB_LIST_CONCAT(type, *first, second, next);\ |
}\ |
void sglib_##type##_delete(type **list, type *elem) {\ |
SGLIB_LIST_DELETE(type, *list, elem, next);\ |
}\ |
int sglib_##type##_delete_if_member(type **list, type *elem, type **member) {\ |
SGLIB_LIST_DELETE_IF_MEMBER(type, *list, elem, comparator, next, *member);\ |
return(*member!=NULL);\ |
}\ |
void sglib_##type##_sort(type **list) { \ |
SGLIB_LIST_SORT(type, *list, comparator, next);\ |
}\ |
int sglib_##type##_len(type *list) {\ |
int res;\ |
SGLIB_LIST_LEN(type, list, next, res);\ |
return(res);\ |
}\ |
void sglib_##type##_reverse(type **list) {\ |
SGLIB_LIST_REVERSE(type, *list, next);\ |
}\ |
\ |
type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto) {\ |
it->subcomparator = subcomparator;\ |
it->equalto = equalto;\ |
it->nextelem = list;\ |
return(sglib_##type##_it_next(it));\ |
}\ |
type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list) {\ |
return(sglib_##type##_it_init_on_equal(it, list, NULL, NULL));\ |
}\ |
type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\ |
return(it->currentelem);\ |
}\ |
type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\ |
type *ce, *eq;\ |
int (*scp)(type *, type *);\ |
ce = it->nextelem;\ |
it->nextelem = NULL;\ |
if (it->subcomparator != NULL) {\ |
eq = it->equalto; \ |
scp = it->subcomparator;\ |
while (ce!=NULL && scp(ce, eq)!=0) ce = ce->next;\ |
}\ |
it->currentelem = ce;\ |
if (ce != NULL) it->nextelem = ce->next;\ |
return(ce);\ |
} |
|
/* ----------------------------- sorted list (level 1) ----------------------------------- */ |
|
|
#define SGLIB_DEFINE_SORTED_LIST_PROTOTYPES(type, comparator, next) \ |
struct sglib_##type##_iterator {\ |
type *currentelem;\ |
type *nextelem;\ |
int (*subcomparator)(type *, type *);\ |
type *equalto;\ |
};\ |
extern void sglib_##type##_add(type **list, type *elem);\ |
extern int sglib_##type##_add_if_not_member(type **list, type *elem, type **member);\ |
extern void sglib_##type##_delete(type **list, type *elem);\ |
extern int sglib_##type##_delete_if_member(type **list, type *elem, type **member);\ |
extern int sglib_##type##_is_member(type *list, type *elem);\ |
extern type *sglib_##type##_find_member(type *list, type *elem);\ |
extern int sglib_##type##_len(type *list);\ |
extern void sglib_##type##_sort(type **list);\ |
extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list); \ |
extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto); \ |
extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \ |
extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it); |
|
|
#define SGLIB_DEFINE_SORTED_LIST_FUNCTIONS(type, comparator, next) \ |
int sglib_##type##_is_member(type *list, type *elem) {\ |
int result;\ |
SGLIB_SORTED_LIST_IS_MEMBER(type, list, elem, comparator, next, result);\ |
return(result);\ |
}\ |
type *sglib_##type##_find_member(type *list, type *elem) {\ |
type *result;\ |
SGLIB_SORTED_LIST_FIND_MEMBER(type, list, elem, comparator, next, result);\ |
return(result);\ |
}\ |
int sglib_##type##_add_if_not_member(type **list, type *elem, type **member) {\ |
SGLIB_SORTED_LIST_ADD_IF_NOT_MEMBER(type, *list, elem, comparator, next, *member);\ |
return(*member==NULL);\ |
}\ |
void sglib_##type##_add(type **list, type *elem) {\ |
SGLIB_SORTED_LIST_ADD(type, *list, elem, comparator, next);\ |
}\ |
void sglib_##type##_delete(type **list, type *elem) {\ |
SGLIB_SORTED_LIST_DELETE(type, *list, elem, next);\ |
}\ |
int sglib_##type##_delete_if_member(type **list, type *elem, type **member) {\ |
SGLIB_SORTED_LIST_DELETE_IF_MEMBER(type, *list, elem, comparator, next, *member);\ |
return(*member!=NULL);\ |
}\ |
int sglib_##type##_len(type *list) {\ |
int res;\ |
SGLIB_SORTED_LIST_LEN(type, list, next, res);\ |
return(res);\ |
}\ |
void sglib_##type##_sort(type **list) { \ |
SGLIB_LIST_SORT(type, *list, comparator, next);\ |
}\ |
\ |
type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto) {\ |
it->subcomparator = subcomparator;\ |
it->equalto = equalto;\ |
it->nextelem = list;\ |
return(sglib_##type##_it_next(it));\ |
}\ |
type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list) {\ |
return(sglib_##type##_it_init_on_equal(it, list, NULL, NULL));\ |
}\ |
type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\ |
return(it->currentelem);\ |
}\ |
type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\ |
type *ce, *eq;\ |
int (*scp)(type *, type *);\ |
int c;\ |
ce = it->nextelem;\ |
it->nextelem = NULL;\ |
if (it->subcomparator != NULL) {\ |
eq = it->equalto; \ |
scp = it->subcomparator;\ |
while (ce!=NULL && (c=scp(ce, eq)) < 0) ce = ce->next;\ |
if (ce != NULL && c > 0) ce = NULL;\ |
}\ |
it->currentelem = ce;\ |
if (ce != NULL) it->nextelem = ce->next;\ |
return(ce);\ |
} |
|
|
/* ----------------------------- double linked list (level 1) ------------------------------ */ |
|
|
#define SGLIB_DEFINE_DL_LIST_PROTOTYPES(type, comparator, previous, next) \ |
struct sglib_##type##_iterator {\ |
type *currentelem;\ |
type *prevelem;\ |
type *nextelem;\ |
int (*subcomparator)(type *, type *);\ |
type *equalto;\ |
};\ |
extern void sglib_##type##_add(type **list, type *elem);\ |
extern void sglib_##type##_add_before(type **list, type *elem);\ |
extern void sglib_##type##_add_after(type **list, type *elem);\ |
extern int sglib_##type##_add_if_not_member(type **list, type *elem, type **member);\ |
extern int sglib_##type##_add_before_if_not_member(type **list, type *elem, type **member);\ |
extern int sglib_##type##_add_after_if_not_member(type **list, type *elem, type **member);\ |
extern void sglib_##type##_concat(type **first, type *second);\ |
extern void sglib_##type##_delete(type **list, type *elem);\ |
extern int sglib_##type##_delete_if_member(type **list, type *elem, type **member);\ |
extern int sglib_##type##_is_member(type *list, type *elem);\ |
extern type *sglib_##type##_find_member(type *list, type *elem);\ |
extern type *sglib_##type##_get_first(type *list);\ |
extern type *sglib_##type##_get_last(type *list);\ |
extern void sglib_##type##_sort(type **list);\ |
extern int sglib_##type##_len(type *list);\ |
extern void sglib_##type##_reverse(type **list);\ |
extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list); \ |
extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto); \ |
extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \ |
extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it); |
|
|
#define SGLIB_DEFINE_DL_LIST_FUNCTIONS(type, comparator, previous, next) \ |
void sglib_##type##_add(type **list, type *elem) {\ |
SGLIB_DL_LIST_ADD(type, *list, elem, previous, next);\ |
}\ |
void sglib_##type##_add_after(type **list, type *elem) {\ |
SGLIB_DL_LIST_ADD_AFTER(type, *list, elem, previous, next);\ |
}\ |
void sglib_##type##_add_before(type **list, type *elem) {\ |
SGLIB_DL_LIST_ADD_BEFORE(type, *list, elem, previous, next);\ |
}\ |
int sglib_##type##_add_if_not_member(type **list, type *elem, type **member) {\ |
SGLIB_DL_LIST_ADD_IF_NOT_MEMBER(type, *list, elem, comparator, previous, next, *member);\ |
return(*member==NULL);\ |
}\ |
int sglib_##type##_add_after_if_not_member(type **list, type *elem, type **member) {\ |
SGLIB_DL_LIST_ADD_AFTER_IF_NOT_MEMBER(type, *list, elem, comparator, previous, next, *member);\ |
return(*member==NULL);\ |
}\ |
int sglib_##type##_add_before_if_not_member(type **list, type *elem, type **member) {\ |
SGLIB_DL_LIST_ADD_BEFORE_IF_NOT_MEMBER(type, *list, elem, comparator, previous, next, *member);\ |
return(*member==NULL);\ |
}\ |
void sglib_##type##_concat(type **first, type *second) {\ |
SGLIB_DL_LIST_CONCAT(type, *first, second, previous, next);\ |
}\ |
void sglib_##type##_delete(type **list, type *elem) {\ |
SGLIB_DL_LIST_DELETE(type, *list, elem, previous, next);\ |
}\ |
int sglib_##type##_delete_if_member(type **list, type *elem, type **member) {\ |
SGLIB_DL_LIST_DELETE_IF_MEMBER(type, *list, elem, comparator, previous, next, *member);\ |
return(*member!=NULL);\ |
}\ |
int sglib_##type##_is_member(type *list, type *elem) {\ |
int result;\ |
SGLIB_DL_LIST_IS_MEMBER(type, list, elem, previous, next, result);\ |
return(result);\ |
}\ |
type *sglib_##type##_find_member(type *list, type *elem) {\ |
type *result;\ |
SGLIB_DL_LIST_FIND_MEMBER(type, list, elem, comparator, previous, next, result);\ |
return(result);\ |
}\ |
type *sglib_##type##_get_first(type *list) {\ |
type *result;\ |
SGLIB_DL_LIST_GET_FIRST(type, list, previous, next, result);\ |
return(result);\ |
}\ |
type *sglib_##type##_get_last(type *list) {\ |
type *result;\ |
SGLIB_DL_LIST_GET_LAST(type, list, previous, next, result);\ |
return(result);\ |
}\ |
void sglib_##type##_sort(type **list) {\ |
SGLIB_DL_LIST_SORT(type, *list, comparator, previous, next);\ |
}\ |
int sglib_##type##_len(type *list) {\ |
int res;\ |
SGLIB_DL_LIST_LEN(type, list, previous, next, res);\ |
return(res);\ |
}\ |
void sglib_##type##_reverse(type **list) {\ |
SGLIB_DL_LIST_REVERSE(type, *list, previous, next);\ |
}\ |
\ |
type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto) {\ |
it->subcomparator = subcomparator;\ |
it->equalto = equalto;\ |
it->prevelem = list;\ |
it->nextelem = list;\ |
if (list != NULL) it->nextelem = list->next;\ |
return(sglib_##type##_it_next(it));\ |
}\ |
type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list) {\ |
return(sglib_##type##_it_init_on_equal(it, list, NULL, NULL));\ |
}\ |
type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\ |
return(it->currentelem);\ |
}\ |
type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\ |
type *ce, *eq;\ |
int (*scp)(type *, type *);\ |
ce = it->prevelem;\ |
it->prevelem = NULL;\ |
if (it->subcomparator != NULL) {\ |
eq = it->equalto; \ |
scp = it->subcomparator;\ |
while (ce!=NULL && scp(eq, ce)!=0) ce = ce->previous;\ |
}\ |
if (ce != NULL) {\ |
it->prevelem = ce->previous;\ |
} else {\ |
ce = it->nextelem;\ |
it->nextelem = NULL;\ |
if (it->subcomparator != NULL) {\ |
eq = it->equalto; \ |
scp = it->subcomparator;\ |
while (ce!=NULL && scp(ce, eq)!=0) ce = ce->next;\ |
}\ |
if (ce != NULL) it->nextelem = ce->next;\ |
}\ |
it->currentelem = ce;\ |
return(ce);\ |
} |
|
|
/* --------------------------------- red-black trees (level 1) -------------------------------- */ |
|
/* |
|
This implementation requires pointers to left and right sons (no |
parent pointer is needed) and one bit of additional information |
storing the color of the node. The implementation follows discrepancy |
fixing rules from: |
http://www.cis.ohio-state.edu/~gurari/course/cis680/cis680Ch11.html |
|
*/ |
|
#define SGLIB___RBTREE_FIX_INSERTION_DISCREPANCY(type, tree, leftt, rightt, bits, RED, BLACK) {\ |
type *t, *tl, *a, *b, *c, *ar, *bl, *br, *cl, *cr;\ |
t = *tree;\ |
tl = t->leftt;\ |
if (t->rightt!=NULL && SGLIB___GET_VALUE(t->rightt->bits)==RED) {\ |
if (SGLIB___GET_VALUE(tl->bits)==RED) {\ |
if ((tl->leftt!=NULL && SGLIB___GET_VALUE(tl->leftt->bits)==RED) \ |
|| (tl->rightt!=NULL && SGLIB___GET_VALUE(tl->rightt->bits)==RED)) {\ |
SGLIB___SET_VALUE(t->leftt->bits,BLACK);\ |
SGLIB___SET_VALUE(t->rightt->bits,BLACK);\ |
SGLIB___SET_VALUE(t->bits,RED);\ |
}\ |
}\ |
} else {\ |
if (SGLIB___GET_VALUE(tl->bits)==RED) {\ |
if (tl->leftt!=NULL && SGLIB___GET_VALUE(tl->leftt->bits)==RED) {\ |
a = t; b = tl; c = tl->leftt;\ |
br = b->rightt;\ |
a->leftt = br;\ |
b->leftt = c; b->rightt = a;\ |
SGLIB___SET_VALUE(a->bits,RED);\ |
SGLIB___SET_VALUE(b->bits,BLACK);\ |
*tree = b;\ |
} else if (tl->rightt!=NULL && SGLIB___GET_VALUE(tl->rightt->bits)==RED) {\ |
a = t; b = tl; ar=a->rightt;\ |
bl=b->leftt; c=b->rightt;\ |
cl=c->leftt; cr=c->rightt;\ |
b->rightt = cl;\ |
a->leftt = cr;\ |
c->leftt = b;\ |
c->rightt = a;\ |
SGLIB___SET_VALUE(c->bits,BLACK);\ |
SGLIB___SET_VALUE(a->bits,RED);\ |
*tree = c;\ |
}\ |
}\ |
}\ |
} |
|
#define SGLIB___RBTREE_FIX_DELETION_DISCREPANCY(type, tree, leftt, rightt, bits, RED, BLACK, res) {\ |
type *t, *a, *b, *c, *d, *ar, *bl, *br, *cl, *cr, *dl, *dr;\ |
t = a = *tree;\ |
assert(t!=NULL);\ |
ar = a->rightt;\ |
b = t->leftt;\ |
if (b==NULL) {\ |
assert(SGLIB___GET_VALUE(t->bits)==RED);\ |
SGLIB___SET_VALUE(t->bits,BLACK);\ |
res = 0;\ |
} else {\ |
bl = b->leftt;\ |
br = b->rightt;\ |
if (SGLIB___GET_VALUE(b->bits)==RED) {\ |
if (br==NULL) {\ |
*tree = b;\ |
SGLIB___SET_VALUE(b->bits,BLACK);\ |
b->rightt = a;\ |
a->leftt = br;\ |
res = 0;\ |
} else {\ |
c = br;\ |
assert(c!=NULL && SGLIB___GET_VALUE(c->bits)==BLACK);\ |
cl = c->leftt;\ |
cr = c->rightt;\ |
if ((cl==NULL||SGLIB___GET_VALUE(cl->bits)==BLACK) && (cr==NULL||SGLIB___GET_VALUE(cr->bits)==BLACK)) {\ |
*tree = b;\ |
b->rightt = a;\ |
SGLIB___SET_VALUE(b->bits,BLACK);\ |
a->leftt = c;\ |
SGLIB___SET_VALUE(c->bits,RED);\ |
res = 0;\ |
} else if (cl!=NULL && SGLIB___GET_VALUE(cl->bits)==RED) {\ |
if (cr!=NULL && SGLIB___GET_VALUE(cr->bits)==RED) {\ |
d = cr;\ |
dl = d->leftt;\ |
dr = d->rightt;\ |
*tree = d;\ |
SGLIB___SET_VALUE(d->bits,BLACK);\ |
d->leftt = b;\ |
c->rightt = dl;\ |
d->rightt = a;\ |
a->leftt = dr;\ |
res = 0;\ |
} else {\ |
*tree = c;\ |
c->leftt = b;\ |
c->rightt = a;\ |
b->leftt = bl;\ |
b->rightt = cl;\ |
a->leftt = cr;\ |
SGLIB___SET_VALUE(cl->bits,BLACK);\ |
res = 0;\ |
}\ |
} else if (cr!=NULL && SGLIB___GET_VALUE(cr->bits)==RED) {\ |
assert(cl==NULL || SGLIB___GET_VALUE(cl->bits)==BLACK);\ |
d = cr;\ |
dl = d->leftt;\ |
dr = d->rightt;\ |
*tree = d;\ |
SGLIB___SET_VALUE(d->bits,BLACK);\ |
d->leftt = b;\ |
c->rightt = dl;\ |
d->rightt = a;\ |
a->leftt = dr;\ |
res = 0;\ |
} else {\ |
assert(0);\ |
res = 0;\ |
}\ |
}\ |
} else {\ |
if ((bl==NULL || SGLIB___GET_VALUE(bl->bits)==BLACK) && (br==NULL || SGLIB___GET_VALUE(br->bits)==BLACK)) {\ |
res = (SGLIB___GET_VALUE(a->bits)==BLACK);\ |
SGLIB___SET_VALUE(a->bits,BLACK);\ |
SGLIB___SET_VALUE(b->bits,RED);\ |
} else if (bl!=NULL && SGLIB___GET_VALUE(bl->bits)==RED) {\ |
if (br==NULL || SGLIB___GET_VALUE(br->bits)==BLACK) {\ |
*tree = b;\ |
SGLIB___SET_VALUE(b->bits,SGLIB___GET_VALUE(a->bits));\ |
SGLIB___SET_VALUE(a->bits,BLACK);\ |
b->rightt = a;\ |
a->leftt = br;\ |
SGLIB___SET_VALUE(bl->bits,BLACK);\ |
res = 0;\ |
} else {\ |
assert(bl!=NULL);\ |
assert(br!=NULL);\ |
assert(SGLIB___GET_VALUE(bl->bits)==RED);\ |
assert(SGLIB___GET_VALUE(br->bits)==RED);\ |
c = br;\ |
cl = c->leftt;\ |
cr = c->rightt;\ |
*tree = c;\ |
SGLIB___SET_VALUE(c->bits,SGLIB___GET_VALUE(a->bits));\ |
SGLIB___SET_VALUE(a->bits,BLACK);\ |
c->leftt = b;\ |
c->rightt = a;\ |
b->rightt = cl;\ |
a->leftt = cr;\ |
res = 0;\ |
}\ |
} else {\ |
assert(br!=NULL && SGLIB___GET_VALUE(br->bits)==RED);\ |
c = br;\ |
cl = c->leftt;\ |
cr = c->rightt;\ |
*tree = c;\ |
SGLIB___SET_VALUE(c->bits,SGLIB___GET_VALUE(a->bits));\ |
SGLIB___SET_VALUE(a->bits,BLACK);\ |
c->leftt = b;\ |
c->rightt = a;\ |
b->rightt = cl;\ |
a->leftt = cr;\ |
res = 0;\ |
}\ |
}\ |
}\ |
} |
|
|
#define SGLIB_DEFINE_RBTREE_FUNCTIONS_GENERAL(type, left, right, bits, comparator, RED, BLACK) \ |
static void sglib___##type##_fix_left_insertion_discrepancy(type **tree) {\ |
SGLIB___RBTREE_FIX_INSERTION_DISCREPANCY(type, tree, left, right, bits, RED, BLACK);\ |
}\ |
\ |
static void sglib___##type##_fix_right_insertion_discrepancy(type **tree) {\ |
SGLIB___RBTREE_FIX_INSERTION_DISCREPANCY(type, tree, right, left, bits, RED, BLACK);\ |
}\ |
\ |
static int sglib___##type##_fix_left_deletion_discrepancy(type **tree) {\ |
int res;\ |
SGLIB___RBTREE_FIX_DELETION_DISCREPANCY(type, tree, right, left, bits, RED, BLACK, res);\ |
return(res);\ |
}\ |
\ |
static int sglib___##type##_fix_right_deletion_discrepancy(type **tree) {\ |
int res;\ |
SGLIB___RBTREE_FIX_DELETION_DISCREPANCY(type, tree, left, right, bits, RED, BLACK, res);\ |
return(res);\ |
}\ |
\ |
static void sglib___##type##_add_recursive(type **tree, type *elem) {\ |
int cmp;\ |
type *t;\ |
t = *tree;\ |
if (t == NULL) {\ |
SGLIB___SET_VALUE(elem->bits,RED);\ |
*tree =elem;\ |
} else {\ |
cmp = comparator(elem, t);\ |
if (cmp < 0 || (cmp==0 && elem<t)) {\ |
sglib___##type##_add_recursive(&t->left, elem);\ |
if (SGLIB___GET_VALUE(t->bits)==BLACK) sglib___##type##_fix_left_insertion_discrepancy(tree);\ |
} else {\ |
sglib___##type##_add_recursive(&t->right, elem);\ |
if (SGLIB___GET_VALUE(t->bits)==BLACK) sglib___##type##_fix_right_insertion_discrepancy(tree);\ |
}\ |
}\ |
}\ |
\ |
static int sglib___##type##_delete_rightmost_leaf(type **tree, type **theLeaf) {\ |
type *t;\ |
int res, deepDecreased;\ |
t = *tree;\ |
res = 0;\ |
assert(t!=NULL);\ |
if (t->right == NULL) {\ |
*theLeaf = t;\ |
if (t->left!=NULL) {\ |
if (SGLIB___GET_VALUE(t->bits)==BLACK && SGLIB___GET_VALUE(t->left->bits)==BLACK) res = 1;\ |
SGLIB___SET_VALUE(t->left->bits,BLACK);\ |
*tree = t->left;\ |
} else {\ |
*tree = NULL;\ |
res = (SGLIB___GET_VALUE(t->bits)==BLACK);\ |
}\ |
} else {\ |
deepDecreased = sglib___##type##_delete_rightmost_leaf(&t->right, theLeaf);\ |
if (deepDecreased) res = sglib___##type##_fix_right_deletion_discrepancy(tree);\ |
}\ |
return(res);\ |
}\ |
\ |
int sglib___##type##_delete_recursive(type **tree, type *elem) {\ |
type *t, *theLeaf;\ |
int cmp, res, deepDecreased;\ |
t = *tree;\ |
res = 0;\ |
if (t==NULL) {\ |
assert(0 && "The element to delete not found in the tree, use 'delete_if_member'"!=NULL);\ |
} else {\ |
cmp = comparator(elem, t);\ |
if (cmp < 0 || (cmp==0 && elem<t)) {\ |
deepDecreased = sglib___##type##_delete_recursive(&t->left, elem);\ |
if (deepDecreased) {\ |
res = sglib___##type##_fix_left_deletion_discrepancy(tree);\ |
}\ |
} else if (cmp > 0 || (cmp==0 && elem>t)) {\ |
deepDecreased = sglib___##type##_delete_recursive(&t->right, elem);\ |
if (deepDecreased) {\ |
res = sglib___##type##_fix_right_deletion_discrepancy(tree);\ |
}\ |
} else {\ |
assert(elem==t && "Deleting an element which is non member of the tree, use 'delete_if_member'"!=NULL);\ |
if (t->left == NULL) {\ |
if (t->right == NULL) {\ |
/* a leaf, delete, it; */\ |
*tree = NULL;\ |
res = (SGLIB___GET_VALUE(t->bits)==BLACK);\ |
} else {\ |
if (SGLIB___GET_VALUE(t->bits)==0 && SGLIB___GET_VALUE(t->right->bits)==0) res = 1;\ |
SGLIB___SET_VALUE(t->right->bits,BLACK);\ |
*tree = t->right;\ |
}\ |
} else {\ |
/* propagate deletion until righmost leaf of left subtree */\ |
deepDecreased = sglib___##type##_delete_rightmost_leaf(&t->left, &theLeaf);\ |
theLeaf->left = t->left;\ |
theLeaf->right = t->right;\ |
SGLIB___SET_VALUE(theLeaf->bits,SGLIB___GET_VALUE(t->bits));\ |
*tree = theLeaf;\ |
if (deepDecreased) res = sglib___##type##_fix_left_deletion_discrepancy(tree);\ |
}\ |
}\ |
}\ |
return(res);\ |
}\ |
\ |
void sglib_##type##_add(type **tree, type *elem) {\ |
elem->left = elem->right = NULL;\ |
sglib___##type##_add_recursive(tree, elem);\ |
SGLIB___SET_VALUE((*tree)->bits,BLACK);\ |
}\ |
\ |
void sglib_##type##_delete(type **tree, type *elem) {\ |
sglib___##type##_delete_recursive(tree, elem);\ |
if (*tree!=NULL) SGLIB___SET_VALUE((*tree)->bits,BLACK);\ |
}\ |
\ |
type *sglib_##type##_find_member(type *t, type *elem) {\ |
type *res;\ |
SGLIB___BIN_TREE_FIND_MEMBER(type, t, elem, left, right, comparator, res);\ |
return(res);\ |
}\ |
\ |
int sglib_##type##_is_member(type *t, type *elem) {\ |
int cmp;\ |
while (t!=NULL) {\ |
cmp = comparator(elem, t);\ |
if (cmp < 0 || (cmp==0 && elem<t)) {\ |
t = t->left;\ |
} else if (cmp > 0 || (cmp==0 && elem>t)) {\ |
t = t->right;\ |
} else {\ |
assert(t == elem);\ |
return(1);\ |
}\ |
}\ |
return(0);\ |
}\ |
\ |
int sglib_##type##_delete_if_member(type **tree, type *elem, type **memb) {\ |
if ((*memb=sglib_##type##_find_member(*tree, elem))!=NULL) {\ |
sglib_##type##_delete(tree, *memb);\ |
return(1);\ |
} else {\ |
return(0);\ |
}\ |
}\ |
int sglib_##type##_add_if_not_member(type **tree, type *elem, type **memb) {\ |
if ((*memb=sglib_##type##_find_member(*tree, elem))==NULL) {\ |
sglib_##type##_add(tree, elem);\ |
return(1);\ |
} else {\ |
return(0);\ |
}\ |
}\ |
int sglib_##type##_len(type *t) {\ |
int n;\ |
type *e;\ |
n = 0;\ |
SGLIB_BIN_TREE_MAP_ON_ELEMENTS(type, t, e, left, right, n++);\ |
return(n);\ |
}\ |
\ |
void sglib__##type##_it_compute_current_elem(struct sglib_##type##_iterator *it) {\ |
int i,j,cmp;\ |
type *s, *eqt;\ |
int (*subcomparator)(type *, type *);\ |
eqt = it->equalto;\ |
subcomparator = it->subcomparator;\ |
it->currentelem = NULL;\ |
while(it->pathi > 0 && it->currentelem==NULL) {\ |
i = it->pathi-1;\ |
if (i >= 0) {\ |
if (it->pass[i] >= 2) {\ |
/* goto up */\ |
it->pathi --;\ |
} else {\ |
if (it->pass[i] == 0) {\ |
/* goto left */\ |
s = it->path[i]->left;\ |
} else {\ |
/* goto right */\ |
s = it->path[i]->right;\ |
}\ |
if (eqt != NULL) {\ |
if (subcomparator == NULL) {\ |
SGLIB___BIN_TREE_FIND_MEMBER(type, s, eqt, left, right, comparator, s);\ |
} else {\ |
SGLIB___BIN_TREE_FIND_MEMBER(type, s, eqt, left, right, subcomparator, s);\ |
}\ |
}\ |
if (s != NULL) {\ |
j = i+1;\ |
it->path[j] = s;\ |
it->pass[j] = 0;\ |
it->pathi ++;\ |
}\ |
it->pass[i] ++;\ |
}\ |
}\ |
if (it->pathi>0 && it->order == it->pass[it->pathi-1]) {\ |
it->currentelem = it->path[it->pathi-1];\ |
}\ |
}\ |
}\ |
type *sglib__##type##_it_init(struct sglib_##type##_iterator *it, type *tree, int order, int (*subcomparator)(type *, type *), type *equalto) {\ |
type *t;\ |
assert(it!=NULL);\ |
it->order = order;\ |
it->equalto = equalto;\ |
it->subcomparator = subcomparator;\ |
if (equalto == NULL) { \ |
t = tree;\ |
} else {\ |
if (subcomparator == NULL) {\ |
SGLIB___BIN_TREE_FIND_MEMBER(type, tree, equalto, left, right, comparator, t);\ |
} else {\ |
SGLIB___BIN_TREE_FIND_MEMBER(type, tree, equalto, left, right, subcomparator, t);\ |
}\ |
}\ |
if (t == NULL) {\ |
it->pathi = 0;\ |
it->currentelem = NULL;\ |
} else {\ |
it->pathi = 1;\ |
it->pass[0] = 0;\ |
it->path[0] = t;\ |
if (order == 0) {\ |
it->currentelem = t;\ |
} else {\ |
sglib__##type##_it_compute_current_elem(it);\ |
}\ |
}\ |
return(it->currentelem);\ |
}\ |
type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *tree) {\ |
return(sglib__##type##_it_init(it, tree, 2, NULL, NULL));\ |
}\ |
type *sglib_##type##_it_init_preorder(struct sglib_##type##_iterator *it, type *tree) {\ |
return(sglib__##type##_it_init(it, tree, 0, NULL, NULL));\ |
}\ |
type *sglib_##type##_it_init_inorder(struct sglib_##type##_iterator *it, type *tree) {\ |
return(sglib__##type##_it_init(it, tree, 1, NULL, NULL));\ |
}\ |
type *sglib_##type##_it_init_postorder(struct sglib_##type##_iterator *it, type *tree) {\ |
return(sglib__##type##_it_init(it, tree, 2, NULL, NULL));\ |
}\ |
type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *tree, int (*subcomparator)(type *, type *), type *equalto) {\ |
return(sglib__##type##_it_init(it, tree, 1, subcomparator, equalto));\ |
}\ |
type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\ |
return(it->currentelem);\ |
}\ |
type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\ |
sglib__##type##_it_compute_current_elem(it);\ |
return(it->currentelem);\ |
}\ |
\ |
static void sglib___##type##_consistency_check_recursive(type *t, int *pathdeep, int cdeep) {\ |
if (t==NULL) {\ |
if (*pathdeep < 0) *pathdeep = cdeep;\ |
else assert(*pathdeep == cdeep);\ |
} else {\ |
if (t->left!=NULL) assert(comparator(t->left, t) <= 0);\ |
if (t->right!=NULL) assert(comparator(t, t->right) <= 0);\ |
if (SGLIB___GET_VALUE(t->bits) == RED) {\ |
assert(t->left == NULL || SGLIB___GET_VALUE(t->left->bits)==BLACK);\ |
assert(t->right == NULL || SGLIB___GET_VALUE(t->right->bits)==BLACK);\ |
sglib___##type##_consistency_check_recursive(t->left, pathdeep, cdeep);\ |
sglib___##type##_consistency_check_recursive(t->right, pathdeep, cdeep);\ |
} else {\ |
sglib___##type##_consistency_check_recursive(t->left, pathdeep, cdeep+1);\ |
sglib___##type##_consistency_check_recursive(t->right, pathdeep, cdeep+1);\ |
}\ |
}\ |
}\ |
\ |
void sglib___##type##_consistency_check(type *t) {\ |
int pathDeep;\ |
assert(t==NULL || SGLIB___GET_VALUE(t->bits) == BLACK);\ |
pathDeep = -1;\ |
sglib___##type##_consistency_check_recursive(t, &pathDeep, 0);\ |
} |
|
|
#define SGLIB_DEFINE_RBTREE_PROTOTYPES(type, left, right, colorbit, comparator) \ |
struct sglib_##type##_iterator {\ |
type *currentelem;\ |
char pass[SGLIB_MAX_TREE_DEEP];\ |
type *path[SGLIB_MAX_TREE_DEEP];\ |
short int pathi;\ |
short int order;\ |
type *equalto;\ |
int (*subcomparator)(type *, type *);\ |
};\ |
extern void sglib___##type##_consistency_check(type *t); \ |
extern void sglib_##type##_add(type **tree, type *elem); \ |
extern int sglib_##type##_add_if_not_member(type **tree, type *elem, type **memb); \ |
extern void sglib_##type##_delete(type **tree, type *elem); \ |
extern int sglib_##type##_delete_if_member(type **tree, type *elem, type **memb); \ |
extern int sglib_##type##_is_member(type *t, type *elem); \ |
extern type *sglib_##type##_find_member(type *t, type *elem); \ |
extern int sglib_##type##_len(type *t); \ |
extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *tree); \ |
extern type *sglib_##type##_it_init_preorder(struct sglib_##type##_iterator *it, type *tree); \ |
extern type *sglib_##type##_it_init_inorder(struct sglib_##type##_iterator *it, type *tree); \ |
extern type *sglib_##type##_it_init_postorder(struct sglib_##type##_iterator *it, type *tree); \ |
extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *tree, int (*subcomparator)(type *, type *), type *equalto); \ |
extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \ |
extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it); \ |
|
|
#define SGLIB_DEFINE_RBTREE_FUNCTIONS(type, left, right, colorbit, comparator) \ |
SGLIB_DEFINE_RBTREE_FUNCTIONS_GENERAL(type, left, right, colorbit, comparator, 1, 0) |
|
|
|
/* ---------------------------------------------------------------------------- */ |
/* ---------------------------------------------------------------------------- */ |
/* - SUPPLEMENTARY DEFINITIONS - */ |
/* ---------------------------------------------------------------------------- */ |
/* ---------------------------------------------------------------------------- */ |
|
|
#define SGLIB___GET_VALUE(x) (x) |
#define SGLIB___SET_VALUE(x, value) {(x) = (value);} |
#define SGLIB_ARRAY_ELEMENTS_EXCHANGER(type, a, i, j) {type _sgl_aee_tmp_; _sgl_aee_tmp_=(a)[(i)]; (a)[(i)]=(a)[(j)]; (a)[(j)]= _sgl_aee_tmp_;} |
|
|
#define SGLIB_NUMERIC_COMPARATOR(x, y) ((int)((x) - (y))) |
#define SGLIB_REVERSE_NUMERIC_COMPARATOR(x, y) ((int)((y) - (x))) |
|
#ifndef SGLIB_MAX_TREE_DEEP |
#define SGLIB_MAX_TREE_DEEP 128 |
#endif |
|
#ifndef SGLIB_HASH_TAB_SHIFT_CONSTANT |
#define SGLIB_HASH_TAB_SHIFT_CONSTANT 211 /* should be a prime */ |
#endif |
|
#endif /* _SGLIB__h_ */ |
/trunk/src/sc2v_step1.c
0,0 → 1,79
/* ----------------------------------------------------------------------------- |
* |
* SystemC to Verilog Translator v0.3 |
* Provided by OpenSoc Design |
* |
* www.opensocdesign.com |
* |
* ----------------------------------------------------------------------------- |
* 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 Library General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program; if not, write to the Free Software |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston,MA 02111-1307, USA. |
*/ |
|
#include <stdlib.h> |
#include <stdio.h> |
#include <math.h> |
|
#include "sc2v_step1.h" |
|
DefineNode *InsertDefine(DefineNode *list,char *name){ |
DefineNode *dl; |
|
dl=(DefineNode *)malloc(sizeof(DefineNode)); |
strcpy(dl->name,name); |
SGLIB_LIST_ADD(DefineNode,list,dl,next); |
|
return(list); |
} |
|
int IsDefine(DefineNode *list,char *name){ |
|
DefineNode *dll; |
SGLIB_LIST_MAP_ON_ELEMENTS (DefineNode, list, dll, next, |
{ |
if ((strcmp (name, (char *)dll->name) == 0)) return(1); |
} |
); |
return(0); |
} |
|
|
RegNode *InsertReg(RegNode *list, char *name, char *name2){ |
|
RegNode *rl; |
|
rl=(RegNode *)malloc(sizeof(RegNode)); |
strcpy(rl->name,name); |
strcpy(rl->name2,name2); |
SGLIB_LIST_ADD(RegNode,list,rl,next); |
return(list); |
|
} |
|
|
/*Looks if a WORD of func.y file is a register of the process*/ |
char * |
IsReg (RegNode *list, char *name) |
{ |
|
RegNode *rll; |
SGLIB_LIST_MAP_ON_ELEMENTS (RegNode, list, rll, next, |
{ |
if ((strcmp (name, (char *)rll->name) == 0)) |
{ |
return (rll->name2);} |
} |
); |
return NULL; |
} |
/trunk/src/sc2v_step2.c
0,0 → 1,573
/* ----------------------------------------------------------------------------- |
* |
* SystemC to Verilog Translator v0.3 |
* Provided by OpenSoc Design |
* |
* www.opensocdesign.com |
* |
* ----------------------------------------------------------------------------- |
* 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 Library General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program; if not, write to the Free Software |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
*/ |
|
#include <stdlib.h> |
#include <stdio.h> |
#include <math.h> |
|
#include "sc2v_step2.h" |
|
void |
ShowDefines (char *filedefines) |
{ |
|
int readok; |
|
char *auxchar; |
FILE *file; |
|
file = fopen (filedefines, (char *) "r"); |
|
while (1){ |
readok = fread ((void *) &auxchar, sizeof (char), 1, file); |
if (readok){ |
printf ("%c", auxchar); |
}else{ |
break; |
} |
} |
} |
|
WriteNode * |
InsertWrite (WriteNode * list, char *name) |
{ |
WriteNode *wl; |
|
wl = (WriteNode *) malloc (sizeof (WriteNode)); |
strcpy (wl->name, name); |
SGLIB_LIST_ADD (WriteNode, list, wl, next); |
return (list); |
} |
|
int |
IsWrite (WriteNode * list, char *name) |
{ |
WriteNode *wll; |
SGLIB_LIST_MAP_ON_ELEMENTS (WriteNode, list, wll, next, |
{ |
if ((strcmp (name, (char *) wll->name) == 0)) return (1); |
} |
); |
return (0); |
} |
|
void |
ShowWritesList (WriteNode * list) |
{ |
WriteNode *wll; |
SGLIB_LIST_MAP_ON_ELEMENTS (WriteNode, list, wll, next,{ |
printf ("%s\n", wll->name); |
} |
); |
return; |
} |
|
|
|
WriteNode * |
ReadWritesFile (WriteNode *list,char *name) |
{ |
|
char *leido; |
int ret; |
FILE *file_writes; |
file_writes = fopen (name, (char *) "r"); |
|
leido = (char *) malloc (256 * sizeof (char)); |
|
while (1){ |
ret = fscanf (file_writes, "%s", leido); |
if (ret == EOF) |
break; |
list = InsertWrite (list, leido); |
} |
return(list); |
} |
|
PortNode * |
InsertPort (PortNode * list, char *name, char *tipo, int size) |
{ |
PortNode *pl; |
pl = (PortNode *) malloc (sizeof (PortNode)); |
strcpy (pl->name, name); |
strcpy (pl->tipo, tipo); |
pl->size = size; |
SGLIB_LIST_ADD (PortNode, list, pl, next); |
return (list); |
} |
|
void |
ShowPortList (PortNode * list) |
{ |
|
PortNode *pll; |
SGLIB_LIST_MAP_ON_ELEMENTS (PortNode, list, pll, next, |
{ |
printf ("%s ", pll->tipo); |
if (pll->size != 0 && pll->size != 1) |
{ |
printf ("[%d:0] ", (-1 + pll->size));} |
printf ("%s;\n", pll->name); |
} |
); |
return; |
} |
|
void |
RegOutputs (PortNode * list) |
{ |
|
PortNode *pll; |
SGLIB_LIST_MAP_ON_ELEMENTS (PortNode, list, pll, next, |
{ |
if (strcmp (pll->tipo, "output") == 0) |
{ |
printf ("reg "); |
if (pll->size != 0 && pll->size != 1) |
{ |
printf ("[%d:0] ", (-1 + pll->size));} |
printf ("%s;\n", pll->name);} |
} |
); |
return; |
} |
|
void |
EnumeratePorts (PortNode * list) |
{ |
PortNode *pll; |
|
SGLIB_LIST_MAP_ON_ELEMENTS (PortNode, list, pll, next, |
{ |
if (pll->next == NULL) |
{ |
printf ("%s", pll->name); break; |
} |
else |
{ |
printf ("%s,", pll->name);} |
} |
); |
return; |
} |
|
SignalNode * |
InsertSignal (SignalNode * list, char *name, int size) |
{ |
SignalNode *sl; |
|
sl = (SignalNode *) malloc (sizeof (SignalNode)); |
strcpy (sl->name, name); |
sl->size = size; |
SGLIB_LIST_ADD (SignalNode, list, sl, next); |
return (list); |
|
} |
|
|
void |
ShowSignalsList (SignalNode * list) |
{ |
SignalNode *sll; |
SGLIB_LIST_MAP_ON_ELEMENTS (SignalNode, list, sll, next, |
{ |
if (IsWrite (writeslist, sll->name)) |
{ |
printf ("reg "); |
if (sll->size != 0 && sll->size != 1) |
{ |
printf ("[%d:0] ", (-1 + sll->size)); |
} |
printf ("%s;\n", sll->name); |
} |
else |
{ |
printf ("wire "); |
if (sll->size != 0 && sll->size != 1) |
{ |
printf ("[%d:0] ", (-1 + sll->size)); |
} |
printf ("%s;\n", sll->name); |
} |
} |
); |
return; |
} |
|
|
/* Decides if a signal is a wire or a reg*/ |
int |
IsWire (char *name, InstanceNode * list) |
{ |
|
InstanceNode *ill; |
SGLIB_LIST_MAP_ON_ELEMENTS (InstanceNode, list, ill, next, |
{ |
BindNode * bll; |
SGLIB_LIST_MAP_ON_ELEMENTS (BindNode,ill->bindslist, bll, next, |
{ |
if ((strcmp(name,bll->namebind) ==0)) |
{ |
return 1; |
} |
} |
);} |
); |
return 0; |
} |
|
|
|
SensibilityNode * |
InsertSensibility (SensibilityNode * list, char *name, char *tipo) |
{ |
SensibilityNode *sl; |
sl = (SensibilityNode *) malloc (sizeof (SensibilityNode)); |
strcpy (sl->name, name); |
strcpy (sl->tipo, tipo); |
SGLIB_LIST_ADD (SensibilityNode, list, sl, next); |
return (list); |
} |
|
void |
ShowSensibilityList (SensibilityNode * list) |
{ |
SensibilityNode *sll; |
SGLIB_LIST_MAP_ON_ELEMENTS (SensibilityNode, list, sll, next, |
{ |
if (!strcmp (sll->tipo, "posedge")|| !strcmp (sll->tipo,"negedge")) |
printf (" %s",sll->tipo); |
if (sll->next == NULL) |
{ |
printf (" %s", sll->name); break; |
} |
else |
{ |
printf (" %s or", sll->name);} |
} |
); |
return; |
} |
|
|
ProcessNode * |
InsertProcess (ProcessNode * list, char *name, |
SensibilityNode * SensibilityList, char *tipo) |
{ |
ProcessNode *pl; |
pl = (ProcessNode *) malloc (sizeof (ProcessNode)); |
strcpy (pl->name, name); |
strcpy (pl->tipo, tipo); |
pl->list = SensibilityList; |
SGLIB_LIST_ADD (ProcessNode, list, pl, next); |
return (list); |
} |
|
|
void |
ShowProcessList (ProcessNode * list) |
{ |
ProcessNode *pll; |
SGLIB_LIST_MAP_ON_ELEMENTS (ProcessNode, list, pll, next, |
{ |
printf ("%s: always @(", pll->name); |
ShowSensibilityList (pll->list); printf (")\n"); |
} |
); |
return; |
} |
|
|
void |
ShowProcessCode (ProcessNode * list) |
{ |
FILE *archivo; |
int readok; |
char lookahead; |
char *filename; |
char auxchar; |
char begin[10]; |
|
ProcessNode *pll; |
SGLIB_LIST_MAP_ON_ELEMENTS (ProcessNode, list, pll, next, |
{ |
fprintf(stderr,"Writing process code => %s\n",pll->name); |
printf ("//%s:\n", pll->name); |
filename =(char *) malloc (256 * sizeof (char)); |
strcpy (filename, pll->name); |
strcat (filename, (char *) "_regs.sc2v"); |
archivo = fopen (filename, (char *) "r"); |
while (1) |
{ |
readok =fread ((void *) &auxchar, sizeof (char), 1,archivo); |
if (readok) printf ("%c", auxchar); |
else |
break; |
} |
fclose (archivo); |
printf ("always @("); |
|
ShowSensibilityList (pll->list); |
printf (" )\n"); |
printf (" begin\n"); |
strcpy (filename, pll->name); |
strcat (filename, (char *) ".sc2v"); |
archivo = fopen (filename, (char *) "r"); |
|
/*Read the initial begin of the file */ |
fscanf (archivo, "%s", begin); |
readok =fread ((void *) &auxchar, sizeof (char), 1,archivo); |
|
/*Trim the beggining of the file */ |
while (auxchar == '\n' || auxchar == ' ' || auxchar == '\t') |
readok =fread ((void *) &auxchar, sizeof (char), 1,archivo); printf ("\n %c", auxchar); |
|
while (1){ |
readok = fread ((void *) &auxchar, sizeof (char), 1,archivo); |
if (readok){ |
if (strcmp (pll->tipo, "comb") == 0 && auxchar == '<') |
{ |
readok = fread ((void *) &lookahead, sizeof (char), 1, archivo); |
if (readok){ |
if (lookahead == '='){ |
auxchar = lookahead; |
}else{ |
printf ("%c", auxchar); |
} |
} |
} |
printf ("%c", auxchar); |
} |
else |
{ |
break; |
} |
} |
|
fclose (archivo); |
} |
); |
|
} |
|
InstanceNode * |
InsertInstance (InstanceNode * list, char *nameinstance, char *namemodulo) |
{ |
InstanceNode *il; |
il = (InstanceNode *) malloc (sizeof (InstanceNode)); |
strcpy (il->nameinstance, nameinstance); |
strcpy (il->namemodulo, namemodulo); |
il->bindslist = NULL; |
SGLIB_LIST_ADD (InstanceNode, list, il, next); |
return (list); |
} |
|
BindNode * |
InsertBind (BindNode * list, char *nameport, char *namebind) |
{ |
BindNode *bl; |
bl = (BindNode *) malloc (sizeof (BindNode)); |
strcpy (bl->nameport, nameport); |
strcpy (bl->namebind, namebind); |
SGLIB_LIST_ADD (BindNode, list, bl, next); |
return (list); |
|
} |
|
|
void |
ShowInstancedModules (InstanceNode * list) |
{ |
InstanceNode *ill; |
SGLIB_LIST_MAP_ON_ELEMENTS (InstanceNode, list, ill, next, |
{ |
printf ("%s %s (", ill->namemodulo,ill->nameinstance); |
BindNode * bll; |
SGLIB_LIST_MAP_ON_ELEMENTS (BindNode,ill->bindslist, bll,next, |
{ |
printf (".%s(%s)",bll->nameport,bll->namebind); |
if (bll->next == NULL) |
printf (");\n"); |
else |
printf (", ");} |
);} |
); |
} |
|
|
EnumeratesNode *InsertEnumerates (EnumeratesNode * list, char *name) |
{ |
|
EnumeratesNode *el; |
el = (EnumeratesNode *) malloc (sizeof (EnumeratesNode)); |
strcpy (el->name, name); |
SGLIB_LIST_ADD (EnumeratesNode, list, el, next); |
return (list); |
} |
|
|
int |
ShowEnumeratesList (EnumeratesNode *list) |
{ |
|
EnumeratesNode *ell; |
int i = 0; |
|
SGLIB_LIST_REVERSE(EnumeratesNode, list, next); |
|
printf ("parameter %s = 0", list->name); |
|
if(list->next!=NULL) |
list=list->next; |
|
if(list->next!=NULL){ |
printf(",\n"); |
i=1; |
SGLIB_LIST_MAP_ON_ELEMENTS (EnumeratesNode,list, ell,next, |
{ |
if(ell->next==NULL) |
{ |
printf(" %s = %d;\n\n",ell->name,i); |
return(i); |
} |
else |
{ |
printf(" %s = %d,\n",ell->name,i); |
} |
i++; |
} |
); |
}else{ |
printf(";\n\n"); |
return(i); |
} |
} |
|
EnumListNode * |
InsertEnumList (EnumListNode * list, EnumeratesNode * enumlist, char *name,int istype) |
{ |
EnumListNode *el; |
el = (EnumListNode *) malloc (sizeof (EnumListNode)); |
strcpy (el->name, name); |
el->istype=istype; |
el->list=enumlist; |
SGLIB_LIST_ADD (EnumListNode, list, el, next); |
return (list); |
} |
|
void |
ShowEnumListList (EnumListNode * list) |
{ |
|
int items; |
EnumListNode *ell; |
double bits, bits_round; |
int bits_i; |
|
SGLIB_LIST_MAP_ON_ELEMENTS(EnumListNode,list, ell,next, |
{ |
|
items = ShowEnumeratesList (ell->list); |
|
//Calculate the number of bits needed to represent the enumerate |
bits = log ((double) (items + 1)) / log (2.0); |
bits_i = bits; |
bits_round = bits_i; |
if (bits_round != bits) |
bits_i++; |
if (bits_i == 0) |
bits_i = 1; |
|
if (!(ell->istype)) |
{ |
if ((bits_i - 1) != 0) |
printf ("reg [%d:0] %s;\n\n", bits_i - 1, ell->name); |
else |
printf ("reg %s;\n\n", ell->name); |
} |
|
} |
); |
} |
|
|
int |
findEnumList (EnumListNode * list, char *name) |
{ |
|
int i = 0; |
EnumListNode *ell; |
|
SGLIB_LIST_MAP_ON_ELEMENTS (EnumListNode,list, ell,next, |
{ |
//printf("%s %s %d %d\n", aux->name,name,aux->istype,i); |
if ((strcmp (ell->name, name) == 0) && ((ell->istype) == 1)) |
{ |
return i; |
} |
|
i++; |
} |
); |
return -1; |
} |
|
|
int |
findEnumerateLength (EnumListNode * list, int offset) |
{ |
|
int i,j = 0; |
double bits, bits_round; |
int bits_i; |
|
EnumListNode *ell; |
EnumeratesNode *enumll; |
|
j=0; |
i=0; |
|
SGLIB_LIST_MAP_ON_ELEMENTS (EnumListNode,list, ell,next, |
{ |
i++; |
if(i==offset+1){ |
SGLIB_LIST_MAP_ON_ELEMENTS (EnumeratesNode,ell->list, enumll,next, |
{ |
j++; |
}); |
} |
}); |
|
//Calculate the number of bits needed to represent the enumerate |
bits = log ((double) (j)) / log (2.0); |
bits_i = bits; |
bits_round = bits_i; |
|
if (bits_round != bits) |
bits_i++; |
if (bits_i == 0) |
bits_i = 1; |
|
return bits_i; |
|
} |
/trunk/src/Makefile
15,25 → 15,26
# |
# Cygwin |
# |
#LEX = flex |
#YACC = bison -y |
LEX = flex |
YACC = bison -y |
# |
# Linux |
# |
LEX = lex |
YACC = yacc |
#LEX = lex |
#YACC = yacc |
|
all: |
$(LEX) sc2v_step1.l |
$(YACC) -d sc2v_step1.y |
gcc lex.yy.c y.tab.c sc2v_step1.c -Isrc -o ../bin/sc2v_step1 -lm |
|
$(LEX) sc2v_step2.l |
$(YACC) -d sc2v_step2.y |
gcc lex.yy.c y.tab.c list.c -Isrc -o ../bin/sc2v_step2 -lm |
$(LEX) sc2v_step1.l |
$(YACC) -d sc2v_step1.y |
gcc lex.yy.c y.tab.c list.c -Isrc -o ../bin/sc2v_step1 -lm |
gcc lex.yy.c y.tab.c sc2v_step2.c -Isrc -o ../bin/sc2v_step2 -lm |
|
$(LEX) sc2v_step3.l |
$(YACC) -d sc2v_step3.y |
gcc lex.yy.c y.tab.c list.c -Isrc -o ../bin/sc2v_step3 -lm |
gcc lex.yy.c y.tab.c -Isrc -o ../bin/sc2v_step3 -lm |
|
clean: |
|
/trunk/Makefile
18,10 → 18,10
|
test: |
cd src; make all |
cd examples; ../bin/sc2v.sh stmach_k; ../bin/sc2v.sh rng; ../bin/sc2v.sh md5; ../bin/sc2v.sh fsm; echo ""; echo "sc2v translated the following files successfully"; echo ""; ls -l *.v |
cd examples; ../bin/sc2v.sh delay_line; ../bin/sc2v.sh stmach_k; ../bin/sc2v.sh rng; ../bin/sc2v.sh md5; ../bin/sc2v.sh fsm; echo ""; echo "sc2v translated the following files successfully"; echo ""; ls -l *.v |
|
docs: |
cd src; doxygen doxygen.cfg |
|
clean: |
\rm -r docs; cd src; make clean |
\rm -r docs; cd src; make clean; cd ../examples/; rm -rf *.v |
/trunk/README
54,8 → 54,7
|
- You cannot use functions. |
|
-Macros with no parameters are supported, but may cause little problems |
with name of variables. Macros with parameters are not supported. |
-Macros not fully supported. |
|
-Only data types: bool, sc_int, sc_bigint, sc_uint and sc_biguint are |
supported. |
/trunk/examples/fsm.cpp
3,52 → 3,65
#define HOLA 1 |
#define CONCAT 1 |
|
void fsm::regs(){ |
if(rst.read()){ |
state.write(S0); |
}else |
state.write(next_state); |
void |
fsm::regs () |
{ |
if (rst.read ()) |
{ |
state.write (S0); |
} |
else |
state.write (next_state); |
} |
|
void fsm::fsm_proc(){ |
void |
fsm::fsm_proc () |
{ |
/*Verilog begin |
cfsm_proc={a[1:0],b[1:0]}; |
verilog end*/ |
|
sc_uint<2> c; |
next_state.write(state.read()); |
a.write(0); |
b.write(HOLA); |
|
#ifdef CONCAT |
c.write((a.range(1,0),b.range(1,0))); |
#else |
c.write((a,a)); |
#endif |
|
switch((int)state.read()){ |
case S0 : //Case 0 |
if(input1.read()){ |
next_state.write(S1); |
a.write(true); |
}else if (input2.read()){ |
next_state.write(S2); |
a.write(false); |
}else{ |
next_state.write(S0); |
a.write(1); |
} |
break; |
// tRaNsLaTe oFF |
case S1: |
if(input2.read()){ |
next_state.write(S2); |
b.write(1); |
} |
break; |
// tRaNsLaTe oN |
case S2: |
next_state.write(S0); |
break; |
} |
sc_uint < 2 > c; |
next_state.write (state.read ()); |
a.write (0); |
b.write (HOLA); |
|
#ifdef CONCAT |
c.write ((a.range (1, 0), b.range (1, 0))); |
#else |
c.write ((a, a)); |
#endif |
|
switch ((int) state.read ()) |
{ |
case S0: //Case 0 |
if (input1.read ()) |
{ |
next_state.write (S1); |
a.write (true); |
} |
else if (input2.read ()) |
{ |
next_state.write (S2); |
a.write (false); |
} |
else |
{ |
next_state.write (S0); |
a.write (1); |
} |
break; |
// tRaNsLaTe oFF |
case S1: |
if (input2.read ()) |
{ |
next_state.write (S2); |
b.write (1); |
} |
break; |
// tRaNsLaTe oN |
case S2: |
next_state.write (S0); |
break; |
} |
} |
/trunk/examples/fsm.h
13,6 → 13,9
enum state_t {S0,S1,S2}; |
sc_signal<state_t> state,next_state; |
|
enum {AA,BB,CC,DD,EE} estado; |
enum {a} est; |
|
//translate off |
sc_signal<sc_uint<4> > temp; |
//translate on |
23,12 → 26,12
SC_CTOR(fsm){ |
|
SC_METHOD(regs); |
sensitive_pos(clk); |
sensitive_neg(rst); |
sensitive_pos(clk); |
sensitive_neg(rst); |
|
SC_METHOD(fsm_proc); |
sensitive(state); |
sensitive << input1; |
SC_METHOD(fsm_proc); |
sensitive(state); |
sensitive << input1; |
sensitive(input2); |
|
} |