~ubuntu-branches/ubuntu/trusty/eclipse-linuxtools/trusty

« back to all changes in this revision

Viewing changes to rpm/org.eclipse.linuxtools.rpm.ui.editor/src/org/eclipse/linuxtools/rpm/ui/editor/parser/SpecfileParser.java

  • Committer: Package Import Robot
  • Author(s): Jakub Adam
  • Date: 2012-06-29 12:07:30 UTC
  • Revision ID: package-import@ubuntu.com-20120629120730-bfri1xys1i71dpn6
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*******************************************************************************
 
2
 * Copyright (c) 2007, 2009 Red Hat, Inc.
 
3
 * All rights reserved. This program and the accompanying materials
 
4
 * are made available under the terms of the Eclipse Public License v1.0
 
5
 * which accompanies this distribution, and is available at
 
6
 * http://www.eclipse.org/legal/epl-v10.html
 
7
 *
 
8
 * Contributors:
 
9
 *    Red Hat - initial API and implementation
 
10
 *    Alphonse Van Assche
 
11
 *******************************************************************************/
 
12
 
 
13
package org.eclipse.linuxtools.rpm.ui.editor.parser;
 
14
 
 
15
import static org.eclipse.linuxtools.internal.rpm.ui.editor.RpmSections.BUILD_SECTION;
 
16
import static org.eclipse.linuxtools.internal.rpm.ui.editor.RpmSections.CHANGELOG_SECTION;
 
17
import static org.eclipse.linuxtools.internal.rpm.ui.editor.RpmSections.CLEAN_SECTION;
 
18
import static org.eclipse.linuxtools.internal.rpm.ui.editor.RpmSections.DESCRIPTION_SECTION;
 
19
import static org.eclipse.linuxtools.internal.rpm.ui.editor.RpmSections.FILES_SECTION;
 
20
import static org.eclipse.linuxtools.internal.rpm.ui.editor.RpmSections.INSTALL_SECTION;
 
21
import static org.eclipse.linuxtools.internal.rpm.ui.editor.RpmSections.PACKAGE_SECTION;
 
22
import static org.eclipse.linuxtools.internal.rpm.ui.editor.RpmSections.POSTTRANS_SECTION;
 
23
import static org.eclipse.linuxtools.internal.rpm.ui.editor.RpmSections.POSTUN_SECTION;
 
24
import static org.eclipse.linuxtools.internal.rpm.ui.editor.RpmSections.POST_SECTION;
 
25
import static org.eclipse.linuxtools.internal.rpm.ui.editor.RpmSections.PREP_SECTION;
 
26
import static org.eclipse.linuxtools.internal.rpm.ui.editor.RpmSections.PRETRANS_SECTION;
 
27
import static org.eclipse.linuxtools.internal.rpm.ui.editor.RpmSections.PREUN_SECTION;
 
28
import static org.eclipse.linuxtools.internal.rpm.ui.editor.RpmSections.PRE_SECTION;
 
29
 
 
30
import java.io.IOException;
 
31
import java.io.LineNumberReader;
 
32
import java.io.StringReader;
 
33
import java.util.Arrays;
 
34
import java.util.Iterator;
 
35
import java.util.List;
 
36
 
 
37
import org.eclipse.core.resources.IMarker;
 
38
import org.eclipse.jface.preference.IPreferenceStore;
 
39
import org.eclipse.jface.text.Document;
 
40
import org.eclipse.jface.text.IDocument;
 
41
import org.eclipse.linuxtools.internal.rpm.ui.editor.Activator;
 
42
import org.eclipse.linuxtools.internal.rpm.ui.editor.ISpecfileSpecialSymbols;
 
43
import org.eclipse.linuxtools.internal.rpm.ui.editor.RpmTags;
 
44
import org.eclipse.linuxtools.internal.rpm.ui.editor.SpecfileLog;
 
45
import org.eclipse.linuxtools.internal.rpm.ui.editor.parser.Messages;
 
46
import org.eclipse.linuxtools.internal.rpm.ui.editor.parser.SpecfileParseException;
 
47
import org.eclipse.linuxtools.internal.rpm.ui.editor.parser.SpecfilePatchMacro;
 
