1 /****************************************************************************/
2 /*                                                                          */
3 /*  Module:         jamnote.c                                               */
4 /*                                                                          */
5 /*                  Copyright (C) Altera Corporation 1997                   */
6 /*                                                                          */
7 /*  Description:    Functions to extract NOTE fields from an JAM program    */
8 /*                                                                          */
9 /****************************************************************************/
10 
11 #include "jamexprt.h"
12 #include "jamdefs.h"
13 #include "jamexec.h"
14 #include "jamutil.h"
15 #include <stdint.h>
16 
17 BOOL urj_jam_get_note_key (char *statement_buffer, int32_t *key_begin,
18                        int32_t *key_end);
19 BOOL urj_jam_get_note_value (char *statement_buffer, int32_t *value_begin,
20                          int32_t *value_end);
21 int urj_jam_get_note (char *program, int32_t program_size, int32_t *offset,
22                   char *key, char *value, int length);
23 
24 
25 /****************************************************************************/
26 /*                                                                          */
27 
urj_jam_get_note_key(char * statement_buffer,int32_t * key_begin,int32_t * key_end)28 BOOL urj_jam_get_note_key
29     (char *statement_buffer, int32_t *key_begin, int32_t *key_end)
30 /*                                                                          */
31 /*  Description:    This function finds the note key name in the statement  */
32 /*                  buffer and returns the start and end offsets            */
33 /*                                                                          */
34 /*  Returns:        true for success, false if key not found                */
35 /*                                                                          */
36 /****************************************************************************/
37 {
38     int index = 0;
39     BOOL quoted_string = false;
40 
41     index = urj_jam_skip_instruction_name (statement_buffer);
42 
43     /*
44      *      Check if key string has quotes
45      */
46     if ((statement_buffer[index] == JAMC_QUOTE_CHAR) &&
47         (index < JAMC_MAX_STATEMENT_LENGTH))
48     {
49         quoted_string = true;
50         ++index;
51     }
52 
53     /*
54      *      Mark the beginning of the key string
55      */
56     *key_begin = index;
57 
58     /*
59      *      Now find the end of the key string
60      */
61     if (quoted_string)
62     {
63         /* look for matching quote */
64         while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
65                (statement_buffer[index] != JAMC_QUOTE_CHAR) &&
66                (index < JAMC_MAX_STATEMENT_LENGTH))
67         {
68             ++index;
69         }
70 
71         if (statement_buffer[index] == JAMC_QUOTE_CHAR)
72         {
73             *key_end = index;
74         }
75     }
76     else
77     {
78         /* look for white space */
79         while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
80                (!isspace (statement_buffer[index])) &&
81                (index < JAMC_MAX_STATEMENT_LENGTH))
82         {
83             ++index;            /* skip over white space */
84         }
85 
86         if (isspace (statement_buffer[index]))
87         {
88             *key_end = index;
89         }
90     }
91 
92     return (*key_end > *key_begin) ? true : false;
93 }
94 
95 /****************************************************************************/
96 /*                                                                          */
97 
urj_jam_get_note_value(char * statement_buffer,int32_t * value_begin,int32_t * value_end)98 BOOL urj_jam_get_note_value
99     (char *statement_buffer, int32_t *value_begin, int32_t *value_end)
100 /*                                                                          */
101 /*  Description:    Finds the value field of a NOTE.  Could be enclosed in  */
102 /*                  quotation marks, or could not be.  Must be followed by  */
103 /*                  a semicolon.                                            */
104 /*                                                                          */
105 /*  Returns:        true for success, false for failure                     */
106 /*                                                                          */
107 /****************************************************************************/
108 {
109     int index = 0;
110     BOOL quoted_string = false;
111     BOOL status = false;
112 
113     /* skip over white space */
114     while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
115            (isspace (statement_buffer[index])) &&
116            (index < JAMC_MAX_STATEMENT_LENGTH))
117     {
118         ++index;
119     }
120 
121     /*
122      *      Check if value string has quotes
123      */
124     if ((statement_buffer[index] == JAMC_QUOTE_CHAR) &&
125         (index < JAMC_MAX_STATEMENT_LENGTH))
126     {
127         quoted_string = true;
128         ++index;
129     }
130 
131     /*
132      *      Mark the beginning of the value string
133      */
134     *value_begin = index;
135 
136     /*
137      *      Now find the end of the value string
138      */
139     if (quoted_string)
140     {
141         /* look for matching quote */
142         while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
143                (statement_buffer[index] != JAMC_QUOTE_CHAR) &&
144                (index < JAMC_MAX_STATEMENT_LENGTH))
145         {
146             ++index;
147         }
148 
149         if (statement_buffer[index] == JAMC_QUOTE_CHAR)
150         {
151             *value_end = index;
152             status = true;
153             ++index;
154         }
155     }
156     else
157     {
158         /* look for white space or semicolon */
159         while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
160                (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
161                (!isspace (statement_buffer[index])) &&
162                (index < JAMC_MAX_STATEMENT_LENGTH))
163         {
164             ++index;            /* skip over non-white space */
165         }
166 
167         if ((statement_buffer[index] == JAMC_SEMICOLON_CHAR) ||
168             (isspace (statement_buffer[index])))
169         {
170             *value_end = index;
171             status = true;
172         }
173     }
174 
175     if (status)
176     {
177         while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
178                (isspace (statement_buffer[index])) &&
179                (index < JAMC_MAX_STATEMENT_LENGTH))
180         {
181             ++index;            /* skip over white space */
182         }
183 
184         /*
185          *      Next character must be semicolon
186          */
187         if (statement_buffer[index] != JAMC_SEMICOLON_CHAR)
188         {
189             status = false;
190         }
191     }
192 
193     return status;
194 }
195 
196 /****************************************************************************/
197 /*                                                                          */
198 
urj_jam_get_note(char * program,int32_t program_size,int32_t * offset,char * key,char * value,int length)199 JAM_RETURN_TYPE urj_jam_get_note
200     (char *program,
201      int32_t program_size,
202      int32_t *offset, char *key, char *value, int length)
203 /*                                                                          */
204 /*  Description:    Gets key and value of NOTE fields in the JAM file.      */
205 /*                  Can be called in two modes:  if offset pointer is NULL, */
206 /*                  then the function searches for note fields which match  */
207 /*                  the key string provided.  If offset is not NULL, then   */
208 /*                  the function finds the next note field of any key,      */
209 /*                  starting at the offset specified by the offset pointer. */
210 /*                                                                          */
211 /*  Returns:        JAMC_SUCCESS for success, else appropriate error code   */
212 /*                                                                          */
213 /****************************************************************************/
214 {
215     JAM_RETURN_TYPE status = JAMC_SUCCESS;
216     char statement_buffer[JAMC_MAX_STATEMENT_LENGTH + 1];
217     char label_buffer[JAMC_MAX_NAME_LENGTH + 1];
218     JAME_INSTRUCTION instruction = JAM_ILLEGAL_INSTR;
219     int32_t key_begin = 0L;
220     int32_t key_end = 0L;
221     int32_t value_begin = 0L;
222     int32_t value_end = 0L;
223     BOOL done = false;
224     char *tmp_program = urj_jam_program;
225     int32_t tmp_program_size = urj_jam_program_size;
226     int32_t tmp_current_file_position = urj_jam_current_file_position;
227     int32_t tmp_current_statement_position = urj_jam_current_statement_position;
228     int32_t tmp_next_statement_position = urj_jam_next_statement_position;
229 
230     urj_jam_program = program;
231     urj_jam_program_size = program_size;
232 
233     urj_jam_current_statement_position = 0L;
234     urj_jam_next_statement_position = 0L;
235 
236     if (offset == NULL)
237     {
238         /*
239          *      We will search for the first note with a specific key, and
240          *      return only the value
241          */
242         status = urj_jam_seek (0L);
243         urj_jam_current_file_position = 0L;
244     }
245     else
246     {
247         /*
248          *      We will search for the next note, regardless of the key, and
249          *      return both the value and the key
250          */
251         status = urj_jam_seek (*offset);
252         urj_jam_current_file_position = *offset;
253     }
254 
255     /*
256      *      Get program statements and look for NOTE statements
257      */
258     while ((!done) && (status == JAMC_SUCCESS))
259     {
260         status = urj_jam_get_statement (statement_buffer, label_buffer);
261 
262         if (status == JAMC_SUCCESS)
263         {
264             instruction = urj_jam_get_instruction (statement_buffer);
265 
266             if (instruction == JAM_NOTE_INSTR)
267             {
268                 if (urj_jam_get_note_key (statement_buffer, &key_begin, &key_end))
269                 {
270                     statement_buffer[key_end] = JAMC_NULL_CHAR;
271 
272                     if ((offset != NULL)
273                         || (strcasecmp (key, &statement_buffer[key_begin]) ==
274                             0))
275                     {
276                         if (urj_jam_get_note_value
277                             (&statement_buffer[key_end + 1], &value_begin,
278                              &value_end))
279                         {
280                             done = true;
281                             value_begin += (key_end + 1);
282                             value_end += (key_end + 1);
283                             statement_buffer[value_end] = JAMC_NULL_CHAR;
284 
285                             if (offset != NULL)
286                             {
287                                 *offset = urj_jam_current_file_position;
288                             }
289                         }
290                         else
291                         {
292                             status = JAMC_SYNTAX_ERROR;
293                         }
294                     }
295                 }
296                 else
297                 {
298                     status = JAMC_SYNTAX_ERROR;
299                 }
300             }
301         }
302     }
303 
304     /*
305      *      Copy the key and value strings into buffers provided
306      */
307     if (done && (status == JAMC_SUCCESS))
308     {
309         if (offset != NULL)
310         {
311             /* only copy the key string if we were looking for all NOTEs */
312             strncpy (key, &statement_buffer[key_begin],
313                          JAMC_MAX_NAME_LENGTH);
314         }
315         strncpy (value, &statement_buffer[value_begin], length);
316     }
317 
318     urj_jam_program = tmp_program;
319     urj_jam_program_size = tmp_program_size;
320     urj_jam_current_file_position = tmp_current_file_position;
321     urj_jam_current_statement_position = tmp_current_statement_position;
322     urj_jam_next_statement_position = tmp_next_statement_position;
323 
324     return status;
325 }
326