001    // This file is part of the program FRYSK.
002    //
003    // Copyright 2007, 2008, Red Hat Inc.
004    //
005    // FRYSK is free software; you can redistribute it and/or modify it
006    // under the terms of the GNU General Public License as published by
007    // the Free Software Foundation; version 2 of the License.
008    //
009    // FRYSK is distributed in the hope that it will be useful, but
010    // WITHOUT ANY WARRANTY; without even the implied warranty of
011    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012    // General Public License for more details.
013    // 
014    // You should have received a copy of the GNU General Public License
015    // along with FRYSK; if not, write to the Free Software Foundation,
016    // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
017    // 
018    // In addition, as a special exception, Red Hat, Inc. gives You the
019    // additional right to link the code of FRYSK with code not covered
020    // under the GNU General Public License ("Non-GPL Code") and to
021    // distribute linked combinations including the two, subject to the
022    // limitations in this paragraph. Non-GPL Code permitted under this
023    // exception must only link to the code of FRYSK through those well
024    // defined interfaces identified in the file named EXCEPTION found in
025    // the source code files (the "Approved Interfaces"). The files of
026    // Non-GPL Code may instantiate templates or use macros or inline
027    // functions from the Approved Interfaces without causing the
028    // resulting work to be covered by the GNU General Public
029    // License. Only Red Hat, Inc. may make changes or additions to the
030    // list of Approved Interfaces. You must obey the GNU General Public
031    // License in all respects for all of the FRYSK code and other code
032    // used in conjunction with FRYSK except the Non-GPL Code covered by
033    // this exception. If you modify this file, you may extend this
034    // exception to your version of the file, but you are not obligated to
035    // do so. If you do not wish to provide this exception without
036    // modification, you must delete this exception statement from your
037    // version and license this file solely under the GPL without
038    // exception.
039    
040    package frysk.debuginfo;
041    
042    import java.util.HashMap;
043    import frysk.rsl.Log;
044    import frysk.rsl.LogFactory;
045    
046    public class CompilerVersionFactory {
047        private static HashMap compilerVersions = new HashMap();
048        protected static Log fine = LogFactory.fine(CompilerVersionFactory.class);
049        protected static Log finest = LogFactory.finest(CompilerVersionFactory.class);
050    
051        public static CompilerVersion getCompilerVersion(String compiler) {
052            if (compilerVersions.containsKey(compiler))
053                return (CompilerVersion) compilerVersions.get(compiler);
054    
055            // XXX: GNU C specific.
056            fine.log("Found compiler: ", compiler);
057    
058            CompilerVersion compVersion;
059    
060            // String looks like: GNU C++ 4.1.2 20070925 (Red Hat 4.1.2-33)
061            //
062            if (!compiler.matches("GNU C.*\\(Red Hat \\d+\\.\\d+\\.\\d+-\\d+\\)")) {
063                compVersion = new CompilerVersion(compiler);
064            } else {
065                String preCompilerVersion = "(Red Hat ";
066    
067                String compilerVersion = compiler.substring(compiler
068                        .indexOf(preCompilerVersion)
069                        + preCompilerVersion.length(), compiler.lastIndexOf(')'));
070    
071                String[] versions = compilerVersion.split("\\.");
072    
073                finest.log("Version string has 3 sections");
074    
075                int version = Integer.parseInt(versions[0]);
076                int minorVersion = Integer.parseInt(versions[1]);
077    
078                String[] minorVersions = versions[2].split("-");
079    
080                int patchLevel = Integer.parseInt(minorVersions[0]);
081                int RHRelease = Integer.parseInt(minorVersions[1]);
082                compVersion = new GNURedHatCompilerVersion(compiler, version,
083                        minorVersion, patchLevel, RHRelease);
084            }
085            compilerVersions.put(compiler, compVersion);
086            return compVersion;
087        }
088    }