commit db753126ac45991ef360b0a240c696894fa8064f Author: Mario Hüttel Date: Mon May 7 13:27:50 2018 +0200 parser for gds started diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bf313c1 --- /dev/null +++ b/.gitignore @@ -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 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..7a6a084 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 2.8) + +project(gds-render) +add_executable(${PROJECT_NAME} "main.c" "gdsparse.c") diff --git a/gdsparse.c b/gdsparse.c new file mode 100644 index 0000000..4509bdb --- /dev/null +++ b/gdsparse.c @@ -0,0 +1,219 @@ +#include "gdsparse.h" +#include +#include +#include + +#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; + + +} diff --git a/gdsparse.h b/gdsparse.h new file mode 100644 index 0000000..4184041 --- /dev/null +++ b/gdsparse.h @@ -0,0 +1,62 @@ +#ifndef __GDSPARSE_H__ +#define __GDSPARSE_H__ + +#include + +#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__ */ diff --git a/main.c b/main.c new file mode 100644 index 0000000..bc4dae0 --- /dev/null +++ b/main.c @@ -0,0 +1,11 @@ +#include +#include "gdsparse.h" + +int main() +{ + struct gds_library *libs; + unsigned int count = 0; + parse_gds_from_file("/home/mari/Desktop/test.gds", &libs, &count); + + return 0; +}