001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.cnd.makewizard;
043:
044: import java.io.File;
045: import java.io.IOException;
046: import java.util.ArrayList;
047: import java.util.ResourceBundle;
048: import org.netbeans.modules.cnd.api.utils.IpeUtils;
049: import org.openide.util.NbBundle;
050:
051: /**
052: * A MakefileData record. This file should contain ALL iformation necessary to
053: * create a Makefile.
054: */
055:
056: final public class MakefileData {
057: // Makefile Type Values
058: public final static int EXECUTABLE_MAKEFILE_TYPE = 1;
059: public final static int ARCHIVE_MAKEFILE_TYPE = 2;
060: public final static int SHAREDLIB_MAKEFILE_TYPE = 3;
061: public final static int COMPLEX_MAKEFILE_TYPE = 4;
062:
063: // Makefile Compiler Collection Values
064: public final static int SUN_TOOLSET_TYPE = 0;
065: public final static int GNU_TOOLSET_TYPE = 1;
066: public final static int SUNGNU_TOOLSET_TYPE = 2;
067:
068: // Makefile OS Values
069: public final static int SOLARIS_OS_TYPE = 0;
070: public final static int LINUX_OS_TYPE = 1;
071: public final static int UNIX_OS_TYPE = 2;
072: public final static int WINDOWS_OS_TYPE = 3;
073: public final static int MACOSX_OS_TYPE = 4;
074:
075: // Conformance Level C SUN
076: private int conformLevelCSun = 1; // Default
077: public final static String[] conformLevelsCSun = { "-Xc", // ISO C (-Xc) // NOI18N
078: "", // ISO C plus K&R C (-Xa) // NOI18N
079: "-Xs", // K&R C (-Xs) // NOI18N
080: };
081:
082: // Conformance Level Cpp SUN
083: private int conformLevelCppSun = 1; // Default
084: public final static String[] conformLevelsCppSun = { "-compat=4", // 4.2 compatible // NOI18N
085: "", // Standard // NOI18N
086: };
087:
088: // Conformance Level C GNU
089: private int conformLevelCGNU = 1; // Default
090: public final static String[] conformLevelsCGNU = { "-ansi", // Ansi // NOI18N
091: "", // Ansi plus GNU extentions // NOI18N
092: };
093:
094: // Conformance Level Cpp GNU
095: private int conformLevelCppGNU = 1; // Default
096: public final static String[] conformLevelsCppGNU = { "-ansi", // Ansi // NOI18N
097: "", // Ansi plus GNU extentions // NOI18N
098: };
099:
100: /** The type of Makefile this data could make (complex, single executbale, ...)*/
101: private int makefileType;
102:
103: /** The compiler collection this Makefile should support (Sun, GNU, ...)*/
104: private int toolset;
105:
106: /** The OS this Makefile should support (Solaris, Linux, both, ...)*/
107: private int makefileOS;
108:
109: /** The directory of the Makefile */
110: private String baseDirectory;
111:
112: /** The Makefile name */
113: private String makefileName;
114:
115: /** The Makefile dir name */
116: private String makefileDirName;
117:
118: /** The targetList contains information about each target */
119: private ArrayList targetList;
120:
121: /** The compile time flags for this Makefile */
122: private CompilerFlags compilerFlags;
123:
124: /** Look up i18n strings here */
125: private ResourceBundle bundle;
126:
127: /** Save the C compiler path */
128: private String cCompilerSun;
129: private String cCompilerGNU;
130:
131: /** Save the C++ compiler path */
132: private String cppCompilerSun;
133: private String cppCompilerGNU;
134:
135: /** Save the Fortran compiler path */
136: private String fCompilerSun;
137: private String fCompilerGNU;
138:
139: /** Save the Fortran compiler type setting */
140: private int ftype;
141:
142: /** Do we have Fortran 95 files and are we using either MODULE or USE statements? */
143: private boolean moduleEnabled;
144:
145: /** Save the path to X-Designer */
146: private String xdCompiler;
147:
148: /** Save the assembler path */
149: private String asmPath;
150:
151: /** Save the compiler bin directory */
152: private static String binDir;
153:
154: /** Default C++ Compatability mode */
155: public final static int COMPAT_DEFAULT = 0;
156:
157: /** Ansi C++ Compatability mode */
158: public final static int COMPAT_ANSI = 1;
159:
160: /** C++ 4.2 Compatability mode */
161: public final static int COMPAT_4_2 = 2;
162:
163: /** Expand the base directory */
164: public static final boolean EXPAND = true;
165:
166: /**
167: * Default constructor for class Makefile. Initialize data to default.
168: */
169:
170: public MakefileData() {
171:
172: makefileType = MakefileData.COMPLEX_MAKEFILE_TYPE;
173: toolset = MakefileData.SUNGNU_TOOLSET_TYPE;
174: makefileOS = MakefileData.UNIX_OS_TYPE;
175: baseDirectory = new String(System.getProperty("user.dir")); // NOI18N
176: makefileName = getString("DFLT_MakefileName"); // NOI18N
177: targetList = new ArrayList();
178: compilerFlags = new CompilerFlags();
179: binDir = null;
180: moduleEnabled = false;
181: }
182:
183: /**
184: * Create a new Makefile using values from the previously created one. This
185: * ensures we have better defaults than we would if we used compiled in
186: * defaults.
187: */
188: public MakefileData(MakefileData old) {
189:
190: bundle = NbBundle.getBundle(MakefileWizardPanel.class);
191:
192: makefileType = old.getMakefileType();
193: toolset = old.getToolset();
194: makefileOS = old.getMakefileOS();
195: baseDirectory = old.getBaseDirectory();
196: makefileName = old.getMakefileName();
197: makefileDirName = old.getMakefileDirName();
198: targetList = new ArrayList();
199: compilerFlags = new CompilerFlags();
200: binDir = old.binDir;
201: }
202:
203: /**
204: * Compute the full Makefile path from the name and base.
205: */
206: public String getMakefilePath() {
207: String name = IpeUtils.expandPath(makefileName);
208: String path;
209:
210: if (name.charAt(0) == File.separatorChar) {
211: path = makefileName;
212: } else {
213: File file = new File(getBaseDirectory(EXPAND), name);
214: try {
215: path = file.getCanonicalPath();
216: } catch (IOException ex) {
217: path = file.getAbsolutePath();
218: }
219: }
220:
221: return path;
222: }
223:
224: /**
225: * Compute default output directory
226: */
227: public String defaultOutputDirectory() {
228: String toolset = "toolset"; // NOI18N
229: String OS = "os"; // NOI18N
230: String dir = null;
231:
232: if (getToolset() == SUN_TOOLSET_TYPE) {
233: toolset = "Sun"; // NOI18N
234: } else if (getToolset() == GNU_TOOLSET_TYPE) {
235: toolset = "GNU"; // NOI18N
236: }
237:
238: if (getMakefileOS() == SOLARIS_OS_TYPE) {
239: OS = "Solaris"; // NOI18N
240: } else if (getMakefileOS() == LINUX_OS_TYPE) {
241: OS = "Linux"; // NOI18N
242: } else if (getMakefileOS() == WINDOWS_OS_TYPE) {
243: OS = "Windows"; // NOI18N
244: } else if (getMakefileOS() == MACOSX_OS_TYPE) {
245: OS = "MacOSX"; // NOI18N
246: }
247:
248: dir = toolset + "-" + System.getProperty("os.arch") + "-" + OS; // NOI18N
249: return dir;
250: }
251:
252: /** Get the type of Makefile being created */
253: public int getMakefileType() {
254: return makefileType;
255: }
256:
257: /** Set the type of Makefile to be created */
258: public void setMakefileType(int makefileType) {
259: this .makefileType = makefileType;
260: }
261:
262: /** Get compiler conformance flag C SUN */
263: public String getConformFlagCSun() {
264: return conformLevelsCSun[conformLevelCSun];
265: }
266:
267: /** Get the type of compiler conformance level C SUN */
268: public int getConformLevelCSun() {
269: return conformLevelCSun;
270: }
271:
272: /** Set the type of compiler conformance level C SUN */
273: public void setConformLevelCSun(int level) {
274: this .conformLevelCSun = level;
275: }
276:
277: /** Get compiler conformance flag Cpp SUN */
278: public String getConformFlagCppSun() {
279: return conformLevelsCppSun[conformLevelCppSun];
280: }
281:
282: /** Get the type of compiler conformance level Cpp SUN */
283: public int getConformLevelCppSun() {
284: return conformLevelCppSun;
285: }
286:
287: /** Set the type of compiler conformance level Cpp SUN */
288: public void setConformLevelCppSun(int level) {
289: this .conformLevelCppSun = level;
290: }
291:
292: /** Get compiler conformance flag C GNU */
293: public String getConformFlagCGNU() {
294: return conformLevelsCGNU[conformLevelCGNU];
295: }
296:
297: /** Get the type of compiler conformance level C GNU */
298: public int getConformLevelCGNU() {
299: return conformLevelCGNU;
300: }
301:
302: /** Set the type of compiler conformance level C GNU */
303: public void setConformLevelCGNU(int level) {
304: this .conformLevelCGNU = level;
305: }
306:
307: /** Get compiler conformance flag Cpp GNU */
308: public String getConformFlagCppGNU() {
309: return conformLevelsCppGNU[conformLevelCppGNU];
310: }
311:
312: /** Get the type of compiler conformance level Cpp GNU */
313: public int getConformLevelCppGNU() {
314: return conformLevelCppGNU;
315: }
316:
317: /** Set the type of compiler conformance level Cpp GNU */
318: public void setConformLevelCppGNU(int level) {
319: this .conformLevelCppGNU = level;
320: }
321:
322: /** Get the type of compiler collection */
323: public int getToolset() {
324: return toolset;
325: }
326:
327: /** Set the type of compiler collection */
328: public void setToolset(int toolset) {
329: this .toolset = toolset;
330: }
331:
332: /** Get the OS the makefile should be created for */
333: public int getMakefileOS() {
334: return makefileOS;
335: }
336:
337: /** Set the OS the makefile should be created for */
338: public void setMakefileOS(int makefileOS) {
339: this .makefileOS = makefileOS;
340: }
341:
342: /** Get the current directory */
343: public String getBaseDirectory() {
344: return baseDirectory;
345: }
346:
347: /**
348: * Get the base directory.
349: *
350: * @param expand Expand ~[user] and $vars
351: */
352: public String getBaseDirectory(boolean expand) {
353: // Ignore expand...
354: return getBaseDirectory();
355: }
356:
357: /** Set the current directory */
358: public void setBaseDirectory(String baseDirectory) {
359: this .baseDirectory = IpeUtils.trimSlashes(baseDirectory);
360: ;
361: }
362:
363: /** Get the Makefile name */
364: public String getMakefileName() {
365: return makefileName;
366: }
367:
368: /** Set the Makefile name */
369: public void setMakefileName(String makefileName) {
370: if (makefileName.length() > 0) {
371: this .makefileName = makefileName;
372: }
373: }
374:
375: /** Get the Makefile dir name */
376: public String getMakefileDirName() {
377: return makefileDirName;
378: }
379:
380: /** Set the Makefile dir name */
381: public void setMakefileDirName(String makefileDirName) {
382: if (makefileDirName.length() > 0) {
383: this .makefileDirName = makefileDirName;
384: }
385: }
386:
387: /** Get the CompilerFlags */
388: public CompilerFlags getCompilerFlags() {
389: return compilerFlags;
390: }
391:
392: /** Get the list of targets */
393: public ArrayList getTargetList() {
394: if (targetList == null) {
395: targetList = new ArrayList(
396: makefileType == MakefileData.COMPLEX_MAKEFILE_TYPE ? 15
397: : 1);
398: }
399: return targetList;
400: }
401:
402: /** Get the current target */
403: public TargetData getCurrentTarget() {
404: int key = MakefileWizard.getMakefileWizard()
405: .getCurrentTargetKey();
406:
407: return getTarget(key);
408: }
409:
410: /** Get the target matching key */
411: public TargetData getTarget(int key) {
412: TargetData target = null;
413:
414: for (int i = 0; i < targetList.size(); i++) {
415: target = (TargetData) targetList.get(i);
416: if (target.getKey() == key) {
417: break;
418: }
419: }
420:
421: return target;
422: }
423:
424: /**
425: * Tells if all targets are complete. In some cases thim method is called
426: * after a target has been completed but before the data has been
427: * transferred from the widget to the TargetData. When this happens the
428: * method is called with ignoreCurrent set to true.
429: *
430: * @param ignoreCurrent Ignore the current target (its complete)
431: */
432: public boolean isComplete(boolean ignoreCurrent) {
433: TargetData ct = getCurrentTarget();
434:
435: for (int i = 0; i < targetList.size(); i++) {
436: TargetData target = (TargetData) targetList.get(i);
437:
438: if (target == ct && ignoreCurrent) {
439: continue;
440: }
441: if (!target.isComplete()) {
442: return false;
443: }
444: }
445:
446: return targetList.size() > 0; // always return false for empty list
447: }
448:
449: /** Tells if all targets are complete */
450: public boolean isComplete() {
451: return isComplete(false);
452: }
453:
454: /** Get the C compiler */
455: public String getCCompiler(int toolset) {
456: if (toolset == SUN_TOOLSET_TYPE) {
457: return getCCompilerSun();
458: } else if (toolset == GNU_TOOLSET_TYPE) {
459: return getCCompilerGNU();
460: } else {
461: ; // FIXUP - error
462: }
463: return null;
464: }
465:
466: /** Get the C compiler Sun*/
467: public String getCCompilerSun() {
468: if (cCompilerSun == null) {
469: cCompilerSun = "cc"; // NOI18N
470: }
471: return cCompilerSun;
472: }
473:
474: /** Get the C compiler GNU*/
475: public String getCCompilerGNU() {
476: if (cCompilerGNU == null) {
477: cCompilerGNU = "gcc"; // NOI18N
478: }
479: return cCompilerGNU;
480: }
481:
482: /** Setter for the C compiler*/
483: public void setCCompiler(int toolset, String cCompiler) {
484: if (toolset == SUN_TOOLSET_TYPE) {
485: setCCompilerSun(cCompiler);
486: } else if (toolset == GNU_TOOLSET_TYPE) {
487: setCCompilerGNU(cCompiler);
488: } else {
489: ; // FIXUP - error
490: }
491: }
492:
493: /** Setter for the C compiler Sun*/
494: public void setCCompilerSun(String cCompiler) {
495: this .cCompilerSun = cCompiler;
496: }
497:
498: /** Setter for the C compiler GNU*/
499: public void setCCompilerGNU(String cCompiler) {
500: this .cCompilerGNU = cCompiler;
501: }
502:
503: /** Get the C++ compiler */
504: public String getCppCompiler(int toolset) {
505: if (toolset == SUN_TOOLSET_TYPE) {
506: return getCppCompilerSun();
507: } else if (toolset == GNU_TOOLSET_TYPE) {
508: return getCppCompilerGNU();
509: } else {
510: ; // FIXUP - error
511: }
512: return null;
513: }
514:
515: /** Get the C++ compiler Sun*/
516: public String getCppCompilerSun() {
517: if (cppCompilerSun == null) {
518: cppCompilerSun = "CC"; // NOI18N);
519: }
520: return cppCompilerSun;
521: }
522:
523: /** Get the C++ compiler GNU*/
524: public String getCppCompilerGNU() {
525: if (cppCompilerGNU == null) {
526: cppCompilerGNU = "g++"; // NOI18N);
527: }
528: return cppCompilerGNU;
529: }
530:
531: /** Setter for the Cpp compiler*/
532: public void setCppCompiler(int toolset, String cppCompiler) {
533: if (toolset == SUN_TOOLSET_TYPE) {
534: setCppCompilerSun(cppCompiler);
535: } else if (toolset == GNU_TOOLSET_TYPE) {
536: setCppCompilerGNU(cppCompiler);
537: } else {
538: ; // FIXUP - error
539: }
540: }
541:
542: /** Setter for the C++ compiler Sun*/
543: public void setCppCompilerSun(String cppCompiler) {
544: this .cppCompilerSun = cppCompiler;
545: }
546:
547: /** Setter for the C++ compiler GNU*/
548: public void setCppCompilerGNU(String cppCompiler) {
549: this .cppCompilerGNU = cppCompiler;
550: }
551:
552: /** Get the Fortran compiler */
553: public String getFCompiler(int toolset) {
554: if (toolset == SUN_TOOLSET_TYPE) {
555: return getFCompilerSun();
556: } else if (toolset == GNU_TOOLSET_TYPE) {
557: return getFCompilerGNU();
558: } else {
559: ; // FIXUP - error
560: }
561: return null;
562: }
563:
564: /** Get the Fortran compiler - Sun */
565: public String getFCompilerSun() {
566: if (fCompilerSun == null) {
567: fCompilerSun = "f95"; // NOI18N
568: }
569: return fCompilerSun;
570: }
571:
572: /** Get the Fortran compiler - GNU */
573: public String getFCompilerGNU() {
574: if (fCompilerGNU == null) {
575: fCompilerGNU = "g77"; // NOI18N
576: }
577: return fCompilerGNU;
578: }
579:
580: /** Setter for the F compiler */
581: public void setFCompiler(int toolset, String fCompiler) {
582: if (toolset == SUN_TOOLSET_TYPE) {
583: setFCompilerSun(fCompiler);
584: } else if (toolset == GNU_TOOLSET_TYPE) {
585: setFCompilerGNU(fCompiler);
586: } else {
587: ; // FIXUP - error
588: }
589: }
590:
591: /** Setter for the F compiler - Sun*/
592: public void setFCompilerSun(String fCompiler) {
593: this .fCompilerSun = fCompiler;
594: }
595:
596: /** Setter for the F compiler - GNU*/
597: public void setFCompilerGNU(String fCompiler) {
598: this .fCompilerGNU = fCompiler;
599: }
600:
601: /** Get the Assembler name/path */
602: public String getAsmPath() {
603: if (asmPath == null) {
604: asmPath = "as"; // NOI18N
605: }
606: return asmPath;
607: }
608:
609: /** Setter for the Assembler */
610: public void setAsmPath(String asmPath) {
611: this .asmPath = asmPath;
612: }
613:
614: private String getString(String s) {
615: if (bundle == null) {
616: bundle = NbBundle.getBundle(MakefileWizardPanel.class);
617: }
618: return bundle.getString(s);
619: }
620:
621: /** Check if we are using MODULE or USE statements in Fortran sources */
622: public final boolean isModuleEnabled() {
623: return moduleEnabled;
624: }
625:
626: /** Setter for muduleEnabled */
627: public void setModuleEnabled(boolean moduleEnabled) {
628: this .moduleEnabled = moduleEnabled;
629: }
630:
631: // Debugging stuff...
632: private String indent;
633:
634: public void dump() {
635:
636: setIndent(""); // NOI18N
637: println("\n\nDumping Makefile:"); // NOI18N
638: println(" makefileType = " + makefileType); // NOI18N
639: println(" toolset " + toolset); // NOI18N
640: println(" makefileOS = " + makefileOS); // NOI18N
641: println(" baseDirectory = \"" + baseDirectory + "\""); // NOI18N
642: println(" makefileName = \"" + makefileName + "\""); // NOI18N
643: println(" makefileDirName = \"" + makefileDirName + "\""); // NOI18N
644: compilerFlags.dump(indent + " "); // NOI18N
645: println(" targetList.size = " + targetList.size()); // NOI18N
646:
647: for (int i = 0; i < targetList.size(); i++) {
648: println(" targetList[" + i + "] = {"); // NOI18N
649: ((TargetData) targetList.get(i)).dump(new StringBuffer(
650: indent).append(" ").toString());// NOI18N
651: println(" }"); // NOI18N
652: }
653: }
654:
655: public void dump(String indent) {
656: setIndent(indent);
657: dump();
658: }
659:
660: private void println(String s) {
661: System.out.println(indent + s);
662: }
663:
664: private void setIndent(String indent) {
665: this .indent = indent;
666: }
667:
668: public boolean validateTargetName(String name, int type) {
669: boolean ok = true;
670:
671: if (name == null || name.length() == 0) {
672: ok = false;
673: } else {
674: switch (type) {
675: case TargetData.COMPLEX_EXECUTABLE:
676: case TargetData.COMPLEX_ARCHIVE:
677: case TargetData.COMPLEX_SHAREDLIB:
678: ok = dontContainChar(name, ":#= \t()"); // NOI18N
679: break;
680: case TargetData.COMPLEX_MAKE_TARGET:
681: case TargetData.COMPLEX_CUSTOM_TARGET:
682: ok = dontContainChar(name, ":#= \t"); // NOI18N
683: break;
684: default:
685: }
686: }
687: return ok;
688: }
689:
690: private boolean dontContainChar(String name, String chars) {
691: boolean ok = true;
692:
693: if (chars == null || chars.length() == 0) {
694: ; // nothing
695: } else {
696: for (int i = 0; i < chars.length(); i++) {
697: if (name.indexOf(chars.charAt(i)) >= 0) {
698: ok = false;
699: break;
700: }
701: }
702: }
703: return ok;
704: }
705: }
|