43#include <glib/gi18n.h>
51#define GDS_DEFAULT_UNITS (10E-9)
53#define GDS_ERROR(fmt, ...) printf("[PARSE_ERROR] " fmt "\n", ##__VA_ARGS__)
54#define GDS_WARN(fmt, ...) printf("[PARSE_WARNING] " fmt "\n", ##__VA_ARGS__)
56#if GDS_PRINT_DEBUG_INFOS
58 #define GDS_INF(fmt, ...) printf(fmt, ##__VA_ARGS__)
60 #define GDS_INF(fmt, ...)
115 unsigned int bytes,
char *data)
119 if (cell_inst == NULL) {
120 GDS_ERROR(
"Naming cell ref with no opened cell ref");
124 len = (int)strlen(data);
126 GDS_ERROR(
"Cell name '%s' too long: %d\n", data, len);
145 unsigned int bytes,
char *data)
149 if (cell_inst == NULL) {
150 GDS_ERROR(
"Naming array cell ref with no opened cell ref");
154 len = (int)strlen(data);
156 GDS_ERROR(
"Cell name '%s' too long: %d\n", data, len);
181 sign_bit = ((data[0] & 0x80) ?
true :
false);
184 for (i = 0; i < 8; i++) {
195 for (i = 8; i < 64; i++) {
196 current_byte = data[i/8];
199 if ((current_byte & (0x80 >> bit)))
200 ret_val += pow(2, ((
double)(-i+7)));
205 exponent = (int)(data[0] & 0x7F);
207 ret_val *= pow(16, exponent) * (sign_bit ==
true ? -1 : 1);
222 GDS_ERROR(
"Conversion from GDS data to signed int failed.");
226 ret = (
signed int)(((((
int)data[0]) & 0xFF) << 24) |
227 ((((int)data[1]) & 0xFF) << 16) |
228 (((int)(data[2]) & 0xFF) << 8) |
229 (((int)(data[3]) & 0xFF) << 0));
244 return (int16_t)((((int16_t)(data[0]) & 0xFF) << 8) |
245 (((int16_t)(data[1]) & 0xFF) << 0));
259 return (uint16_t)((((uint16_t)(data[0]) & 0xFF) << 8) |
260 (((uint16_t)(data[1]) & 0xFF) << 0));
284 return g_list_append(curr_list, lib);
313 return g_list_prepend(curr_list, gfx);
333 return g_list_append(curr_list, vertex);
362 return g_list_append(curr_list, cell);
389 *instance_ptr = inst;
391 return g_list_append(curr_list, inst);
402 unsigned int bytes,
char *data)
406 if (current_library == NULL) {
407 GDS_ERROR(
"Naming cell with no opened library");
412 len = (int)strlen(data);
414 GDS_ERROR(
"Library name '%s' too long: %d\n", data, len);
418 strcpy(current_library->
name, data);
419 GDS_INF(
"Named library: %s\n", current_library->
name);
438 GDS_ERROR(
"Naming library with no opened library");
442 len = (int)strlen(data);
444 GDS_ERROR(
"Cell name '%s' too long: %d\n", data, len);
448 strcpy(cell->
name, data);
473 for (cell_item = lib->
cells; cell_item != NULL;
474 cell_item = cell_item->next) {
476 cell = (
struct gds_cell *)cell_item->data;
487 GDS_WARN(
"referenced cell could not be found in library");
535 if (!access_date || !mod_date) {
536 GDS_WARN(
"Date structures invalid");
540 if (length != (2*6*2)) {
541 GDS_WARN(
"Could not parse date field! Not the specified length");
545 for (temp_date = mod_date; 1; temp_date = access_date) {
559 if (temp_date == access_date)
584 if (!aref || !container_cell)
588 GDS_ERROR(
"Conversion of array instance aborted. No rows / columns.");
600 for (col = 0; col < aref->
columns; col++) {
601 for (row = 0; row < aref->
rows; row++) {
613 sref_inst->
origin.
x =
origin.
x + row_shift_vector.
x * row + col_shift_vector.
x * col;
614 sref_inst->
origin.
y =
origin.
y + row_shift_vector.
y * row + col_shift_vector.
y * col;
617 GDS_INF(
"Converted AREF to SREFs\n");
626 FILE *gds_file = NULL;
627 uint16_t rec_data_length;
630 struct gds_cell *current_cell = NULL;
639 lib_list = *library_list;
642 workbuff = (
char *)malloc(
sizeof(
char)*128*1024);
648 gds_file = fopen(filename,
"rb");
649 if (gds_file == NULL) {
650 GDS_ERROR(
"Could not open File %s", filename);
657 read = fread(workbuff,
sizeof(
char), 2, gds_file);
658 if (read != 2 && (current_cell != NULL ||
659 current_graphics != NULL ||
660 current_lib != NULL ||
661 current_s_reference != NULL)) {
662 GDS_ERROR(
"End of File. with openend structs/libs");
665 }
else if (read != 2) {
673 if (rec_data_length < 4) {
677 if (current_cell != NULL ||
678 current_graphics != NULL ||
679 current_lib != NULL ||
680 current_s_reference != NULL) {
686 rec_data_length -= 4;
688 read = fread(workbuff,
sizeof(
char), 2, gds_file);
701 if (lib_list == NULL) {
710 if (current_lib == NULL) {
712 GDS_ERROR(
"Closing Library with no opened library");
717 if (current_cell != NULL) {
719 GDS_ERROR(
"Closing Library with opened cells");
726 if (current_lib == NULL) {
727 GDS_ERROR(
"Defining Cell outside of library!\n");
732 if (current_lib->
cells == NULL) {
743 if (current_cell == NULL) {
745 GDS_ERROR(
"Closing cell with no opened cell");
749 if (current_graphics != NULL || current_s_reference != NULL) {
751 GDS_ERROR(
"Closing cell with opened Elements");
759 if (current_cell == NULL) {
760 GDS_ERROR(
"Boundary/Box outside of cell");
774 GDS_INF(
"\tEntering boundary/Box\n");
777 if (current_cell == NULL) {
778 GDS_ERROR(
"Cell Reference outside of cell");
783 ¤t_s_reference);
790 GDS_INF(
"\tEntering reference\n");
793 if (current_cell == NULL) {
808 if (current_graphics != NULL) {
810 current_graphics = NULL;
812 if (current_s_reference != NULL) {
813 GDS_INF(
"\tLeaving Reference\n");
814 current_s_reference = NULL;
816 if (current_a_reference != NULL) {
817 GDS_INF(
"\tLeaving Array Reference\n");
819 current_a_reference = NULL;
824 if (current_graphics) {
826 }
else if (current_s_reference) {
827 if (rec_data_length != 8) {
828 GDS_WARN(
"Instance has weird coordinates. Rendered output might be screwed!");
830 }
else if (current_a_reference) {
831 if (rec_data_length != (3*(4+4)))
832 GDS_WARN(
"Array instance has weird coordinates. Rendered output might be screwed!");
836 if (current_cell == NULL) {
837 GDS_ERROR(
"Cell array reference outside of cell");
842 if (current_a_reference != NULL) {
843 GDS_ERROR(
"Recursive cell array reference");
848 GDS_INF(
"Entering Array Reference\n");
853 current_a_reference = &temp_a_reference;
854 current_a_reference->
ref_name[0] =
'\0';
855 current_a_reference->
angle = 0.0;
857 current_a_reference->
flipped = 0;
858 current_a_reference->
rows = 0;
859 current_a_reference->
columns = 0;
875 GDS_INF(
"Unhandled Record: %04x, len: %u\n", (
unsigned int)rec_type, (
unsigned int)rec_data_length);
881 if (!rec_data_length || run != 1)
continue;
883 read = fread(workbuff,
sizeof(
char), rec_data_length, gds_file);
885 if (read != rec_data_length) {
886 GDS_ERROR(
"Could not read enough data: requested: %u, read: %u | Type: 0x%04x\n",
887 (
unsigned int)rec_data_length, (
unsigned int)read, (
unsigned int)rec_type);
906 if (!current_a_reference) {
907 GDS_ERROR(
"COLROW record defined outside of array instance");
910 if (rec_data_length != 4 || read != 4) {
911 GDS_ERROR(
"COLUMN/ROW count record contains too few data. Won't set column and row counts (%d, %d)",
912 rec_data_length, read);
917 GDS_INF(
"\tRows: %d\n\tColumns: %d\n", current_a_reference->
rows, current_a_reference->
columns);
921 GDS_WARN(
"Units defined outside of library!\n");
925 if (rec_data_length != 16) {
926 GDS_WARN(
"Unit define incomplete. Will assume database unit of %E meters\n", current_lib->
unit_in_meters);
941 name_library(current_lib, (
unsigned int)read, workbuff);
944 name_cell(current_cell, (
unsigned int)read, workbuff, current_lib);
947 if (current_s_reference) {
951 GDS_INF(
"\t\tSet origin to: %d/%d\n", current_s_reference->
origin.
x,
952 current_s_reference->
origin.
y);
953 }
else if (current_graphics) {
954 for (i = 0; i < read/8; i++) {
959 GDS_INF(
"\t\tSet coordinate: %d/%d\n", x, y);
962 }
else if (current_a_reference) {
963 for (i = 0; i < 3; i++) {
968 GDS_INF(
"\tSet control point %d: %d/%d\n", i, x, y);
973 if (current_s_reference) {
974 current_s_reference->
flipped = ((workbuff[0] & 0x80) ? 1 : 0);
975 }
else if (current_a_reference) {
976 current_a_reference->
flipped = ((workbuff[0] & 0x80) ? 1 : 0);
978 GDS_ERROR(
"Transformation defined outside of instance");
983 if (current_s_reference) {
984 name_cell_ref(current_s_reference, (
unsigned int)read, workbuff);
985 }
else if (current_a_reference) {
988 GDS_ERROR(
"Reference name set outside of cell reference");
992 if (!current_graphics) {
993 GDS_WARN(
"Width defined outside of path element");
998 if (!current_graphics) {
999 GDS_WARN(
"Layer has to be defined inside graphics object. Probably unknown object. Implement it yourself!");
1003 if (current_graphics->
layer < 0) {
1006 GDS_INF(
"\t\tAdded layer %d\n", (
int)current_graphics->
layer);
1009 if (!current_graphics) {
1010 GDS_WARN(
"Datatype has to be defined inside graphics object. Probably unknown object. Implement it yourself!");
1014 if (current_graphics->
datatype < 0)
1019 if (rec_data_length != 8) {
1020 GDS_WARN(
"Magnification is not an 8 byte real. Results may be wrong");
1022 if (current_graphics != NULL && current_s_reference != NULL) {
1023 GDS_ERROR(
"Open Graphics and Cell Reference\n\tMissing ENDEL?");
1027 if (current_s_reference != NULL) {
1031 if (current_a_reference != NULL) {
1037 if (rec_data_length != 8) {
1038 GDS_WARN(
"Angle is not an 8 byte real. Results may be wrong");
1040 if (current_graphics != NULL && current_s_reference != NULL && current_a_reference != NULL) {
1041 GDS_ERROR(
"Open Graphics and Cell Reference\n\tMissing ENDEL?");
1045 if (current_s_reference != NULL) {
1047 GDS_INF(
"\t\tAngle defined: %lf\n", current_s_reference->
angle);
1049 if (current_a_reference != NULL) {
1051 GDS_INF(
"\t\tAngle defined: %lf\n", current_a_reference->
angle);
1055 if (current_graphics == NULL) {
1056 GDS_WARN(
"Path type defined outside of path. Ignoring");
1063 GDS_WARN(
"Path type defined inside non-path graphics object. Ignoring");
1078 *library_list = lib_list;
1151 if (*library_list == NULL)
1155 *library_list = NULL;
Header file for the GDS-Parser.
static void delete_cell_element(struct gds_cell *cell)
delete_cell_element
static int name_cell_ref(struct gds_cell_instance *cell_inst, unsigned int bytes, char *data)
Name cell reference.
#define GDS_DEFAULT_UNITS
Default units assumed for library.
static GList * append_cell(GList *curr_list, struct gds_cell **cell_ptr)
append_cell Append a gds_cell to a list
static GList * append_vertex(GList *curr_list, int x, int y)
Appends vertext List.
static void delete_vertex(struct gds_point *vertex)
delete_vertex
static int name_library(struct gds_library *current_library, unsigned int bytes, char *data)
Name a gds_library.
static int name_array_cell_ref(struct gds_cell_array_instance *cell_inst, unsigned int bytes, char *data)
Name cell reference.
static void convert_aref_to_sref(struct gds_cell_array_instance *aref, struct gds_cell *container_cell)
Convert AREF to a bunch of SREFs and append them to container_cell.
#define GDS_WARN(fmt,...)
Print GDS warning.
#define GDS_ERROR(fmt,...)
Print GDS error.
static double gds_convert_double(const char *data)
Convert GDS 8-byte real to double.
static signed int gds_convert_signed_int(const char *data)
Convert GDS INT32 to int.
static void scan_library_references(gpointer library_list_item, gpointer user)
Scans library's cell references.
static GList * append_cell_ref(GList *curr_list, struct gds_cell_instance **instance_ptr)
Append a cell reference to the reference GList.
static void delete_graphics_obj(struct gds_graphics *gfx)
delete_graphics_obj
static void parse_reference_list(gpointer gcell_ref, gpointer glibrary)
Search for cell reference gcell_ref in glibrary.
static void gds_parse_date(const char *buffer, int length, struct gds_time_field *mod_date, struct gds_time_field *access_date)
gds_parse_date
static void delete_cell_inst_element(struct gds_cell_instance *cell_inst)
delete_cell_inst_element
static void scan_cell_reference_dependencies(gpointer gcell, gpointer library)
Scans cell references inside cell This function searches all the references in gcell and updates the ...
graphics_type
Types of graphic objects.
int clear_lib_list(GList **library_list)
Deletes all libraries including cells, references etc.
static GList * prepend_graphics(GList *curr_list, enum graphics_type type, struct gds_graphics **graphics_ptr)
Prepend graphics to list.
static int name_cell(struct gds_cell *cell, unsigned int bytes, char *data, struct gds_library *lib)
Names a gds_cell.
path_type
Defines the line caps of a path.
static uint16_t gds_convert_unsigned_int16(const char *data)
Convert GDS UINT16 String to uint16.
int parse_gds_from_file(const char *filename, GList **library_list)
Parse a GDS file.
static int16_t gds_convert_signed_int16(const char *data)
Convert GDS INT16 to int16.
static GList * append_library(GList *curr_list, struct gds_library **library_ptr)
Append library to list.
static void delete_library_element(struct gds_library *lib)
delete_library_element
#define CELL_NAME_MAX
Maximum length of a gds_cell::name or a gds_library::name.
@ GRAPHIC_POLYGON
An arbitrary polygon.
@ GRAPHIC_PATH
Path. Esentially a line.
@ GRAPHIC_BOX
A rectangle.
Struct representing an array instantiation.
struct gds_point control_points[3]
The three control points.
int flipped
Mirror each instance on x-axis before rotation.
double angle
Angle of rotation for each instance (counter clockwise) in degrees.
double magnification
Magnification of each instance.
struct gds_cell * cell_ref
Referenced gds_cell structure.
char ref_name[CELL_NAME_MAX]
Name of referenced cell.
int unresolved_child_count
Number of unresolved cell instances inside this cell. Default: GDS_CELL_CHECK_NOT_RUN.
int affected_by_reference_loop
1 if the cell is affected by a reference loop and therefore not renderable. Default: GDS_CELL_CHECK_N...
This represents an instanc of a cell inside another cell.
int flipped
Mirrored on x-axis before rotation.
double angle
Angle of rotation (counter clockwise) in degrees.
double magnification
magnification
struct gds_cell * cell_ref
Referenced gds_cell structure.
struct gds_point origin
Origin.
char ref_name[CELL_NAME_MAX]
Name of referenced cell.
A Cell inside a gds_library.
struct gds_time_field mod_time
struct gds_cell_checks checks
Checking results.
struct gds_time_field access_time
GList * child_cells
List of gds_cell_instance elements.
struct gds_library * parent_library
Pointer to parent library.
GList * graphic_objs
List of gds_graphics.
int16_t datatype
Data type of graphic object.
enum graphics_type gfx_type
Type of graphic.
enum path_type path_render_type
Line cap.
int width_absolute
Width. Not used for objects other than paths.
int16_t layer
Layer the graphic object is on.
GList * vertices
List of gds_point.
struct gds_time_field mod_time
struct gds_time_field access_time
A point in the 2D plane. Sometimes referred to as vertex.
Date information for cells and libraries.