/* * COPYRIGHT * * cschem - modular/flexible schematics editor - libcschem (core library) * Copyright (C) 2018,2022 Tibor 'Igor2' Palinkas * * (Supported by NLnet NGI0 PET Fund in 2022) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version.* * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 31 Milk Street, # 960789 Boston, MA 02196 USA * * Contact: * Project page: http://repo.hu/projects/sch-rnd * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html */ #ifndef CSCH_ATTRIB_H #define CSCH_ATTRIB_H #include "libcschem/common_types.h" #include #include #include typedef enum { CSCH_ATP_HARDWIRED = 0, CSCH_ATP_USER_DEFAULT = 250 } csch_attrib_prio_t; typedef struct csch_attrib_s { char *key; int prio; unsigned int deleted:1; char *val; /* scalar; if NULL, use arr */ vts0_t arr; vts0_t source; char *export_name; /* abstract model: if not NULL, export this attribute using this name (always strdup'd) */ } csch_attrib_t; /* Opaque struct for temporarily holding attribute source information */ typedef struct csch_source_arg_s csch_source_arg_t; /* Create source info in dst for different source addressing schemes, as specified in {des4:19} */ csch_source_arg_t *csch_attrib_src_c(const char *filename, long line, long col, const char *desc); csch_source_arg_t *csch_attrib_src_ac(csch_chdr_t *cobj, const char *attr_name, const char *desc); csch_source_arg_t *csch_attrib_src_pa(csch_ahdr_t *aobj, const char *attr_name, const char *plugin_name, const char *desc); csch_source_arg_t *csch_attrib_src_p(const char *plugin_name, const char *desc); typedef enum csch_attrib_src_type_e { /* bitfield */ CSCH_ASRCT_P = 1, CSCH_ASRCT_C = 2, CSCH_ASRCT_A = 4, CSCH_ASRCT_E = 8, CSCH_ASRCT_FAIL = 16 } csch_attrib_src_type_t; /* Parse a source string found in attribute history; return 0 on success; out: - prio: if not NULL: integer priority - type: if not NULL: bitfield of type letters - cobj: if not NULL: loaded with concrete object if addr is concrete - aobj: if not NULL: loaded with abstract object if addr is abstract - attr: if not NULL: loaded with strdup()'d attribute name if available - desc: if not NULL: loaded with pointer into the original source to description Returned values are valid only until any change to the data model in the project or recompilation. *attr needs to be free()'d be the caller. Any output may be NULL if field is not available. */ int csch_attrib_src_parse(csch_sheet_t *sheet, const char *source, int *prio, csch_attrib_src_type_t *type, csch_chdr_t **cobj, csch_ahdr_t **aobj, char **attr, const char **desc); typedef htsp_t csch_attribs_t; void csch_attrib_init(csch_attribs_t *attribs); void csch_attrib_uninit(csch_attribs_t *attribs); #define csch_attrib_get(attribs, key) htsp_get((csch_attribs_t *)attribs, key) /* Returns the string value (or arr value) of an attribute or NULL if the attribute doesn't exist or is not a string (or arr) */ RND_INLINE const char *csch_attrib_get_str(const csch_attribs_t *attribs, const char *key); RND_INLINE const vts0_t *csch_attrib_get_arr(const csch_attribs_t *attribs, const char *key); /* Set a scalar attribute; the ptr version takes malloc()'d val and source; return 0 on write, -1 on failure or if the attrib didn't change because of prios (ptr means "use the ptr provided, don't strdup"). src is always free'd. */ int csch_attrib_set(csch_attribs_t *attribs, int prio, const char *key, const char *val, csch_source_arg_t *source, csch_attrib_t **attr_out); int csch_attrib_setptr(csch_attribs_t *attribs, int prio, char *key, const char *val, csch_source_arg_t *source, csch_attrib_t **attr_out); /* Overwrite an array; src is always free'd. Items are strdup'd */ int csch_attrib_set_arr(csch_attribs_t *attribs, int prio, const char *key, const vts0_t *val, csch_source_arg_t *source, csch_attrib_t **attr_out); int csch_attrib_set_arr_c(csch_attribs_t *attribs, int prio, const char *key, const char **val, csch_source_arg_t *source, csch_attrib_t **attr_out); /* Same as above, but for arrays: overwrite an existing item; src is always free'd. */ int csch_attrib_seti(csch_attribs_t *attribs, int prio, const char *key, long idx, const char *val, csch_source_arg_t *source, csch_attrib_t **attr_out); int csch_attrib_setiptr(csch_attribs_t *attribs, int prio, const char *key, long idx, char *val, csch_source_arg_t *source, csch_attrib_t **attr_out); /* Prepend or append to an array; src is always free'd.*/ int csch_attrib_prepend(csch_attribs_t *attribs, int prio, const char *key, const char *val, csch_source_arg_t *source); int csch_attrib_prependptr(csch_attribs_t *attribs, int prio, const char *key, char *val, csch_source_arg_t *source); int csch_attrib_append(csch_attribs_t *attribs, int prio, const char *key, const char *val, csch_source_arg_t *source); int csch_attrib_appendptr(csch_attribs_t *attribs, int prio, const char *key, char *val, csch_source_arg_t *source); /* Append the value of srca; if it's an array, append all elements in order */ int csch_attrib_append_val(csch_attribs_t *attribs, int prio, const char *key, const csch_attrib_t *srca, csch_source_arg_t *source); /* Del a key from an attribute hash; if history is not NULL, the key is kept and the value is emptied so source history is preserved. src is always free'd. */ int csch_attrib_del(csch_attribs_t *attribs, int prio, const char *key, csch_source_arg_t *source); /* Build an ordered list of attributes; vector items point to (const csch_attrib_t *) */ void csch_attrib_sort(vtp0_t *dst, const csch_attribs_t *attribs); /* Overwrites the export name from expname */ void csch_attrib_set_export_name(csch_attrib_t *dst, const char *expname); /* Allocate a new attribute, duplicate src with all sources (deep copy); does not copy export name. */ csch_attrib_t *csch_attrib_dup(csch_attrib_t *src); csch_attrib_t *csch_attrib_dup_rename(csch_attrib_t *src, const char *new_key); /* copy each src attrib to dst */ void csch_attrib_copy_all(csch_attribs_t *dst, const csch_attribs_t *src); void csch_attrib_copy_all_undoable(csch_sheet_t *sheet, csch_cgrp_t *dst_obj, csch_attribs_t *dst, const csch_attribs_t *src, int undoable); /* copy each src attrib to dst using a forced source; returns 0 on success; src is always free'd. If force_prio is not NULL, use that as the new attributes prio - plugins shall do this normally. Does not apply '-' or '+' prefix; rather use csch_compile_attribute() unless low level copy is needed */ int csch_attrib_apply(csch_attribs_t *dst, const csch_attribs_t *src, csch_source_arg_t *source, int *force_prio); unsigned csch_attrib_hash(const csch_attribs_t *attr); int csch_attrib_eq(const csch_attribs_t *a1, const csch_attribs_t *a2); int csch_attrib_eq_(const csch_attrib_t *a1, const csch_attrib_t *a2); int csch_attrib_val_eq_(const csch_attrib_t *a1, const csch_attrib_t *a2); /* Standard undoable mod functions; negative prio means: keep original if possible, use positive version of the prio if original is not available; src is always free'd. */ void csch_attr_modify_str(csch_sheet_t *sheet, csch_cgrp_t *obj, int prio, const char *key, const char *val, csch_source_arg_t *source, int undoable); void csch_attr_modify_del(csch_sheet_t *sheet, csch_cgrp_t *obj, const char *key, int undoable); /* Undoable modification of attribute priority */ void csch_attr_modify_prio(csch_sheet_t *sheet, csch_cgrp_t *obj, csch_attrib_t *a, int prio, csch_source_arg_t *source, int undoable); /* Rename an attribute (by creating a new one and removing the old one); new_name must not be the same as a->key */ void csch_attr_modify_rename(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_attrib_t *a, const char *new_name, csch_source_arg_t *src, int undoable); void csch_attr_arr_modify_ins_before(csch_sheet_t *sheet, csch_cgrp_t *obj, const char *key, long idx, const char *newval, int undoable); void csch_attr_arr_modify_str(csch_sheet_t *sheet, csch_cgrp_t *obj, const char *key, long idx, const char *newval, int undoable); void csch_attr_arr_modify_del(csch_sheet_t *sheet, csch_cgrp_t *obj, const char *key, long idx, int undoable); void csch_attr_arr_modify_move(csch_sheet_t *sheet, csch_cgrp_t *obj, const char *key, long idx, long delta, int undoable); void csch_attr_modify_conv_to_arr(csch_sheet_t *sheet, csch_cgrp_t *obj, const char *key, int undoable); void csch_attr_modify_conv_to_str(csch_sheet_t *sheet, csch_cgrp_t *obj, const char *key, int undoable); /* Free fields of src and src itself */ void csch_attr_src_free(csch_source_arg_t *src); /* allocate new csch_source_arg_t and copy src */ csch_source_arg_t *csch_attr_src_dup(csch_source_arg_t *src); /* Append src to history of abstract attribute a; useful to log failed attribute sets */ void csch_attrib_append_src(csch_attrib_t *a, int prio, csch_source_arg_t *source, int fail); void csch_attr_side_effects(csch_cgrp_t *grp, const char *key); /* Some alien I/O code need to remove attributes after creating them on load */ void csch_attr_free(csch_attrib_t *a); /*** implementation ***/ RND_INLINE const char *csch_attrib_get_str(const csch_attribs_t *attribs, const char *key) { csch_attrib_t *a = csch_attrib_get(attribs, key); if ((a == NULL) || (a->deleted)) return NULL; return a->val; } RND_INLINE const vts0_t *csch_attrib_get_arr(const csch_attribs_t *attribs, const char *key) { csch_attrib_t *a = csch_attrib_get(attribs, key); if ((a == NULL) || (a->deleted) || (a->val != NULL)) return NULL; return &a->arr; } #endif