48
import org.eclipse.linuxtools.internal.rpm.ui.editor.parser.SpecfileSource;
 
49
import org.eclipse.linuxtools.internal.rpm.ui.editor.parser.SpecfileSource.SourceType;
 
50
import org.eclipse.linuxtools.internal.rpm.ui.editor.parser.SpecfileTag;
 
51
import org.eclipse.linuxtools.internal.rpm.ui.editor.preferences.PreferenceConstants;
 
52
import org.eclipse.linuxtools.rpm.ui.editor.markers.SpecfileErrorHandler;
 
53
import org.eclipse.linuxtools.rpm.ui.editor.markers.SpecfileTaskHandler;
 
54
 
 
55
public class SpecfileParser {
 
56
 
 
57
        private static final String DEFINE_SEPARATOR = ":"; //$NON-NLS-1$
 
58
 
 
59
        private static final String SPACE_REGEX = "\\s+"; //$NON-NLS-1$
 
60
 
 
61
        /**
 
62
         * These are SRPM-wide sections, and they also cannot have any flags like -n
 
63
         * or -f. Hence they are called simple. This is probably a misleading name
 
64
         * and it should be renamed to reflect that they are SRPM-wide sections.
 
65
         */
 
66
        public static final String[] simpleSections = { PREP_SECTION, BUILD_SECTION,
 
67
                        INSTALL_SECTION, CLEAN_SECTION, CHANGELOG_SECTION };
 
68
 
 
69
        /**
 
70
         * These are sections that apply to a particular sub-package (i.e. binary
 
71
         * RPM), including the main package. These can also have flags like -f or -n
 
72
         * appended to them, hence they are called complex. This should probably be
 
73
         * renamed to reflect that they are in fact per-RPM sections.
 
74
         */
 
75
        private static String[] complexSections = { PRETRANS_SECTION, PRE_SECTION,
 
76
                        PREUN_SECTION, POST_SECTION, POSTUN_SECTION, POSTTRANS_SECTION,
 
77
                        FILES_SECTION, PACKAGE_SECTION, DESCRIPTION_SECTION };
 
78
 
 
79
        private static String[] simpleDefinitions = { RpmTags.EPOCH, RpmTags.NAME,
 
80
                        RpmTags.VERSION, RpmTags.RELEASE, RpmTags.URL, RpmTags.BUILD_ARCH };
 
81
 
 
82
        private static String[] directValuesDefinitions = { RpmTags.LICENSE,
 
83
                        RpmTags.BUILD_ROOT };
 
84
        // Note that the ordering here should match that in
 
85
        // SpecfileSource#SOURCETYPE
 
86
        private static String[] complexDefinitions = { "Source", "Patch" }; //$NON-NLS-1$ //$NON-NLS-2$
 
87
 
 
88
        private static String[] packageLevelDefinitions = { RpmTags.SUMMARY,
 
89
                        RpmTags.GROUP, RpmTags.OBSOLETES, RpmTags.PROVIDES,
 
90
                        RpmTags.REQUIRES, RpmTags.REQUIRES_PRE, RpmTags.REQUIRES_POST,
 
91
                        RpmTags.REQUIRES_POSTUN };
 
92
 
 
93
        private SpecfileErrorHandler errorHandler;
 
94
        private SpecfileTaskHandler taskHandler;
 
95
        private IPreferenceStore store;
 
96
        private SpecfileSection lastSection;
 
97
        private SpecfilePackage activePackage;
 
98
 
 
99
        public SpecfileParser() {
 
100
                store = Activator.getDefault().getPreferenceStore();
 
101
        }
 
102
 
 
103
        public Specfile parse(IDocument specfileDocument) {
 
104
 
 
105
                // remove all existing markers, if a SpecfileErrorHandler is
 
106
                // instantiated.
 
107
                if (errorHandler != null)
 
108
                        errorHandler.removeExistingMarkers();
 
109
                if (taskHandler != null) {
 
110
                        taskHandler.removeExistingMarkers();
 
111
                }
 
112
                LineNumberReader reader = new LineNumberReader(new StringReader(
 
113
                                specfileDocument.get()));
 
114
                String line = ""; //$NON-NLS-1$
 
115
                int lineStartPosition = 0;
 
116
                Specfile specfile = new Specfile();
 
117
                specfile.setDocument(specfileDocument);
 
118
                try {
 
119
                        while ((line = reader.readLine()) != null) {
 
120
                                if (taskHandler != null) {
 
121
                                        generateTaskMarker(reader.getLineNumber() - 1, line);
 
122
                                }
 
123
                                // IDocument.getLine(#) is 0-indexed whereas
 
124
                                // reader.getLineNumber appears to be 1-indexed
 
125
                                SpecfileElement element = parseLine(line, specfile, reader
 
126
                                                .getLineNumber() - 1);
 
127
                                if (element != null) {
 
128
                                        element.setLineNumber(reader.getLineNumber() - 1);
 
129
                                        element.setLineStartPosition(lineStartPosition);
 
130
                                        element.setLineEndPosition(lineStartPosition
 
131
                                                        + line.length());
 
132
                                        if (element.getClass() == SpecfileTag.class) {
 
133
                                                SpecfileTag tag = (SpecfileTag) element;
 
134
                                                specfile.addDefine(tag);
 
135
                                        } else if ((element.getClass() == SpecfilePatchMacro.class)) {
 
136
                                                SpecfilePatchMacro thisPatchMacro = (SpecfilePatchMacro) element;
 
137
                                                if (thisPatchMacro != null) {
 
138
                                                        thisPatchMacro.setSpecfile(specfile);
 
139
                                                }
 
140
                                                SpecfileSource thisPatch = specfile
 
141
                                                                .getPatch(thisPatchMacro.getPatchNumber());
 
142
                                                if (thisPatch != null) {
 
143
                                                        thisPatch.addLineUsed(reader.getLineNumber() - 1);
 
144
                                                        thisPatch.setSpecfile(specfile);
 
145
                                                }
 
146
                                        } else if ((element.getClass() == SpecfileDefine.class)) {
 
147
                                                specfile.addDefine((SpecfileDefine) element);
 
148
                                        } else if ((element.getClass() == SpecfileSource.class)) {
 
149
                                                SpecfileSource source = (SpecfileSource) element;
 
150
 
 
151
                                                source.setLineNumber(reader.getLineNumber() - 1);
 
152
                                                if (source.getSourceType() == SpecfileSource.SourceType.SOURCE) {
 
153
                                                        specfile.addSource(source);
 
154
                                                } else {
 
155
                                                        specfile.addPatch(source);
 
156
                                                }
 
157
                                        }
 
158
                                }
 
159
                                // The +1 is for the line delimiter. FIXME: will we end up off
 
160
                                // by one on the last line?
 
161
                                lineStartPosition += line.length() + 1;
 
162
                        }
 
163
                } catch (IOException e) {
 
164
                        // FIXME
 
165
                        SpecfileLog.logError(e);
 
166
                }
 
167
                return specfile;
 
168
        }
 
169
 
 
170
        private void generateTaskMarker(int lineNumber, String line) {
 
171
                String[] taskTags = store.getString(PreferenceConstants.P_TASK_TAGS)
 
172
                                .split(";"); //$NON-NLS-1$
 
173
                int commentCharIndex = line
 
174
                                .indexOf(ISpecfileSpecialSymbols.COMMENT_START);
 
175
                if (commentCharIndex > -1) {
 
176
                        for (String item : taskTags) {
 
177
                                int taskIndex = line.indexOf(item);
 
178
                                if (taskIndex > commentCharIndex) {
 
179
                                        taskHandler.handleTask(lineNumber, line, item);
 
180
                                }
 
181
                        }
 
182
                }
 
183
        }
 
184
 
 
185
        public Specfile parse(String specfileContent) {
 
186
                return parse(new Document(specfileContent));
 
187
        }
 
188
 
 
189
        public SpecfileElement parseLine(String lineText, Specfile specfile,
 
190
                        int lineNumber) {
 
191
 
 
192
                if (lineText.startsWith("%")) //$NON-NLS-1$
 
193
                        return parseMacro(lineText, specfile, lineNumber);
 
194
 
 
195
                for (String simpleDefinition : simpleDefinitions) {
 
196
                        if (lineText.startsWith(simpleDefinition + DEFINE_SEPARATOR)) {
 
197
                                return parseSimpleDefinition(lineText, specfile, lineNumber,
 
198
                                                false);
 
199
                        }
 
200
                }
 
201
                for (String directValuesDefinition : directValuesDefinitions) {
 
202
                        if (lineText.startsWith(directValuesDefinition + DEFINE_SEPARATOR)) {
 
203
                                return parseDirectDefinition(lineText, specfile, lineNumber);
 
204
                        }
 
205
                }
 
206
                for (String directValuesDefinition : packageLevelDefinitions) {
 
207
                        if (lineText.startsWith(directValuesDefinition + DEFINE_SEPARATOR)) {
 
208
                                SpecfileElement definition = parseDirectDefinition(lineText,
 
209
                                                specfile, lineNumber);
 
210
                                if (directValuesDefinition.equals(RpmTags.REQUIRES)) {
 
211
                                        if (activePackage != null) {
 
212
                                                activePackage.addRequire((SpecfileTag) definition);
 
213
                                        } else {
 
214
                                                specfile.addRequire((SpecfileTag) definition);
 
215
                                        }
 
216
                                }
 
217
                                return definition;
 
218
                        }
 
219
                }
 
220
 
 
221
                if (lineText.startsWith(complexDefinitions[0])
 
222
                                && lineText.contains(DEFINE_SEPARATOR)) {
 
223
                        return parseComplexDefinition(lineText, lineNumber,
 
224
                                        SourceType.SOURCE);
 
225
                } else if (lineText.startsWith(complexDefinitions[1])
 
226
                                && lineText.contains(DEFINE_SEPARATOR)) {
 
227
                        return parseComplexDefinition(lineText, lineNumber,
 
228
                                        SourceType.PATCH);
 
229
                } else if (lineText.startsWith("BuildRequires")) { //$NON-NLS-1$
 
230
                        return parseBuildRequire(lineText, lineNumber, specfile);
 
231
                }
 
232
 
 
233
                return null;
 
234
        }
 
235
 
 
236
        private SpecfileElement parseBuildRequire(String lineText, int lineNumber,
 
237
                        Specfile specfile) {
 
238
                String value = lineText.substring(lineText.indexOf(':') + 1,
 
239
                                lineText.length()).trim();
 
240
                SpecfileDefine buildRequire = new SpecfileDefine(
 
241
                                "BuildRequires", value, specfile, null); //$NON-NLS-1$
 
242
                buildRequire.setLineNumber(lineNumber);
 
243
                specfile.addBuildRequire(buildRequire);
 
244
                return buildRequire;
 
245
        }
 
246
 
 
247
        private SpecfileSection parseSection(String lineText, Specfile specfile,
 
248
                        int lineNumber) {
 
249
                List<String> tokens = Arrays.asList(lineText.split(SPACE_REGEX));
 
250
                SpecfileSection toReturn = null;
 
251
                boolean isSimpleSection = false;
 
252
                for (Iterator<String> iter = tokens.iterator(); iter.hasNext();) {
 
253
                        String token = iter.next();
 
254
 
 
255
                        // Sections
 
256
                        // Simple Section Headers
 
257
                        for (String simpleSection : simpleSections) {
 
258
                                if (token.equals(simpleSection)) {
 
259
                                        toReturn = new SpecfileSection(token.substring(1), specfile);
 
260
                                        specfile.addSection(toReturn);
 
261
                                        isSimpleSection = true;
 
262
                                }
 
263
 
 
264
                        }
 
265
 
 
266
                        // Complex Section Headers
 
267
                        for (String complexSection : complexSections) {
 
268
                                if (token.equals(complexSection)) {
 
269
                                        String name = token.substring(1);
 
270
                                        if (!name.equals("package")) { //$NON-NLS-1$
 
271
                                                toReturn = new SpecfileSection(name, specfile);
 
272
                                                specfile.addComplexSection(toReturn);
 
273
                                        }
 
274
                                        while (iter.hasNext()) {
 
275
                                                String nextToken = iter.next();
 
276
                                                if (nextToken.equals("-n")) { //$NON-NLS-1$
 
277
                                                        if (!iter.hasNext()) {
 
278
                                                                errorHandler
 
279
                                                                                .handleError(new SpecfileParseException(
 
280
                                                                                                Messages
 
281
                                                                                                                .getString("SpecfileParser.1") //$NON-NLS-1$
 
282
                                                                                                                + name
 
283
                                                                                                                + Messages
 
284
                                                                                                                                .getString("SpecfileParser.2"), //$NON-NLS-1$
 
285
                                                                                                lineNumber, 0, lineText
 
286
                                                                                                                .length(),
 
287
                                                                                                IMarker.SEVERITY_ERROR));
 
288
                                                                continue;
 
289
                                                        }
 
290
 
 
291
                                                        nextToken = iter.next();
 
292
                                                        if (nextToken.startsWith("-")) { //$NON-NLS-1$
 
293
                                                                errorHandler
 
294
                                                                                .handleError(new SpecfileParseException(
 
295
                                                                                                Messages
 
296
                                                                                                                .getString("SpecfileParser.3") //$NON-NLS-1$
 
297
                                                                                                                + nextToken
 
298
                                                                                                                + Messages
 
299
                                                                                                                                .getString("SpecfileParser.4"), //$NON-NLS-1$
 
300
                                                                                                lineNumber, 0, lineText
 
301
                                                                                                                .length(),
 
302
                                                                                                IMarker.SEVERITY_ERROR));
 
303
                                                        }
 
304
 
 
305
                                                } else if (nextToken.equals("-p")) { //$NON-NLS-1$
 
306
                                                        // FIXME: rest of line is the actual section
 
307
                                                        break;
 
308
                                                } else if (nextToken.equals("-f")) { //$NON-NLS-1$
 
309
                                                        break;
 
310
                                                }
 
311
 
 
312
                                                // this is a package
 
313
                                                if (toReturn == null) {
 
314
                                                        SpecfilePackage tmpPackage = specfile
 
315
                                                                        .getPackage(nextToken);
 
316
 
 
317
                                                        if (tmpPackage == null) {
 
318
                                                                tmpPackage = new SpecfilePackage(nextToken,
 
319
                                                                                specfile);
 
320
                                                                specfile.addPackage(tmpPackage);
 
321
                                                        }
 
322
                                                        activePackage = tmpPackage;
 
323
                                                        return tmpPackage;
 
324
                                                }
 
325
 
 
326
                                                // this is another section
 
327
                                                SpecfilePackage enclosingPackage = specfile
 
328
                                                                .getPackage(nextToken);
 
329
                                                if (enclosingPackage == null) {
 
330
                                                        enclosingPackage = new SpecfilePackage(nextToken,
 
331
                                                                        specfile);
 
332
                                                        specfile.addPackage(enclosingPackage);
 
333
                                                }
 
334
                                                toReturn.setPackage(enclosingPackage);
 
335
                                                enclosingPackage.addSection(toReturn);
 
336
                                        }
 
337
                                }
 
338
                        }
 
339
                }
 
340
 
 
341
                // if this package is part of the top level package, add it to
 
342
                // it
 
343
                if (toReturn != null && toReturn.getPackage() == null) {
 
344
                        SpecfilePackage topPackage = specfile
 
345
                                        .getPackage(specfile.getName());
 
346
                        if (topPackage == null) {
 
347
                                topPackage = new SpecfilePackage(specfile.getName(), specfile);
 
348
                                specfile.addPackage(topPackage);
 
349
                        }
 
350
                        if (!isSimpleSection) {
 
351
                                topPackage.addSection(toReturn);
 
352
                        }
 
353
                }
 
354
                if (lastSection != null) {
 
355
                        lastSection.setSectionEndLine(lineNumber);
 
356
                }
 
357
                return toReturn;
 
358
        }
 
359
 
 
360
        private SpecfileElement parseMacro(String lineText, Specfile specfile,
 
361
                        int lineNumber) {
 
362
                // FIXME: handle other macros
 
363
 
 
364
                if (lineText.startsWith("%define") || lineText.startsWith("%global")) { //$NON-NLS-1$ //$NON-NLS-2$
 
365
                        return parseDefine(lineText, specfile, lineNumber);
 
366
                } else if (lineText.startsWith("%patch")) { //$NON-NLS-1$
 
367
                        return parsePatch(lineText, lineNumber);
 
368
                }
 
369
 
 
370
                String[] sections = new String[simpleSections.length
 
371
                                + complexSections.length];
 
372
                System.arraycopy(simpleSections, 0, sections, 0, simpleSections.length);
 
373
                System.arraycopy(complexSections, 0, sections, simpleSections.length,
 
374
                                complexSections.length);
 
375
                for (String section : sections) {
 
376
                        if (lineText.startsWith(section)) {
 
377
                                lastSection = parseSection(lineText, specfile, lineNumber);
 
378
                                if (lastSection != null)
 
379
                                        lastSection.setSectionEndLine(lineNumber + 1);
 
380
                                return lastSection;
 
381
                        }
 
382
                }
 
383
                // FIXME: add handling of lines containing %{SOURCENNN}
 
384
                return null;
 
385
        }
 
386
 
 
387
        private SpecfileElement parsePatch(String lineText, int lineNumber) {
 
388
 
 
389
                SpecfilePatchMacro toReturn = null;
 
390
 
 
391
                List<String> tokens = Arrays.asList(lineText.split(SPACE_REGEX));
 
392
 
 
393
                for (String token : tokens) {
 
394
                        // %patchN+
 
395
                        try {
 
396
                                if (token.startsWith("%patch")) { //$NON-NLS-1$
 
397
                                        int patchNumber = 0;
 
398
                                        if (token.length() > 6) {
 
399
                                                patchNumber = Integer.parseInt(token.substring(6));
 
400
                                        }
 
401
                                        toReturn = new SpecfilePatchMacro(patchNumber);
 
402
                                }
 
403
                        } catch (NumberFormatException e) {
 
404
                                errorHandler.handleError(new SpecfileParseException(
 
405
                                                Messages.getString("SpecfileParser.5"), //$NON-NLS-1$
 
406
                                                lineNumber, 0, lineText.length(),
 
407
                                                IMarker.SEVERITY_ERROR));
 
408
                                return null;
 
409
                        }
 
410
                }
 
411
 
 
412
                return toReturn;
 
413
        }
 
414
 
 
415
        private SpecfileDefine parseDefine(String lineText, Specfile specfile,
 
416
                        int lineNumber) {
 
417
                List<String> tokens = Arrays.asList(lineText.split(SPACE_REGEX));
 
418
                SpecfileDefine toReturn = null;
 
419
                for (Iterator<String> iter = tokens.iterator(); iter.hasNext();) {
 
420
                        // Eat the actual "%define" or "%global" token
 
421
                        iter.next();
 
422
                        while (iter.hasNext()) {
 
423
                                String defineName = iter.next();
 
424
                                // FIXME: is this true? investigate in rpmbuild source
 
425
                                // Definitions must being with a letter
 
426
                                if (!Character.isLetter(defineName.charAt(0))
 
427
                                                && (defineName.charAt(0) != '_')) {
 
428
                                        errorHandler.handleError(new SpecfileParseException(
 
429
                                                        Messages.getString("SpecfileParser.6"), //$NON-NLS-1$
 
430
                                                        lineNumber, 0, lineText.length(),
 
431
                                                        IMarker.SEVERITY_ERROR));
 
432
                                        return null;
 
433
                                } else {
 
434
                                        if (iter.hasNext()) {
 
435
                                                String defineStringValue = iter.next();
 
436
                                                // Defines that are more than one token
 
437
                                                if (iter.hasNext()) {
 
438
                                                        defineStringValue = lineText.substring(lineText
 
439
                                                                        .indexOf(defineStringValue));
 
440
                                                        // Eat up the rest of the tokens
 
441
                                                        while (iter.hasNext())
 
442
                                                                iter.next();
 
443
                                                }
 
444
                                                int defineIntValue = -1;
 
445
                                                try {
 
446
                                                        defineIntValue = Integer
 
447
                                                                        .parseInt(defineStringValue);
 
448
                                                } catch (NumberFormatException e) {
 
449
                                                        toReturn = new SpecfileDefine(defineName,
 
450
                                                                        defineStringValue, specfile, null);
 
451
                                                }
 
452
                                                if (toReturn == null)
 
453
                                                        toReturn = new SpecfileDefine(defineName,
 
454
                                                                        defineIntValue, specfile, null);
 
455
                                        } else {
 
456
                                                errorHandler.handleError(new SpecfileParseException(defineName+
 
457
                                                                Messages.getString("SpecfileParser.14"), //$NON-NLS-1$
 
458
                                                                lineNumber, 0, lineText.length(),
 
459
                                                                IMarker.SEVERITY_ERROR));
 
460
                                        }
 
461
                                }
 
462
                        }
 
463
                }
 
464
                return toReturn;
 
465
        }
 
466
 
 
467
        private SpecfileElement parseComplexDefinition(String lineText,
 
468
                        int lineNumber, SourceType sourceType) {
 
469
                SpecfileSource toReturn = null;
 
470
                List<String> tokens = Arrays.asList(lineText.split(SPACE_REGEX));
 
471
                int number = -1;
 
472
                boolean firstToken = true;
 
473
 
 
474
                for (Iterator<String> iter = tokens.iterator(); iter.hasNext();) {
 
475
                        String token = iter.next();
 
476
                        if (token != null && token.length() > 0) {
 
477
                                if (firstToken) {
 
478
                                        if (token.endsWith(DEFINE_SEPARATOR)) {
 
479
                                                token = token.substring(0, token.length() - 1);
 
480
                                        } else {
 
481
                                                // FIXME: come up with a better error message here
 
482
                                                // FIXME: what about descriptions that begin a line with
 
483
                                                // the word "Source" or "Patch"?
 
484
                                                errorHandler.handleError(new SpecfileParseException(
 
485
                                                                Messages.getString("SpecfileParser.8"), //$NON-NLS-1$
 
486
                                                                lineNumber, 0, lineText.length(),
 
487
                                                                IMarker.SEVERITY_WARNING));
 
488
                                                return null;
 
489
                                        }
 
490
                                        if (sourceType == SourceType.PATCH) {
 
491
                                                if (token.length() > 5) {
 
492
                                                        number = Integer.parseInt(token.substring(5));
 
493
                                                        if (!("patch" + number).equalsIgnoreCase(token)) { //$NON-NLS-1$
 
494
                                                                errorHandler
 
495
                                                                                .handleError(new SpecfileParseException(
 
496
                                                                                                Messages
 
497
                                                                                                                .getString("SpecfileParser.10"), //$NON-NLS-1$
 
498
                                                                                                lineNumber, 0, lineText
 
499
                                                                                                                .length(),
 
500
                                                                                                IMarker.SEVERITY_ERROR));
 
501
                                                                return null;
 
502
                                                        }
 
503
                                                } else {
 
504
                                                        number = 0;
 
505
                                                }
 
506
                                        } else {
 
507
                                                if (token.length() > 6) {
 
508
                                                        number = Integer.parseInt(token.substring(6));
 
509
                                                        if (!("source" + number).equalsIgnoreCase(token)) { //$NON-NLS-1$
 
510
                                                                errorHandler
 
511
                                                                                .handleError(new SpecfileParseException(
 
512
                                                                                                Messages
 
513
                                                                                                                .getString("SpecfileParser.11"), //$NON-NLS-1$
 
514
                                                                                                lineNumber, 0, lineText
 
515
                                                                                                                .length(),
 
516
                                                                                                IMarker.SEVERITY_ERROR));
 
517
                                                                return null;
 
518
                                                        }
 
519
                                                } else {
 
520
                                                        number = 0;
 
521
                                                }
 
522
                                        }
 
523
                                        toReturn = new SpecfileSource(number, ""); //$NON-NLS-1$
 
524
                                        toReturn.setSourceType(sourceType);
 
525
                                        firstToken = false;
 
526
                                } else {
 
527
                                        // toReturn should never be null but check just in case
 
528
                                        if (toReturn != null)
 
529
                                                toReturn.setFileName(token);
 
530
                                        if (iter.hasNext()) {
 
531
                                                errorHandler.handleError(new SpecfileParseException(
 
532
                                                                Messages.getString("SpecfileParser.12"), //$NON-NLS-1$
 
533
                                                                lineNumber, 0, lineText.length(),
 
534
                                                                IMarker.SEVERITY_ERROR));
 
535
                                        }
 
536
                                }
 
537
                        }
 
538
                }
 
539
 
 
540
                return toReturn;
 
541
        }
 
542
 
 
543
        private SpecfileElement parseSimpleDefinition(String lineText,
 
544
                        Specfile specfile, int lineNumber, boolean warnMultipleValues) {
 
545
                List<String> tokens = Arrays.asList(lineText.split(SPACE_REGEX));
 
546
                SpecfileTag toReturn = null;
 
547
 
 
548
                for (Iterator<String> iter = tokens.iterator(); iter.hasNext();) {
 
549
                        String token = iter.next();
 
550
 
 
551
                        if (token.length() <= 0) {
 
552
                                break;
 
553
                        }
 
554
 
 
555
                        if (iter.hasNext()) {
 
556
                                String possValue = iter.next();
 
557
                                if (possValue.startsWith("%") && iter.hasNext()) { //$NON-NLS-1$
 
558
                                        possValue += ' ' + iter.next();
 
559
                                }
 
560
                                toReturn = new SpecfileTag(token.substring(0,
 
561
                                                token.length() - 1).toLowerCase(), possValue, specfile,
 
562
                                                null);
 
563
                                if (iter.hasNext() && !warnMultipleValues) {
 
564
                                        errorHandler.handleError(new SpecfileParseException(
 
565
                                                        token.substring(0, token.length() - 1)
 
566
                                                                        + Messages.getString("SpecfileParser.13"), //$NON-NLS-1$
 
567
                                                        lineNumber, 0, lineText.length(),
 
568
                                                        IMarker.SEVERITY_ERROR));
 
569
                                        return null;
 
570
                                }
 
571
                        } else {
 
572
                                errorHandler.handleError(new SpecfileParseException(token
 
573
                                                .substring(0, token.length() - 1)
 
574
                                                + Messages.getString("SpecfileParser.14"), lineNumber, //$NON-NLS-1$
 
575
                                                0, lineText.length(), IMarker.SEVERITY_ERROR));
 
576
                                toReturn = null;
 
577
                        }
 
578
                }
 
579
                if ((toReturn != null) && (toReturn.getStringValue() != null)) {
 
580
                        try {
 
581
                                int intValue = Integer.parseInt(toReturn.getStringValue());
 
582
                                toReturn.setValue(intValue);
 
583
                        } catch (NumberFormatException e) {
 
584
                                if (toReturn.getName().equalsIgnoreCase(RpmTags.EPOCH)) {
 
585
                                        errorHandler
 
586
                                                        .handleError(new SpecfileParseException(
 
587
                                                                        Messages.getString("SpecfileParser.16"), lineNumber, //$NON-NLS-1$
 
588
                                                                        0, lineText.length(),
 
589
                                                                        IMarker.SEVERITY_ERROR));
 
590
                                        toReturn = null;
 
591
                                }
 
592
                        }
 
593
                }
 
594
                return toReturn;
 
595
        }
 
596
 
 
597
        private SpecfileElement parseDirectDefinition(String lineText,
 
598
                        Specfile specfile, int lineNumber) {
 
599
                String[] parts = lineText.split(DEFINE_SEPARATOR, 2);
 
600
                SpecfileTag directDefinition;
 
601
                if (parts.length == 2) {
 
602
                        directDefinition = new SpecfileTag(parts[0], parts[1].trim(),
 
603
                                        specfile, activePackage);
 
604
                        directDefinition.setLineNumber(lineNumber);
 
605
                } else {
 
606
                        errorHandler.handleError(new SpecfileParseException(parts[0]
 
607
                                        + Messages.getString("SpecfileParser.14"), lineNumber, //$NON-NLS-1$
 
608
                                        0, lineText.length(), IMarker.SEVERITY_ERROR));
 
609
                        directDefinition = null;
 
610
                }
 
611
                return directDefinition;
 
612
        }
 
613
 
 
614
        public void setErrorHandler(SpecfileErrorHandler specfileErrorHandler) {
 
615
                errorHandler = specfileErrorHandler;
 
616
        }
 
617
 
 
618
        public void setTaskHandler(SpecfileTaskHandler specfileTaskHandler) {
 
619
                taskHandler = specfileTaskHandler;
 
620
        }
 
621
}