Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: a57acb761f0340634b921aeea978a73da4547c39 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
/*******************************************************************************
 * Copyright (c) 2000, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.cdt.core;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import org.eclipse.cdt.core.dom.CDOM;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.core.parser.IScannerInfoProvider;
import org.eclipse.cdt.core.resources.IConsole;
import org.eclipse.cdt.core.resources.IPathEntryVariableManager;
import org.eclipse.cdt.core.resources.ScannerProvider;
import org.eclipse.cdt.internal.core.CDTLogWriter;
import org.eclipse.cdt.internal.core.CDescriptorManager;
import org.eclipse.cdt.internal.core.PathEntryVariableManager;
import org.eclipse.cdt.internal.core.model.BufferManager;
import org.eclipse.cdt.internal.core.model.CModelManager;
import org.eclipse.cdt.internal.core.model.DeltaProcessor;
import org.eclipse.cdt.internal.core.model.IBufferFactory;
import org.eclipse.cdt.internal.core.model.Util;
import org.eclipse.cdt.internal.core.pdom.PDOMManager;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.content.IContentTypeManager;
import org.eclipse.core.runtime.content.IContentTypeMatcher;
import org.osgi.framework.BundleContext;

public class CCorePlugin extends Plugin {

	public static final int STATUS_CDTPROJECT_EXISTS = 1;
	public static final int STATUS_CDTPROJECT_MISMATCH = 2;
	public static final int CDT_PROJECT_NATURE_ID_MISMATCH = 3;

	public static final String PLUGIN_ID = "org.eclipse.cdt.core"; //$NON-NLS-1$

	public static final String BUILDER_MODEL_ID = PLUGIN_ID + ".CBuildModel"; //$NON-NLS-1$
	public static final String BINARY_PARSER_SIMPLE_ID = "BinaryParser"; //$NON-NLS-1$
	public final static String BINARY_PARSER_UNIQ_ID = PLUGIN_ID + "." + BINARY_PARSER_SIMPLE_ID; //$NON-NLS-1$
	public final static String PREF_BINARY_PARSER = "binaryparser"; //$NON-NLS-1$
	public final static String DEFAULT_BINARY_PARSER_SIMPLE_ID = "ELF"; //$NON-NLS-1$
	public final static String DEFAULT_BINARY_PARSER_UNIQ_ID = PLUGIN_ID + "." + DEFAULT_BINARY_PARSER_SIMPLE_ID; //$NON-NLS-1$
	public final static String PREF_USE_STRUCTURAL_PARSE_MODE = "useStructualParseMode"; //$NON-NLS-1$
	
	public static final String INDEXER_SIMPLE_ID = "CIndexer"; //$NON-NLS-1$
	public static final String INDEXER_UNIQ_ID = PLUGIN_ID + "." + INDEXER_SIMPLE_ID; //$NON-NLS-1$
	public final static String PREF_INDEXER = "indexer"; //$NON-NLS-1$
	
	public final static String ERROR_PARSER_SIMPLE_ID = "ErrorParser"; //$NON-NLS-1$

	// default store for pathentry
	public final static String DEFAULT_PATHENTRY_STORE_ID = PLUGIN_ID + ".cdtPathEntryStore"; //$NON-NLS-1$

	// Build Model Interface Discovery
	public final static String BUILD_SCANNER_INFO_SIMPLE_ID = "ScannerInfoProvider"; //$NON-NLS-1$
	public final static String BUILD_SCANNER_INFO_UNIQ_ID = PLUGIN_ID + "." + BUILD_SCANNER_INFO_SIMPLE_ID; //$NON-NLS-1$

	/**
	 * Name of the extension point for contributing a source code formatter
	 */
	public static final String FORMATTER_EXTPOINT_ID = "CodeFormatter" ; //$NON-NLS-1$

	/**
	 * Possible configurable option value for TRANSLATION_TASK_PRIORITIES.
	 * @see #getDefaultOptions
	 */
	public static final String TRANSLATION_TASK_PRIORITY_NORMAL = "NORMAL"; //$NON-NLS-1$	    
    /**
     * Possible configurable option value for TRANSLATION_TASK_PRIORITIES.
     * @see #getDefaultOptions
     */
    public static final String TRANSLATION_TASK_PRIORITY_HIGH = "HIGH"; //$NON-NLS-1$
    /**
     * Possible configurable option value for TRANSLATION_TASK_PRIORITIES.
     * @see #getDefaultOptions
     */
    public static final String TRANSLATION_TASK_PRIORITY_LOW = "LOW"; //$NON-NLS-1$
    /**
     * Possible  configurable option ID.
     * @see #getDefaultOptions
     */
    public static final String CORE_ENCODING = PLUGIN_ID + ".encoding"; //$NON-NLS-1$
	
	/**
	 * IContentType id for C Source Unit
	 */
	public final static String CONTENT_TYPE_CSOURCE =  "org.eclipse.cdt.core.cSource"; //$NON-NLS-1$
	/**
	 * IContentType id for C Header Unit
	 */
	public final static String CONTENT_TYPE_CHEADER =  "org.eclipse.cdt.core.cHeader"; //$NON-NLS-1$
	/**
	 * IContentType id for C++ Source Unit
	 */
	public final static String CONTENT_TYPE_CXXSOURCE = "org.eclipse.cdt.core.cxxSource"; //$NON-NLS-1$
	/**
	 * IContentType id for C++ Header Unit
	 */
	public final static String CONTENT_TYPE_CXXHEADER = "org.eclipse.cdt.core.cxxHeader"; //$NON-NLS-1$
	/**
	 * IContentType id for ASM Unit
	 */
	public final static String CONTENT_TYPE_ASMSOURCE = "org.eclipse.cdt.core.asmSource"; //$NON-NLS-1$


    public CDTLogWriter cdtLog = null;

	private static CCorePlugin fgCPlugin;
	private static ResourceBundle fgResourceBundle;

	private CDescriptorManager fDescriptorManager = new CDescriptorManager();

	private CoreModel fCoreModel;
	
	private PDOMManager pdomManager;

	private PathEntryVariableManager fPathEntryVariableManager;

	// -------- static methods --------

	static {
		try {
			fgResourceBundle = ResourceBundle.getBundle("org.eclipse.cdt.internal.core.CCorePluginResources"); //$NON-NLS-1$
		} catch (MissingResourceException x) {
			fgResourceBundle = null;
		}
	}

	/**
	 * Answers the shared working copies currently registered for this buffer factory. 
	 * Working copies can be shared by several clients using the same buffer factory,see 
	 * <code>IWorkingCopy.getSharedWorkingCopy</code>.
	 * 
	 * @param factory the given buffer factory
	 * @return the list of shared working copies for a given buffer factory
	 * @see IWorkingCopy
	 */
	public static IWorkingCopy[] getSharedWorkingCopies(IBufferFactory factory){
		
		// if factory is null, default factory must be used
		if (factory == null) factory = BufferManager.getDefaultBufferManager().getDefaultBufferFactory();
		Map sharedWorkingCopies = CModelManager.getDefault().sharedWorkingCopies;
		
		Map perFactoryWorkingCopies = (Map) sharedWorkingCopies.get(factory);
		if (perFactoryWorkingCopies == null) return CModelManager.NoWorkingCopy;
		Collection copies = perFactoryWorkingCopies.values();
		IWorkingCopy[] result = new IWorkingCopy[copies.size()];
		copies.toArray(result);
		return result;
	}
	
	public static String getResourceString(String key) {
		try {
			return fgResourceBundle.getString(key);
		} catch (MissingResourceException e) {
			return "!" + key + "!"; //$NON-NLS-1$ //$NON-NLS-2$
		} catch (NullPointerException e) {
			return "#" + key + "#"; //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	public static IWorkspace getWorkspace() {
		return ResourcesPlugin.getWorkspace();
	}

	public static String getFormattedString(String key, String arg) {
		return MessageFormat.format(getResourceString(key), new String[] { arg });
	}

	public static String getFormattedString(String key, String[] args) {
		return MessageFormat.format(getResourceString(key), args);
	}

	public static ResourceBundle getResourceBundle() {
		return fgResourceBundle;
	}

	public static CCorePlugin getDefault() {
		return fgCPlugin;
	}

	public static void log(Throwable e) {
		if ( e instanceof CoreException ) {
			log(((CoreException)e).getStatus());
		} else {
			log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.ERROR, "Error", e)); //$NON-NLS-1$
		}
	}

	public static void log(IStatus status) {
		((Plugin) getDefault()).getLog().log(status);
	}

	// ------ CPlugin

	public CCorePlugin() {
		super();
		fgCPlugin = this;
	}

	/**
	 * @see Plugin#shutdown
	 */
	public void stop(BundleContext context) throws Exception {
		try {
			if (fDescriptorManager != null) {
				fDescriptorManager.shutdown();
			}
			
			if (fCoreModel != null) {
				fCoreModel.shutdown();
			}
			
			if (cdtLog != null) {
				cdtLog.shutdown();
			}

			if (fPathEntryVariableManager != null) {
				fPathEntryVariableManager.shutdown();
			}

			savePluginPreferences();
		} finally {
			super.stop(context);
		}
	}

	/**
	 * @see Plugin#startup
	 */
	public void start(BundleContext context) throws Exception {
		super.start(context);
		
		// Start file type manager first !!
		fPathEntryVariableManager = new PathEntryVariableManager();
		fPathEntryVariableManager.startup();

		cdtLog = new CDTLogWriter(CCorePlugin.getDefault().getStateLocation().append(".log").toFile()); //$NON-NLS-1$
		
		//Set debug tracing options
		CCorePlugin.getDefault().configurePluginDebugOptions();
		
		fDescriptorManager.startup();

		// Fired up the model.
		fCoreModel = CoreModel.getDefault();
		fCoreModel.startup();

		// Fire up the PDOM
		pdomManager = new PDOMManager();
		pdomManager.startup();

		// Set the default for using the structual parse mode to build the CModel
		getPluginPreferences().setDefault(PREF_USE_STRUCTURAL_PARSE_MODE, false);

	}
    
    
    /**
     * TODO: Add all options here
     * Returns a table of all known configurable options with their default values.
     * These options allow to configure the behaviour of the underlying components.
     * The client may safely use the result as a template that they can modify and
     * then pass to <code>setOptions</code>.
     * 
     * Helper constants have been defined on CCorePlugin for each of the option ID and 
     * their possible constant values.
     * 
     * Note: more options might be added in further releases.
     * <pre>
     * RECOGNIZED OPTIONS:
     * TRANSLATION / Define the Automatic Task Tags
     *    When the tag list is not empty, translation will issue a task marker whenever it encounters
     *    one of the corresponding tags inside any comment in C/C++ source code.
     *    Generated task messages will include the tag, and range until the next line separator or comment ending.
     *    Note that tasks messages are trimmed. If a tag is starting with a letter or digit, then it cannot be leaded by
     *    another letter or digit to be recognized ("fooToDo" will not be recognized as a task for tag "ToDo", but "foo#ToDo"
     *    will be detected for either tag "ToDo" or "#ToDo"). Respectively, a tag ending with a letter or digit cannot be followed
     *    by a letter or digit to be recognized ("ToDofoo" will not be recognized as a task for tag "ToDo", but "ToDo:foo" will
     *    be detected either for tag "ToDo" or "ToDo:").
     *     - option id:         "org.eclipse.cdt.core.translation.taskTags"
     *     - possible values:   { "<tag>[,<tag>]*" } where <tag> is a String without any wild-card or leading/trailing spaces 
     *     - default:           ""
     * 
     * TRANSLATION / Define the Automatic Task Priorities
     *    In parallel with the Automatic Task Tags, this list defines the priorities (high, normal or low)
     *    of the task markers issued by the translation.
     *    If the default is specified, the priority of each task marker is "NORMAL".
     *     - option id:         "org.eclipse.cdt.core.transltaion.taskPriorities"
     *     - possible values:   { "<priority>[,<priority>]*" } where <priority> is one of "HIGH", "NORMAL" or "LOW"
     *     - default:           ""
     * 
     * CORE / Specify Default Source Encoding Format
     *    Get the encoding format for translated sources. This setting is read-only, it is equivalent
     *    to 'ResourcesPlugin.getEncoding()'.
     *     - option id:         "org.eclipse.cdt.core.encoding"
     *     - possible values:   { any of the supported encoding names}.
     *     - default:           <platform default>
     * </pre>
     * 
     * @return a mutable map containing the default settings of all known options
     *   (key type: <code>String</code>; value type: <code>String</code>)
     * @see #setOptions
     */
    
    public static HashMap getDefaultOptions()
    {
        HashMap defaultOptions = new HashMap(10);

        // see #initializeDefaultPluginPreferences() for changing default settings
        Preferences preferences = getDefault().getPluginPreferences();
        HashSet optionNames = CModelManager.OptionNames;
        
        // get preferences set to their default
        String[] defaultPropertyNames = preferences.defaultPropertyNames();
        for (int i = 0; i < defaultPropertyNames.length; i++){
            String propertyName = defaultPropertyNames[i];
            if (optionNames.contains(propertyName)) {
                defaultOptions.put(propertyName, preferences.getDefaultString(propertyName));
            }
        }       
        // get preferences not set to their default
        String[] propertyNames = preferences.propertyNames();
        for (int i = 0; i < propertyNames.length; i++){
            String propertyName = propertyNames[i];
            if (optionNames.contains(propertyName)) {
                defaultOptions.put(propertyName, preferences.getDefaultString(propertyName));
            }
        }       
        // get encoding through resource plugin
        defaultOptions.put(CORE_ENCODING, ResourcesPlugin.getEncoding()); 
        
        return defaultOptions;
    }

   
    /**
     * Helper method for returning one option value only. Equivalent to <code>(String)CCorePlugin.getOptions().get(optionName)</code>
     * Note that it may answer <code>null</code> if this option does not exist.
     * <p>
     * For a complete description of the configurable options, see <code>getDefaultOptions</code>.
     * </p>
     * 
     * @param optionName the name of an option
     * @return the String value of a given option
     * @see CCorePlugin#getDefaultOptions
     */
    public static String getOption(String optionName) {
        
        if (CORE_ENCODING.equals(optionName)){
            return ResourcesPlugin.getEncoding();
        }
        if (CModelManager.OptionNames.contains(optionName)){
            Preferences preferences = getDefault().getPluginPreferences();
            return preferences.getString(optionName).trim();
        }
        return null;
    }
    
    /**
     * Returns the table of the current options. Initially, all options have their default values,
     * and this method returns a table that includes all known options.
     * <p>
     * For a complete description of the configurable options, see <code>getDefaultOptions</code>.
     * </p>
     * 
     * @return table of current settings of all options 
     *   (key type: <code>String</code>; value type: <code>String</code>)
     * @see CCorePlugin#getDefaultOptions
     */
    public static HashMap getOptions() {
        
        HashMap options = new HashMap(10);

        // see #initializeDefaultPluginPreferences() for changing default settings
        Plugin plugin = getDefault();
        if (plugin != null) {
            Preferences preferences = plugin.getPluginPreferences();
            HashSet optionNames = CModelManager.OptionNames;
            
            // get preferences set to their default
            String[] defaultPropertyNames = preferences.defaultPropertyNames();
            for (int i = 0; i < defaultPropertyNames.length; i++){
                String propertyName = defaultPropertyNames[i];
                if (optionNames.contains(propertyName)){
                    options.put(propertyName, preferences.getDefaultString(propertyName));
                }
            }       
            // get preferences not set to their default
            String[] propertyNames = preferences.propertyNames();
            for (int i = 0; i < propertyNames.length; i++){
                String propertyName = propertyNames[i];
                if (optionNames.contains(propertyName)){
                    options.put(propertyName, preferences.getString(propertyName).trim());
                }
            }       
            // get encoding through resource plugin
            options.put(CORE_ENCODING, ResourcesPlugin.getEncoding());
        }
        return options;
    }

    /**
     * Sets the current table of options. All and only the options explicitly included in the given table 
     * are remembered; all previous option settings are forgotten, including ones not explicitly
     * mentioned.
     * <p>
     * For a complete description of the configurable options, see <code>getDefaultOptions</code>.
     * </p>
     * 
     * @param newOptions the new options (key type: <code>String</code>; value type: <code>String</code>),
     *   or <code>null</code> to reset all options to their default values
     * @see CCorePlugin#getDefaultOptions
     */
    public static void setOptions(HashMap newOptions) {
    
        // see #initializeDefaultPluginPreferences() for changing default settings
        Preferences preferences = getDefault().getPluginPreferences();

        if (newOptions == null){
            newOptions = getDefaultOptions();
        }
        Iterator keys = newOptions.keySet().iterator();
        while (keys.hasNext()){
            String key = (String)keys.next();
            if (!CModelManager.OptionNames.contains(key)) continue; // unrecognized option
            if (key.equals(CORE_ENCODING)) continue; // skipped, contributed by resource prefs
            String value = (String)newOptions.get(key);
            preferences.setValue(key, value);
        }
    
        // persist options
        getDefault().savePluginPreferences();
    }    
    

	public IConsole getConsole(String id) {
		try {
	        IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID, "CBuildConsole"); //$NON-NLS-1$
			if (extension != null) {
				IExtension[] extensions = extension.getExtensions();
				for (int i = 0; i < extensions.length; i++) {
					IConfigurationElement[] configElements = extensions[i].getConfigurationElements();
					for (int j = 0; j < configElements.length; j++) {
						String consoleID = configElements[j].getAttribute("id"); //$NON-NLS-1$
						if ((id == null && consoleID == null) || (id != null && id.equals(consoleID))) {
							return (IConsole) configElements[j].createExecutableExtension("class"); //$NON-NLS-1$
						}
					}
				}
			}
		} catch (CoreException e) {
			log(e);
		}
		return new IConsole() { // return a null console
			private ConsoleOutputStream nullStream = new ConsoleOutputStream() {
			    public void write(byte[] b) throws IOException {
			    }			    
				public void write(byte[] b, int off, int len) throws IOException {
				}					
				public void write(int c) throws IOException {
				}
			};
			
			public void start(IProject project) {
			}
		    // this can be a null console....
			public ConsoleOutputStream getOutputStream() {
				return nullStream;
			}
			public ConsoleOutputStream getInfoStream() {
				return nullStream; 
			}
			public ConsoleOutputStream getErrorStream() {
				return nullStream;
			}
		};
	}

	public IConsole getConsole() {
		String consoleID = System.getProperty("org.eclipse.cdt.core.console"); //$NON-NLS-1$
		return getConsole(consoleID);
	}

	public ICExtensionReference[] getBinaryParserExtensions(IProject project) throws CoreException {
		ICExtensionReference ext[] = new ICExtensionReference[0];
		if (project != null) {
			try {
				ICDescriptor cdesc = getCProjectDescription(project);
				ICExtensionReference[] cextensions = cdesc.get(BINARY_PARSER_UNIQ_ID, true);
				if (cextensions.length > 0) {
					ArrayList list = new ArrayList(cextensions.length);
					for (int i = 0; i < cextensions.length; i++) {
						list.add(cextensions[i]);
					}
					ext = (ICExtensionReference[])list.toArray(ext);
				}
			} catch (CoreException e) {
				log(e);
			}
		}
		return ext;
	}

	/**
	 * @param project
	 * @return
	 * @throws CoreException
	 * @deprecated - use getBinaryParserExtensions(IProject project)
	 */
	public IBinaryParser[] getBinaryParser(IProject project) throws CoreException {
		IBinaryParser parsers[] = null;
		if (project != null) {
			try {
				ICDescriptor cdesc = getCProjectDescription(project);
				ICExtensionReference[] cextensions = cdesc.get(BINARY_PARSER_UNIQ_ID, true);
				if (cextensions.length > 0) {
					ArrayList list = new ArrayList(cextensions.length);
					for (int i = 0; i < cextensions.length; i++) {
						IBinaryParser parser = null;
						try {
							parser = (IBinaryParser) cextensions[i].createExtension();
						} catch (ClassCastException e) {
							//
						}
						if (parser != null) {
							list.add(parser);
						}
					}
					parsers = new IBinaryParser[list.size()];
					list.toArray(parsers);
				}
			} catch (CoreException e) {
				// ignore since we fall back to a default....
			}
		}
		if (parsers == null) {
			IBinaryParser parser = getDefaultBinaryParser();
			if (parser != null) {
				parsers = new IBinaryParser[] {parser};
			}
		}
		return parsers;
	}

	public IBinaryParser getDefaultBinaryParser() throws CoreException {
		IBinaryParser parser = null;
		String id = getPluginPreferences().getDefaultString(PREF_BINARY_PARSER);
		if (id == null || id.length() == 0) {
			id = DEFAULT_BINARY_PARSER_UNIQ_ID;
		}
        IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID, BINARY_PARSER_SIMPLE_ID);
		IExtension extension = extensionPoint.getExtension(id);
		if (extension != null) {
			IConfigurationElement element[] = extension.getConfigurationElements();
			for (int i = 0; i < element.length; i++) {
				if (element[i].getName().equalsIgnoreCase("cextension")) { //$NON-NLS-1$
					parser = (IBinaryParser) element[i].createExecutableExtension("run"); //$NON-NLS-1$
					break;
				}
			}
		} else {
			IStatus s = new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, -1, CCorePlugin.getResourceString("CCorePlugin.exception.noBinaryFormat"), null); //$NON-NLS-1$
			throw new CoreException(s);
		}
		return parser;
	}

	public CoreModel getCoreModel() {
		return fCoreModel;
	}

	public static IPDOMManager getPDOMManager() {
		return getDefault().pdomManager;
	}
	
	public IPathEntryVariableManager getPathEntryVariableManager() {
		return fPathEntryVariableManager;
	}

	/**
	 * @param project
	 * @return
	 * @throws CoreException
	 * @deprecated use getCProjetDescription(IProject project, boolean create)
	 */
	public ICDescriptor getCProjectDescription(IProject project) throws CoreException {
		return fDescriptorManager.getDescriptor(project);
	}

	/**
	 * Get the ICDescriptor for the given project, if <b>create</b> is <b>true</b> then a descriptor will be created
	 * if one does not exist.
	 * 
	 * @param project
	 * @param create
	 * @return ICDescriptor or <b>null</b> if <b>create</b> is <b>false</b> and no .cdtproject file exists on disk.
	 * @throws CoreException
	 */
	public ICDescriptor getCProjectDescription(IProject project, boolean create) throws CoreException {
		return fDescriptorManager.getDescriptor(project, create);
	}

	public void mapCProjectOwner(IProject project, String id, boolean override) throws CoreException {
		if (!override) {
			fDescriptorManager.configure(project, id);
		} else {
			fDescriptorManager.convert(project, id);
		}
	}
	
	public ICDescriptorManager getCDescriptorManager() {
		return fDescriptorManager;
	}

	/**
	 * Creates a C project resource given the project handle and description.
	 *
	 * @param description the project description to create a project resource for
	 * @param projectHandle the project handle to create a project resource for
	 * @param monitor the progress monitor to show visual progress with
	 * @param projectID required for mapping the project to an owner
	 *
	 * @exception CoreException if the operation fails
	 * @exception OperationCanceledException if the operation is canceled
	 */
	public IProject createCProject(
		final IProjectDescription description,
		final IProject projectHandle,
		IProgressMonitor monitor,
		final String projectID)
		throws CoreException, OperationCanceledException {

		getWorkspace().run(new IWorkspaceRunnable() {
			public void run(IProgressMonitor monitor) throws CoreException {
				try {
					if (monitor == null) {
						monitor = new NullProgressMonitor();
					}
					monitor.beginTask("Creating C Project...", 3); //$NON-NLS-1$
					if (!projectHandle.exists()) {
						projectHandle.create(description, new SubProgressMonitor(monitor, 1));
					}
					
					if (monitor.isCanceled()) {
						throw new OperationCanceledException();
					}
					
					// Open first.
					projectHandle.open(IResource.BACKGROUND_REFRESH, new SubProgressMonitor(monitor, 1));

					mapCProjectOwner(projectHandle, projectID, false);

					// Add C Nature ... does not add duplicates
					CProjectNature.addCNature(projectHandle, new SubProgressMonitor(monitor, 1));
				} finally {
					monitor.done();
				}
			}
		}, getWorkspace().getRoot(), 0, monitor);
		return projectHandle;
	}

	/**
	 * Method convertProjectFromCtoCC converts
	 * a C Project to a C++ Project
	 * The newProject MUST, not be null, already have a C Nature 
	 * && must NOT already have a C++ Nature
	 * 
	 * @param projectHandle
	 * @param monitor
	 * @throws CoreException
	 */

	public void convertProjectFromCtoCC(IProject projectHandle, IProgressMonitor monitor) throws CoreException {
		if ((projectHandle != null)
			&& projectHandle.hasNature(CProjectNature.C_NATURE_ID)
			&& !projectHandle.hasNature(CCProjectNature.CC_NATURE_ID)) {
			// Add C++ Nature ... does not add duplicates        
			CCProjectNature.addCCNature(projectHandle, monitor);
		}
	}

	/**
	 * Method to convert a project to a C nature 
	 * All checks should have been done externally
	 * (as in the Conversion Wizards). 
	 * This method blindly does the conversion.
	 * 
	 * @param project
	 * @param String targetNature
	 * @param monitor
	 * @param projectID
	 * @exception CoreException
	 */

	public void convertProjectToC(IProject projectHandle, IProgressMonitor monitor, String projectID)
		throws CoreException {
		if ((projectHandle == null) || (monitor == null) || (projectID == null)) {
			return;
		}
		IWorkspace workspace = ResourcesPlugin.getWorkspace();
		IProjectDescription description = workspace.newProjectDescription(projectHandle.getName());
		description.setLocation(projectHandle.getFullPath());
		createCProject(description, projectHandle, monitor, projectID);
	}

	/**
	 * Method to convert a project to a C++ nature 
	 * 
	 * @param project
	 * @param String targetNature
	 * @param monitor
	 * @param projectID
	 * @exception CoreException
	 */

	public void convertProjectToCC(IProject projectHandle, IProgressMonitor monitor, String projectID)
		throws CoreException {
		if ((projectHandle == null) || (monitor == null) || (projectID == null)) {
			return;
		}
		createCProject(projectHandle.getDescription(), projectHandle, monitor, projectID);
		// now add C++ nature
		convertProjectFromCtoCC(projectHandle, monitor);
	}

	/**
	 * Get the IProcessList contributed interface for the platform.
	 * @return IProcessList
	 */
	public IProcessList getProcessList() throws CoreException {
        IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID, "ProcessList"); //$NON-NLS-1$
		if (extension != null) {
			IExtension[] extensions = extension.getExtensions();
			IConfigurationElement defaultContributor = null;
			for (int i = 0; i < extensions.length; i++) {
				IConfigurationElement[] configElements = extensions[i].getConfigurationElements();
				for (int j = 0; j < configElements.length; j++) {
					if (configElements[j].getName().equals("processList")) { //$NON-NLS-1$
						String platform = configElements[j].getAttribute("platform"); //$NON-NLS-1$
						if (platform == null ) { // first contrbutor found with not platform will be default.
							if (defaultContributor == null) {
								defaultContributor = configElements[j];
							}
						} else if (platform.equals(Platform.getOS())) {
							// found explicit contributor for this platform.
							return (IProcessList) configElements[0].createExecutableExtension("class"); //$NON-NLS-1$
						}
					}
				}
			}
			if ( defaultContributor != null) { 
				return (IProcessList) defaultContributor.createExecutableExtension("class"); //$NON-NLS-1$
			}
		}
		return null;
		
	}
	
	/**
	 * Array of error parsers ids.
	 * @return
	 */
	public String[] getAllErrorParsersIDs() {
        IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID, ERROR_PARSER_SIMPLE_ID);
		String[] empty = new String[0];
		if (extension != null) {
			IExtension[] extensions = extension.getExtensions();
			ArrayList list = new ArrayList(extensions.length);
			for (int i = 0; i < extensions.length; i++) {
				list.add(extensions[i].getUniqueIdentifier());
			}
			return (String[]) list.toArray(empty);
		}
		return empty;
	}

	public IErrorParser[] getErrorParser(String id) {
		IErrorParser[] empty = new IErrorParser[0];
		try {
	        IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID, ERROR_PARSER_SIMPLE_ID);
			if (extension != null) {
				IExtension[] extensions = extension.getExtensions();
				List list = new ArrayList(extensions.length);
				for (int i = 0; i < extensions.length; i++) {
					String parserID = extensions[i].getUniqueIdentifier();
					if ((id == null && parserID != null) || (id != null && id.equals(parserID))) {
						IConfigurationElement[] configElements = extensions[i]. getConfigurationElements();
						for (int j = 0; j < configElements.length; j++) {
							IErrorParser parser = (IErrorParser)configElements[j].createExecutableExtension("class"); //$NON-NLS-1$
							list.add(parser);
						}
					}
				}
				return (IErrorParser[]) list.toArray(empty);
			}
		} catch (CoreException e) {
			log(e);
		}
		return empty;
	}

	public IScannerInfoProvider getScannerInfoProvider(IProject project) {
		IScannerInfoProvider provider = null;
		if (project != null) {
			try {
				ICDescriptor desc = getCProjectDescription(project);
				ICExtensionReference[] extensions = desc.get(BUILD_SCANNER_INFO_UNIQ_ID, true);
				if (extensions.length > 0)
					provider = (IScannerInfoProvider) extensions[0].createExtension();
			} catch (CoreException e) {
				// log(e);
			}
			if ( provider == null) {
				return ScannerProvider.getInstance();
			}
		}
		return provider;
	}

	/**
	 * Helper function, returning the contenttype for a filename
	 * Same as: <p><p>
	 * 	getContentType(null, filename)
	 * <br>
	 * @param project
	 * @param name
	 * @return
	 */
	public static IContentType getContentType(String filename) {
		return getContentType(null, filename);
	}
	
	/**
	 * Helper function, returning the contenttype for a filename
	 * @param project
	 * @param name
	 * @return
	 */
	public static IContentType getContentType(IProject project, String filename) {
		// Always try in the workspace (for multi-language support)
		// try with the project settings
		if (project != null) {
			try {
				IContentTypeMatcher matcher = project.getContentTypeMatcher();
				IContentType ct = matcher.findContentTypeFor(filename);
				if (ct != null) return ct;
			} catch (CoreException e) {
				// ignore. 
			}
		}
		// Try in the workspace.
		IContentTypeManager manager = Platform.getContentTypeManager();
		return manager.findContentTypeFor(filename);
	}


	private static final String MODEL = CCorePlugin.PLUGIN_ID + "/debug/model" ; //$NON-NLS-1$
	private static final String PARSER = CCorePlugin.PLUGIN_ID + "/debug/parser" ; //$NON-NLS-1$
	private static final String SCANNER = CCorePlugin.PLUGIN_ID + "/debug/scanner"; //$NON-NLS-1$
	private static final String DELTA = CCorePlugin.PLUGIN_ID + "/debug/deltaprocessor" ; //$NON-NLS-1$
	//private static final String CONTENTASSIST = CCorePlugin.PLUGIN_ID + "/debug/contentassist" ; //$NON-NLS-1$

	/**
	 * Configure the plugin with respect to option settings defined in ".options" file
	 */
	public void configurePluginDebugOptions() {
		
		if(CCorePlugin.getDefault().isDebugging()) {
			String option = Platform.getDebugOption(PARSER);
			if(option != null) Util.VERBOSE_PARSER = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
		
			option = Platform.getDebugOption(SCANNER);
			if( option != null ) Util.VERBOSE_SCANNER = option.equalsIgnoreCase("true"); //$NON-NLS-1$
			
			option = Platform.getDebugOption(MODEL);
			if(option != null) Util.VERBOSE_MODEL = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
			
			option = Platform.getDebugOption(DELTA);
			if(option != null) DeltaProcessor.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
			
		}
	}

	// Preference to turn on/off the use of structural parse mode to build the CModel
	public void setStructuralParseMode(boolean useNewParser) {
		getPluginPreferences().setValue(PREF_USE_STRUCTURAL_PARSE_MODE, useNewParser);
		savePluginPreferences();
	}

	public boolean useStructuralParseMode() {
		return getPluginPreferences().getBoolean(PREF_USE_STRUCTURAL_PARSE_MODE);
	}
	
	public CDOM getDOM() {
	    return CDOM.getInstance();
	}

	
}

Back to the top