parser for gds started
This commit is contained in:
commit
db753126ac
74
.gitignore
vendored
Normal file
74
.gitignore
vendored
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
# This file is used to ignore files which are generated
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
*~
|
||||||
|
*.autosave
|
||||||
|
*.a
|
||||||
|
*.core
|
||||||
|
*.moc
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
*.orig
|
||||||
|
*.rej
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
*_pch.h.cpp
|
||||||
|
*_resource.rc
|
||||||
|
*.qm
|
||||||
|
.#*
|
||||||
|
*.*#
|
||||||
|
core
|
||||||
|
!core/
|
||||||
|
tags
|
||||||
|
.DS_Store
|
||||||
|
.directory
|
||||||
|
*.debug
|
||||||
|
Makefile*
|
||||||
|
*.prl
|
||||||
|
*.app
|
||||||
|
moc_*.cpp
|
||||||
|
ui_*.h
|
||||||
|
qrc_*.cpp
|
||||||
|
Thumbs.db
|
||||||
|
*.res
|
||||||
|
*.rc
|
||||||
|
/.qmake.cache
|
||||||
|
/.qmake.stash
|
||||||
|
|
||||||
|
# qtcreator generated files
|
||||||
|
*.pro.user*
|
||||||
|
|
||||||
|
# xemacs temporary files
|
||||||
|
*.flc
|
||||||
|
|
||||||
|
# Vim temporary files
|
||||||
|
.*.swp
|
||||||
|
|
||||||
|
# Visual Studio generated files
|
||||||
|
*.ib_pdb_index
|
||||||
|
*.idb
|
||||||
|
*.ilk
|
||||||
|
*.pdb
|
||||||
|
*.sln
|
||||||
|
*.suo
|
||||||
|
*.vcproj
|
||||||
|
*vcproj.*.*.user
|
||||||
|
*.ncb
|
||||||
|
*.sdf
|
||||||
|
*.opensdf
|
||||||
|
*.vcxproj
|
||||||
|
*vcxproj.*
|
||||||
|
|
||||||
|
# MinGW generated files
|
||||||
|
*.Debug
|
||||||
|
*.Release
|
||||||
|
|
||||||
|
# Python byte code
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Binaries
|
||||||
|
# --------
|
||||||
|
*.dll
|
||||||
|
*.exe
|
||||||
|
|
||||||
|
*.user
|
4
CMakeLists.txt
Normal file
4
CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
|
||||||
|
project(gds-render)
|
||||||
|
add_executable(${PROJECT_NAME} "main.c" "gdsparse.c")
|
219
gdsparse.c
Normal file
219
gdsparse.c
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
#include "gdsparse.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define GDS_ERROR(fmt, ...) printf("[PARSE_ERROR] " fmt "\n", #__VA_ARGS__)
|
||||||
|
#define GDS_WARN(fmt, ...) printf("[PARSE_WARNING] " fmt "\n", #__VA_ARGS__)
|
||||||
|
enum parsing_state {PARSING_LENGTH = 0, PARSING_TYPE, PARSING_DAT};
|
||||||
|
enum record {
|
||||||
|
HEADER = 0x0002,
|
||||||
|
BGNLIB = 0x0102,
|
||||||
|
LIBNAME = 0x0206,
|
||||||
|
UNITS = 0x0305,
|
||||||
|
ENDLIB = 0x0400,
|
||||||
|
BGNSTR = 0x0500,
|
||||||
|
STRNAME = 0x0606,
|
||||||
|
ENDSTR = 0x0700,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct gds_library * append_library(struct gds_library *curr_arr, unsigned int curr_count)
|
||||||
|
{
|
||||||
|
unsigned int size = (curr_count +1) * sizeof(struct gds_library);
|
||||||
|
return (struct gds_library *)realloc(curr_arr, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct gds_cell * append_cell(struct gds_cell *curr_arr, unsigned int curr_count)
|
||||||
|
{
|
||||||
|
unsigned int size = (curr_count +1) * sizeof(struct gds_cell);
|
||||||
|
return (struct gds_cell *)realloc(curr_arr, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int name_library(struct gds_library *current_library, unsigned int bytes, char* data) {
|
||||||
|
int len;
|
||||||
|
|
||||||
|
data[bytes] = 0; // Append '0'
|
||||||
|
len = strlen(data);
|
||||||
|
if (len > CELL_NAME_MAX-1) {
|
||||||
|
GDS_ERROR("Library name '%s' too long: %d\n", data, len);
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
strcpy(current_library->name, data);
|
||||||
|
printf("Named library: %s\n", current_library->name);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int name_cell(struct gds_cell *cell, unsigned int bytes, char* data) {
|
||||||
|
int len;
|
||||||
|
|
||||||
|
data[bytes] = 0; // Append '0'
|
||||||
|
len = strlen(data);
|
||||||
|
if (len > CELL_NAME_MAX-1) {
|
||||||
|
GDS_ERROR("Library name '%s' too long: %d\n", data, len);
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
strcpy(cell->name, data);
|
||||||
|
printf("Named library: %s\n", cell->name);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int parse_gds_from_file(const char *filename, struct gds_library **library_array, unsigned int *count)
|
||||||
|
{
|
||||||
|
char workbuff[1024];
|
||||||
|
int read;
|
||||||
|
int run = 1;
|
||||||
|
FILE *gds_file = NULL;
|
||||||
|
uint16_t rec_data_length;
|
||||||
|
enum record rec_type;
|
||||||
|
enum parsing_state state = PARSING_LENGTH;
|
||||||
|
struct gds_library *current_lib = NULL;
|
||||||
|
struct gds_cell *current_cell = NULL;
|
||||||
|
struct gds_graphics *current_graphics = NULL;
|
||||||
|
struct gds_cell_instance *current_s_reference = NULL;
|
||||||
|
////////////
|
||||||
|
struct gds_library *lib_arr = NULL;
|
||||||
|
struct gds_cell *cell_arr = NULL;
|
||||||
|
unsigned int lib_arr_cnt = 0;
|
||||||
|
unsigned int cell_arr_cnt = 0;
|
||||||
|
|
||||||
|
/* open File */
|
||||||
|
gds_file = fopen(filename, "r");
|
||||||
|
if (gds_file == NULL) {
|
||||||
|
GDS_ERROR("Could not open File %s", filename);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Record parser */
|
||||||
|
while (run == 1) {
|
||||||
|
switch (state) {
|
||||||
|
case PARSING_LENGTH:
|
||||||
|
read = fread(workbuff, sizeof(char), 2, gds_file);
|
||||||
|
if (read != 2 && (current_cell != NULL ||
|
||||||
|
current_graphics != NULL ||
|
||||||
|
current_lib != NULL ||
|
||||||
|
current_s_reference != NULL)) {
|
||||||
|
GDS_ERROR("End of File. with openend structs/libs");
|
||||||
|
run = -2;
|
||||||
|
break;
|
||||||
|
} else if (read != 2) {
|
||||||
|
/* EOF */
|
||||||
|
run = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
rec_data_length = (uint16_t)((((uint16_t)(workbuff[0])) << 8) |
|
||||||
|
(uint16_t)(workbuff[1]));
|
||||||
|
|
||||||
|
if (rec_data_length < 4) {
|
||||||
|
/* Possible Zero-Padding: */
|
||||||
|
run = 0;
|
||||||
|
GDS_WARN("Zero Padding detected!");
|
||||||
|
if (current_cell != NULL ||
|
||||||
|
current_graphics != NULL ||
|
||||||
|
current_lib != NULL ||
|
||||||
|
current_s_reference != NULL) {
|
||||||
|
GDS_ERROR("Not all structures closed");
|
||||||
|
run = -2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
rec_data_length -= 4;
|
||||||
|
state = PARSING_TYPE;
|
||||||
|
break;
|
||||||
|
case PARSING_TYPE:
|
||||||
|
read = fread(workbuff, sizeof(char), 2, gds_file);
|
||||||
|
if (read != 2) {
|
||||||
|
run = -2;
|
||||||
|
GDS_ERROR("Unexpected end of file");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
rec_type = (uint16_t)((((uint16_t)(workbuff[0])) << 8) |
|
||||||
|
(uint16_t)(workbuff[1]));
|
||||||
|
state = PARSING_DAT;
|
||||||
|
|
||||||
|
/* if begin: Allocate structures */
|
||||||
|
switch (rec_type) {
|
||||||
|
case BGNLIB:
|
||||||
|
lib_arr = append_library(lib_arr, lib_arr_cnt);
|
||||||
|
lib_arr_cnt++;
|
||||||
|
if (lib_arr == NULL) {
|
||||||
|
GDS_ERROR("Allocating memory failed");
|
||||||
|
run = -3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
printf("Entering Lib\n");
|
||||||
|
current_lib = &(lib_arr[lib_arr_cnt-1]);
|
||||||
|
break;
|
||||||
|
case ENDLIB:
|
||||||
|
if (current_lib == NULL) {
|
||||||
|
run = -4;
|
||||||
|
GDS_ERROR("Closing Library with no opened library");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
current_lib = NULL;
|
||||||
|
printf("Leaving Library\n");
|
||||||
|
case BGNSTR:
|
||||||
|
cell_arr = append_cell(cell_arr, cell_arr_cnt);
|
||||||
|
cell_arr_cnt++;
|
||||||
|
if (lib_arr == NULL) {
|
||||||
|
GDS_ERROR("Allocating memory failed");
|
||||||
|
run = -3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
printf("Entering Cell\n");
|
||||||
|
current_cell = &(cell_arr[cell_arr_cnt-1]);
|
||||||
|
break;
|
||||||
|
case ENDSTR:
|
||||||
|
if (current_cell == NULL) {
|
||||||
|
run = -4;
|
||||||
|
GDS_ERROR("Closing cell with no opened cell");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
current_cell = NULL;
|
||||||
|
printf("Leaving Cell\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PARSING_DAT:
|
||||||
|
read = fread(workbuff, sizeof(char), rec_data_length, gds_file);
|
||||||
|
state = PARSING_LENGTH;
|
||||||
|
|
||||||
|
if (read != rec_data_length) {
|
||||||
|
GDS_ERROR("Could not read enough data");
|
||||||
|
run = -5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* No Data -> No Processing */
|
||||||
|
if (!read) break;
|
||||||
|
|
||||||
|
switch (rec_type) {
|
||||||
|
case LIBNAME:
|
||||||
|
name_library(current_lib, read,workbuff);
|
||||||
|
break;
|
||||||
|
case STRNAME:
|
||||||
|
name_cell(current_cell, read, workbuff);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(gds_file);
|
||||||
|
|
||||||
|
*library_array = lib_arr;
|
||||||
|
*count = lib_arr_cnt;
|
||||||
|
return run;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
62
gdsparse.h
Normal file
62
gdsparse.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#ifndef __GDSPARSE_H__
|
||||||
|
#define __GDSPARSE_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define CELL_NAME_MAX (100)
|
||||||
|
|
||||||
|
enum graphics_type {GRAPHIC_PATH = 0, GRAPHIC_POLYGON = 1};
|
||||||
|
|
||||||
|
struct gds_time_field {
|
||||||
|
uint16_t year;
|
||||||
|
uint16_t month;
|
||||||
|
uint16_t day;
|
||||||
|
uint16_t hour;
|
||||||
|
uint16_t minute;
|
||||||
|
uint16_t second;
|
||||||
|
};
|
||||||
|
struct gds_point {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gds_graphics {
|
||||||
|
enum graphics_type type;
|
||||||
|
struct gds_point *vertices;
|
||||||
|
int vertices_count;
|
||||||
|
uint16_t layer;
|
||||||
|
uint16_t datatype;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gds_cell_instance {
|
||||||
|
char ref_name[CELL_NAME_MAX];
|
||||||
|
struct gds_cell *cell_ref;
|
||||||
|
struct gds_point origin;
|
||||||
|
int flipped;
|
||||||
|
double angle;
|
||||||
|
double magnification;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gds_cell {
|
||||||
|
char name[CELL_NAME_MAX];
|
||||||
|
struct gds_time_field mod_time;
|
||||||
|
struct gds_time_field access_time;
|
||||||
|
struct gds_cell_instance *child_cells;
|
||||||
|
int child_cells_count;
|
||||||
|
struct gds_graphics *graphic_objs;
|
||||||
|
int graphic_objs_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gds_library {
|
||||||
|
char name[CELL_NAME_MAX];
|
||||||
|
struct gds_time_field time;
|
||||||
|
double unit_to_meters;
|
||||||
|
struct gds_cell *cells;
|
||||||
|
int cells_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int parse_gds_from_file(const char *filename, struct gds_library **library_array, unsigned int *count);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __GDSPARSE_H__ */
|
Loading…
Reference in New Issue
Block a user