/* $Id$ */ /******************************************************************** * Copyright (c) 1995 - 2004, EMBL, Peter Keller * * CCIF: a library to access and output data conforming to the * CIF (Crystallographic Information File) and mmCIF (Macromolecular * CIF) specifications, and other related specifications. * * This library is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 3, modified in accordance with the provisions of the * license to address the requirements of UK law. * * You should have received a copy of the modified GNU Lesser General * Public License along with this library. If not, copies may be * downloaded from http://www.ccp4.ac.uk/ccp4license.php * * 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 Lesser General Public License for more details. * ********************************************************************/ /* Structure for tokens (based originally on the charptr code of PCCTS */ #ifndef ZZCHARPTR_H #define ZZCHARPTR_H /* used to store status of text member of attribute */ enum attrib_stat { unknown = 0, mapped, /* address of text refers to position in file held in memory, * or an otherwise un-free()-able address */ constant, /* struct attrib itself, as well as text, should never be free()'d */ input, /* calloc'd during lex-ing of an input file */ output, /* calloc'd to hold a value generated in an application */ error /* as 'output', but token does not conform to a STAR text type */ }; typedef struct attrib { int col,line,length, /* Length is number of columns, counting '\t' as 8 spaces, so it is not * the same as strlen(text) */ output_line, nnodes; /* Number of AST nodes which point at this Attrib. * When this is zero, we can free() the attrib, status * permitting */ char *text; /* Point at text. !!!IMPORTANT!!! RESIST ALL TEMPTATION TO POINT * MULTIPLE ATTRIBUTES AT THE SAME BIT OF TEXT, except for status==mapped * or status==constant. Otherwise, call zzcr_attr() (from C code) or use * a $[...] constructor (from an ANTLR grammar). The attrib structure is * the fundemental lexical entity, not the text to which it points. Ignoring * this will almost certainly create massive memory leaks! */ struct attrib *prev, *next, *err; /* err is used to create a linked list of attributes * during output, which are known to be in error */ enum attrib_stat status; #if _USE_MMAP == 1 struct _map_file_record *map_file; #endif } *Attrib ; /* When an Attrib structure has its prev and next pointers set, it must never be * freed, or the Attrib used as an rvalue, otherwise the prev and next pointers * will no longer be valid. * * Always use embedded actions of the form << ... $0 = $1; ....>>, never * << ... *($0) = *($1); ....>>. * With this in mind, don't allocate memory for the initialisation of $0: */ #define zzdef0(a) *(a) = NULL; /* Has a been set since it was zzdef0'd? */ #define zzif(a) a /* Do not assign zzd_attr - we don't want struct attrib's to be freed simply when a pointer * to one goes out of scope in ANTLR */ /* a is (Attrib *) */ #define zzfr_attr(a) if ( *(a) && (*(a))->nnodes == 0 && (*(a))->status != constant ) { \ if ( (*(a))->status != mapped ) \ free ( (*(a))->text); \ if ( (*(a))->prev ) \ (*(a))->prev->next = NULL; \ if ( (*(a))->next ) \ (*(a))->next->prev = NULL; \ free ( (*(a)) ); \ zzdef0(a) \ } /* Be careful with this macro! If multiple AST nodes are pointing at the * Attrib, you will change all of their values! If this is not what you * want, use zzcr_ast instead */ /* Replace text of an existing attribute. Use like zzcr_attr. */ #define zzrepl_attr(a, tok, t) if ( a ) { \ char *text = ccif_strdup(t); \ if ( (a)->text && (a)->status != mapped && (a)->status != constant ) \ free( (a)->text ); \ (a)->text = text; \ (a)->status = output; \ } \ else \ zzcr_attr(&a, tok, t); #if defined __STDC__ || _MSC_VER extern void zzcr_attr(Attrib *a ,int token ,char * text); #endif #endif