1 /* strcomp.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4 /*                                                                           */
5 /* Macro Assembler AS                                                        */
6 /*                                                                           */
7 /* Definition of a source line's component present after parsing             */
8 /*                                                                           */
9 /*****************************************************************************/
10 
11 #include "stdinc.h"
12 #include <string.h>
13 #include <ctype.h>
14 #include "datatypes.h"
15 #include "strutil.h"
16 #include "strcomp.h"
17 
StrCompAlloc(tStrComp * pComp)18 void StrCompAlloc(tStrComp *pComp)
19 {
20   pComp->Str = (char*)malloc(STRINGSIZE);
21   StrCompReset(pComp);
22 }
23 
StrCompReset(tStrComp * pComp)24 void StrCompReset(tStrComp *pComp)
25 {
26   LineCompReset(&pComp->Pos);
27   *pComp->Str = '\0';
28 }
29 
LineCompReset(tLineComp * pComp)30 void LineCompReset(tLineComp *pComp)
31 {
32   pComp->StartCol = -1;
33   pComp->Len = 0;
34 }
35 
StrCompFree(tStrComp * pComp)36 void StrCompFree(tStrComp *pComp)
37 {
38   LineCompReset(&pComp->Pos);
39   if (pComp->Str)
40     free(pComp->Str);
41   pComp->Str = NULL;
42 }
43 
44 /*!------------------------------------------------------------------------
45  * \fn     StrCompMkTemp(tStrComp *pComp, char *pStr)
46  * \brief  create a dummy StrComp from plain string
47  * \param  pComp comp to create
48  * \param  pStr string to use
49  * ------------------------------------------------------------------------ */
50 
StrCompMkTemp(tStrComp * pComp,char * pStr)51 void StrCompMkTemp(tStrComp *pComp, char *pStr)
52 {
53   LineCompReset(&pComp->Pos);
54   pComp->Str = pStr;
55 }
56 
57 /*!------------------------------------------------------------------------
58  * \fn     StrCompRefRight(tStrComp *pDest, const tStrComp *pSrc, int StartOffs)
59  * \brief  create a right-aligned substring component of string component (no copy)
60  * \param  pDest destination component
61  * \param  pSrc source component
62  * \param  StartOffs how many characters to omit at the left
63  * ------------------------------------------------------------------------ */
64 
StrCompRefRight(tStrComp * pDest,const tStrComp * pSrc,int StartOffs)65 void StrCompRefRight(tStrComp *pDest, const tStrComp *pSrc, int StartOffs)
66 {
67   pDest->Str = pSrc->Str + StartOffs;
68   pDest->Pos.StartCol = pSrc->Pos.StartCol + StartOffs;
69   pDest->Pos.Len = pSrc->Pos.Len - StartOffs;
70 }
71 
72 /*!------------------------------------------------------------------------
73  * \fn     StrCompCopy(tStrComp *pDest, tStrComp *pSrc)
74  * \brief  copy string component
75  * \param  pDest destination component
76  * \param  pSrc source component
77  * ------------------------------------------------------------------------ */
78 
StrCompCopy(tStrComp * pDest,const tStrComp * pSrc)79 void StrCompCopy(tStrComp *pDest, const tStrComp *pSrc)
80 {
81   pDest->Pos = pSrc->Pos;
82   strcpy(pDest->Str, pSrc->Str);
83 }
84 
85 /*!------------------------------------------------------------------------
86  * \fn     StrCompCopySub(tStrComp *pDest, const tStrComp *pSrc, unsigned Start, unsigned Count)
87  * \brief  copy substring
88  * \param  pDest destination
89  * \param  pSrc source
90  * \param  Start start index to copy from
91  * \param  Count # of characters to copy
92  * ------------------------------------------------------------------------ */
93 
StrCompCopySub(tStrComp * pDest,const tStrComp * pSrc,unsigned Start,unsigned Count)94 void StrCompCopySub(tStrComp *pDest, const tStrComp *pSrc, unsigned Start, unsigned Count)
95 {
96   unsigned l = strlen(pSrc->Str);
97 
98   if (Start >= l)
99     Count = 0;
100   else if (Start + Count > l)
101     Count = l - Start;
102   memcpy(pDest->Str, pSrc->Str + Start, Count);
103   pDest->Str[Count] = '\0';
104   pDest->Pos.StartCol = pSrc->Pos.StartCol + Start;
105   pDest->Pos.Len = Count;
106 }
107 
108 /*!------------------------------------------------------------------------
109  * \fn     StrCompSplitRight(tStrComp *pSrc, tStrComp *pDest, char *pSrcSplitPos)
110  * \brief  split off another component at the right of the source
111  * \param  pSrc source to split off
112  * \param  pDest where to put part splitted off
113  * \param  pSrcSplitPos split position (not included in source or dest any more)
114  * ------------------------------------------------------------------------ */
115 
StrCompSplitRight(tStrComp * pSrc,tStrComp * pDest,char * pSrcSplitPos)116 void StrCompSplitRight(tStrComp *pSrc, tStrComp *pDest, char *pSrcSplitPos)
117 {
118   strcpy(pDest->Str, pSrcSplitPos + 1);
119   pDest->Pos.StartCol = pSrc->Pos.StartCol + pSrcSplitPos + 1 - pSrc->Str;
120   pDest->Pos.Len = strlen(pDest->Str);
121   *pSrcSplitPos = '\0';
122   pSrc->Pos.Len = pSrcSplitPos - pSrc->Str;
123 }
124 
125 /*!------------------------------------------------------------------------
126  * \fn     StrCompSplitLeft(tStrComp *pSrc, tStrComp *pDest, char *pSrcSplitPos)
127  * \brief  split off another component at the left of the source
128  * \param  pSrc source to split off
129  * \param  pDest where to put part splitted off
130  * \param  pSrcSplitPos split position (not included in source or dest any more)
131  * ------------------------------------------------------------------------ */
132 
StrCompSplitLeft(tStrComp * pSrc,tStrComp * pDest,char * pSrcSplitPos)133 void StrCompSplitLeft(tStrComp *pSrc, tStrComp *pDest, char *pSrcSplitPos)
134 {
135   *pSrcSplitPos = '\0';
136   strcpy(pDest->Str, pSrc->Str);
137   pDest->Pos.StartCol = pSrc->Pos.StartCol;
138   pDest->Pos.Len = pSrcSplitPos - pSrc->Str;
139   strmov(pSrc->Str, pSrcSplitPos + 1);
140   pSrc->Pos.StartCol += pSrcSplitPos - pSrc->Str + 1;
141   pSrc->Pos.Len = strlen(pSrc->Str);
142 }
143 
StrCompSplitCopy(tStrComp * pLeft,tStrComp * pRight,const tStrComp * pSrc,char * pSplitPos)144 void StrCompSplitCopy(tStrComp *pLeft, tStrComp *pRight, const tStrComp *pSrc, char *pSplitPos)
145 {
146   pLeft->Pos.StartCol = pSrc->Pos.StartCol;
147   pLeft->Pos.Len = pSplitPos - pSrc->Str;
148   memmove(pLeft->Str, pSrc->Str, pLeft->Pos.Len);
149   pLeft->Str[pLeft->Pos.Len] = '\0';
150 
151   pRight->Pos.StartCol = pSrc->Pos.StartCol + (pLeft->Pos.Len + 1);
152   pRight->Pos.Len = pSrc->Pos.Len - (pLeft->Pos.Len + 1);
153   strcpy(pRight->Str, pSplitPos + 1);
154 }
155 
StrCompSplitRef(tStrComp * pLeft,tStrComp * pRight,const tStrComp * pSrc,char * pSplitPos)156 char StrCompSplitRef(tStrComp *pLeft, tStrComp *pRight, const tStrComp *pSrc, char *pSplitPos)
157 {
158   char Old = *pSplitPos;
159   /* save because pLeft and pSrc might be equal */
160   tLineComp SrcPos = pSrc->Pos;
161 
162   *pSplitPos = '\0';
163   pLeft->Str = pSrc->Str;
164   pLeft->Pos.StartCol = SrcPos.StartCol;
165   pLeft->Pos.Len = pSplitPos - pLeft->Str;
166   pRight->Str = pSrc->Str + (pLeft->Pos.Len + 1);
167   pRight->Pos.StartCol = SrcPos.StartCol + (pLeft->Pos.Len + 1);
168   pRight->Pos.Len = SrcPos.Len - (pLeft->Pos.Len + 1);
169 
170   return Old;
171 }
172 
173 /*!------------------------------------------------------------------------
174  * \fn     KillPrefBlanksStrComp(struct sStrComp *pComp)
175  * \brief  remove leading spaces on string component
176  * \param  pComp component to handle
177  * ------------------------------------------------------------------------ */
178 
KillPrefBlanksStrComp(struct sStrComp * pComp)179 void KillPrefBlanksStrComp(struct sStrComp *pComp)
180 {
181   int Delta = KillPrefBlanks(pComp->Str);
182   pComp->Pos.StartCol += Delta;
183   pComp->Pos.Len -= Delta;
184 }
185 
186 /*!------------------------------------------------------------------------
187  * \fn     KillPrefBlanksStrCompRef(struct sStrComp *pComp)
188  * \brief  remove leading spaces on string component by inc'ing pointer
189  * \param  pComp component to handle
190  * ------------------------------------------------------------------------ */
191 
KillPrefBlanksStrCompRef(struct sStrComp * pComp)192 void KillPrefBlanksStrCompRef(struct sStrComp *pComp)
193 {
194   while (isspace(*pComp->Str))
195   {
196     pComp->Str++;
197     pComp->Pos.StartCol++;
198     pComp->Pos.Len--;
199   }
200 }
201 
202 /*!------------------------------------------------------------------------
203  * \fn     KillPostBlanksStrComp(struct sStrComp *pComp)
204  * \brief  remove trailing spaces on string component
205  * \param  pComp component to handle
206  * ------------------------------------------------------------------------ */
207 
KillPostBlanksStrComp(struct sStrComp * pComp)208 void KillPostBlanksStrComp(struct sStrComp *pComp)
209 {
210   pComp->Pos.Len -= KillPostBlanks(pComp->Str);
211 }
212 
213 /*!------------------------------------------------------------------------
214  * \fn     StrCompShorten(struct sStrComp *pComp, int Delta)
215  * \brief  shorten string component by n characters
216  * \param  pComp component to shorten
217  * \param  Delta # of characters to chop off (no checks!)
218  * ------------------------------------------------------------------------ */
219 
StrCompShorten(struct sStrComp * pComp,int Delta)220 void StrCompShorten(struct sStrComp *pComp, int Delta)
221 {
222   pComp->Str[strlen(pComp->Str) - Delta] = '\0';
223   pComp->Pos.Len -= Delta;
224 }
225 
226 /*!------------------------------------------------------------------------
227  * \fn     StrCompCutLeft(struct sStrComp *pComp, int Delta)
228  * \brief  remove n characters at start of component
229  * \param  pComp component to shorten
230  * \param  Delta # of characters to cut off
231  * \return actual # of characters cut off
232  * ------------------------------------------------------------------------ */
233 
StrCompCutLeft(struct sStrComp * pComp,int Delta)234 int StrCompCutLeft(struct sStrComp *pComp, int Delta)
235 {
236   int len = strlen(pComp->Str);
237 
238   if (Delta > len)
239     Delta = len;
240   if (Delta > (int)pComp->Pos.Len)
241     Delta = pComp->Pos.Len;
242   strmov(pComp->Str, pComp->Str + Delta);
243   pComp->Pos.StartCol += Delta;
244   pComp->Pos.Len -= Delta;
245   return Delta;
246 }
247 
248 /*!------------------------------------------------------------------------
249  * \fn     StrCompIncRefLeft(struct sStrComp *pComp, int Delta)
250  * \brief  move start of component by n characters
251  * \param  pComp component to shorten
252  * \param  Delta # of characters to move by (no checks!)
253  * ------------------------------------------------------------------------ */
254 
StrCompIncRefLeft(struct sStrComp * pComp,int Delta)255 void StrCompIncRefLeft(struct sStrComp *pComp, int Delta)
256 {
257   pComp->Str += Delta;
258   pComp->Pos.StartCol += Delta;
259   pComp->Pos.Len -= Delta;
260 }
261 
262 /*!------------------------------------------------------------------------
263  * \fn     DumpStrComp(const char *pTitle, const struct sStrComp *pComp)
264  * \brief  debug dump of component
265  * \param  pTitle description of component
266  * \param  pComp component to dump
267  * ------------------------------------------------------------------------ */
268 
DumpStrComp(const char * pTitle,const struct sStrComp * pComp)269 void DumpStrComp(const char *pTitle, const struct sStrComp *pComp)
270 {
271   fprintf(stderr, "%s: @ col %u len %u '%s'\n", pTitle, pComp->Pos.StartCol, pComp->Pos.Len, pComp->Str);
272 }
273