1 /*
2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 University of Virginia,
4 **         Massachusetts Institute of Technology
5 **
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
10 **
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 ** General Public License for more details.
15 **
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
19 **
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
23 */
24 /*
25 ** structNames.c
26 **
27 ** Hacks to fit tags into the same namespace.
28 */
29 
30 # include "splintMacros.nf"
31 # include "basic.h"
32 # include "structNames.h"
33 
34 /*@constant char MARKCHAR_STRUCT; @*/
35 # define MARKCHAR_STRUCT '@'
36 
37 /*@constant char MARKCHAR_UNION; @*/
38 # define MARKCHAR_UNION  '$'
39 
40 /*@constant char MARKCHAR_ENUM; @*/
41 # define MARKCHAR_ENUM   '&'
42 
43 /*@constant char MARKCHAR_PARAM; @*/
44 # define MARKCHAR_PARAM  '%'
45 
plainTagName(cstring s)46 /*@observer@*/ cstring plainTagName (cstring s)
47 {
48   llassert (!isFakeTag (s));
49 
50   return cstring_suffix (s, 1);
51 }
52 
fixTagName(cstring s)53 /*@only@*/ cstring fixTagName (cstring s)
54 {
55   if (isFakeTag (s))
56     {
57       switch (cstring_firstChar (s))
58 	{
59 	case MARKCHAR_STRUCT: return (cstring_makeLiteral ("struct"));
60 	case MARKCHAR_UNION:  return (cstring_makeLiteral ("union"));
61 	case MARKCHAR_ENUM:   return (cstring_makeLiteral ("enum"));
62 	default:         return (message ("<bad tag name: %s>", s));
63 	}
64     }
65   else
66     {
67       if (cstring_isDefined (s)) {
68 	switch (cstring_firstChar (s))
69 	  {
70 	  case MARKCHAR_STRUCT:
71 	    return (message ("struct %s", cstring_suffix (s, 1)));
72 	  case MARKCHAR_UNION:
73 	    return (message ("union %s", cstring_suffix (s, 1)));
74 	  case MARKCHAR_ENUM:
75 	    return (message ("enum %s", cstring_suffix (s, 1)));
76 	    BADDEFAULT;
77 	  }
78       } else {
79 	return (cstring_makeLiteral ("<missing tag name>"));
80       }
81     }
82 }
83 
makeParam(cstring s)84 cstring makeParam (cstring s)
85 {
86   if (cstring_length(s) > 0 && cstring_firstChar (s) == MARKCHAR_PARAM)
87     {
88       llbug (message ("makeParam: %s\n", s));
89     }
90 
91   if (cstring_isUndefined (s))
92     {
93       return cstring_undefined;
94     }
95 
96   return (cstring_prependChar (MARKCHAR_PARAM, s));
97 }
98 
fixParamName(cstring s)99 /*@observer@*/ cstring fixParamName (cstring s)
100 {
101   if (cstring_length(s) < 1)
102     {
103       return cstring_undefined;
104     }
105 
106   if (cstring_firstChar (s) != MARKCHAR_PARAM)
107     {
108       llbug (message ("fixParamName (no #): %s", s));
109     }
110 
111   return (cstring_suffix (s, 1));
112 }
113 
makeStruct(cstring s)114 cstring makeStruct (cstring s)
115 {
116   if (cstring_firstChar (s) == '@')
117     {
118       llbug (message ("makeStruct: %s\n", s));
119     }
120 
121   return (cstring_prependChar (MARKCHAR_STRUCT, s));
122 }
123 
makeUnion(cstring s)124 cstring makeUnion (cstring s)
125 {
126   return (cstring_prependChar (MARKCHAR_UNION, s));
127 }
128 
makeEnum(cstring s)129 cstring makeEnum (cstring s)
130 {
131   return (cstring_prependChar (MARKCHAR_ENUM, s));
132 }
133 
134 static unsigned int tagno = 1;
135 
setTagNo(unsigned int n)136 void setTagNo (unsigned int n)
137 {
138   if (n > tagno)
139     tagno = n;
140 }
141 
isFakeTag(cstring s)142 bool isFakeTag (cstring s)
143 {
144   size_t length = cstring_length (s);
145 
146   return ((length >= 1 && cstring_firstChar (s) == '!')
147 	  || (length >= 2 && cstring_getChar (s, 2) == '!'));
148 }
149 
fakeTag()150 cstring fakeTag ()
151 {
152   tagno++;
153 
154   return (message ("!%u", tagno));
155 }
156 
157 
158 
159 
160 
161