6 * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
7 * Copyright (C) 2009, 2010, MinGW Project
10 * A simple lexical analyser for decomposing package archive names into their
11 * constituent components. It implements the schema:--
13 * <archive-name> ::= <package-id>[["-"<system-id>]][[-<status>]]"-"<type-id>
15 * <package-id> ::= <package-name>"-"<version>[["-"<build-id>]]
16 * <system-id> ::= <system-name>[["-"<version>[["-"<build-id>]]]]
17 * <type-id> ::= <component-id>"."<format-type>[["."<compression-type>]]
19 * <package-name> ::= !"-"{!"-"}
21 * <version> ::= <major>[["."<minor>[["."<patchlevel>]]]]
23 * <major> ::= "0".."9"{"0".."9"}
24 * <minor> ::= "0".."9"{"0".."9"}[[<suffix>]]
25 * <patchlevel> ::= "0".."9"{"0".."9"}[[<suffix>]]
26 * <suffix> ::= {!("0".."9"|"-"|".")}
28 * <build-id> ::= <datestamp>|<serial-number>{"-"<serial-number>}
30 * <serial-number> ::= "0".."9"{"0".."9"}
31 * <datestamp> ::= <serial-number> ; nominally 8 digit date as YYYYMMDD
32 * ; (currently unenforced, however)
34 * <system-name> ::= !("0".."9"|"-"|"."){!("-"|".")}
36 * <status> ::= ("alpha"|"beta"|"stable")[[-<build-id>]]
38 * <component-id> ::= <component-class>[["-"<component-version>]]
40 * <component-class> ::= !("0".."9"|"-"|"."){!("-"|".")}
41 * <component-version> ::= "0".."9"{!("-"|".")}
43 * <format-type> ::= !("-"|"."){!("-"|".")}
44 * <compression-type> ::= !("-"|"."){!("-"|".")}
48 * <format-type> is expected to take one of the nominal values from the set
49 * "exe"|"tar"|"zip"; however, this is not enforced.
51 * <compression-type> is expected to take one of the nominal values from the
52 * set "bz2"|"gz"|"lzma"; however, this is similarly not enforced.
54 * Additionally, "?" is used as a sentinel, and is not permitted *anywhere*
55 * in <archive-name>; (possibly something like ASCII <ETX> would be a more
56 * useful choice for this purpose.
59 * This is free software. Permission is granted to copy, modify and
60 * redistribute this software, under the provisions of the GNU General
61 * Public License, Version 3, (or, at your option, any later version),
62 * as published by the Free Software Foundation; see the file COPYING
63 * for licensing details.
65 * Note, in particular, that this software is provided "as is", in the
66 * hope that it may prove useful, but WITHOUT WARRANTY OF ANY KIND; not
67 * even an implied WARRANTY OF MERCHANTABILITY, nor of FITNESS FOR ANY
68 * PARTICULAR PURPOSE. Under no circumstances will the author, or the
69 * MinGW Project, accept liability for any damages, however caused,
70 * arising from the use of this software.
74 %option prefix="__pkginfo_"
75 %option case-insensitive
79 STATUS_KEYWORDS (alpha|beta|stable)
82 #define YY_DECL int yylex( int start, pkginfo_t signature, char *name )
86 static int index, mark, phase;
88 if( start == PACKAGE_NAME )
90 /* Initialise for new package archive name...
91 * Clear all `signature' array slots, and set up
92 * to capture the <package-name> element.
96 for( index = PACKAGE_NAME; index < PACKAGE_TAG_COUNT; index++ )
97 signature[index] = NULL;
99 signature[PACKAGE_NAME] = name;
103 * General case rule...
104 * Found the standard element separator, so initiate a transition.
111 /* General case rule...
112 * Matched an arbitrary sequence of non-separators, so mark them;
113 * they will be appended to the current element.
115 return mark += yyleng;
118 <TRANS>{STATUS_KEYWORDS}- {
120 * Transitional case rule...
121 * Identify a following package development <status> descriptor;
122 * revert to INITIAL state, to continue the <archive-name> scan.
125 if( index < PACKAGE_RELEASE_STATUS )
127 /* and, when the <status> descriptor is appropriately placed,
128 * set up `signature' storage to capture it, adjusting phase to
129 * detect a following <build-id>, (representing a release id).
132 signature[index = PACKAGE_RELEASE_STATUS] = name + mark + 1;
135 /* otherwise we simply ignore a misplaced <status> descriptor,
136 * but in either case, we continue the scan at the start of the
137 * apparent <status> descriptor, which has been detected.
143 <TRANS>([%&*]|[^-0-9.][^-.]+)(-[0-9][^-.]*){0,1}(\.[^-.]+){1,2}\? {
145 * Transitional case rule...
146 * Identify a following terminal <type-id> sequence; set up
147 * `signature' storage to capture it, and initiate FINAL phase
148 * of <archive-name> scan.
153 signature[index = PACKAGE_COMPONENT_CLASS] = name + mark;
157 <TRANS>([%&*][.-])|([0-9]+[.-]) {
159 * Transitional case rule...
160 * Found a purely numeric following element, such as a <major>
161 * version number field, or a <serial-number>.
166 /* For a version number element,
167 * terminate the preceding name element, and set up the
168 * `signature' table to capture the version number.
171 signature[++index] = name + mark + 1;
173 /* For any other numeric element class,
174 * simply advance the position marker, and leave the content
175 * to be retrieved by a general (INITIAL) case rule.
183 * Transitional case rule...
184 * Handle any other non-specific element type,
185 * found after an element delimiter.
190 /* When processing a <version> or <build-id> element,
196 * ...and if we haven't reached a <build-id>, then
197 * there isn't one here; leave its pointer unassigned.
201 /* Save pointer to next element,
202 * (which should be <subsystem-name>),
203 * and reset phase accordingly.
205 signature[++index] = name + mark + 1;
208 /* Update element marker, and leave content to be scanned
209 * on return to the INITIAL state.
217 * Wrap up processing rule...
218 * Found a "." element separator, so move on to capture
219 * the next element of the <type-id>...
221 if( index < PACKAGE_COMPONENT_VERSION )
223 * ...omitting the <component-version>, which has either
224 * been captured already, or isn't present.
228 signature[++index] = name + mark;
234 * Wrap up processing rule...
235 * Found a "-" element separator...
237 if( index == PACKAGE_COMPONENT_CLASS )
239 /* ...this should occur only to separate
240 * the <component-version> from the <component-class>;
241 * in this case, terminate the <component-class>, and
242 * prepare to capture the <component-version>.
245 signature[++index] = name + mark;
252 * Wrap up processing rule...
253 * Found element content; adjust mark to its end.
255 return mark += yyleng;
260 * Wrap up processing rule...
261 * Found the sentinel for the end of <archive-name>;
262 * delete it, and we should be done.
269 void *get_pkginfo( const char *name, pkginfo_t signature )
271 if( (*signature = malloc( strlen( name ) + 2)) != NULL )
273 int start = PACKAGE_NAME;
274 sprintf( *signature, "%s?", name );
275 yy_scan_string( *signature );
276 while( (start = yylex( start, signature, *signature )) > 0 )
278 yy_delete_buffer( YY_CURRENT_BUFFER );
283 /* $RCSfile$: end of file */