Example #1
0
		public static LineCounts operator+(LineCounts left, LineCounts right)
		{
			LineCounts counts		= new LineCounts();
			counts._files			= left._files			+ right._files;
			counts._lines			= left._lines			+ right._lines;
			counts._commentlines	= left._commentlines	+ right._commentlines;
			counts._blanklines		= left._blanklines		+ right._blanklines;
			return counts;
		}
Example #2
0
		/// <summary>
		/// Count the lines.
		/// </summary>
		/// <param name="sender">Sender.</param>
		/// <param name="e">Event arguments.</param>
		private void btnCount_Click(object sender, System.EventArgs e)
		{
			if (_files.Count == 0)
			{
				MessageBox.Show(this, "At least 1 file must be specified.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				return;
			}

			// Give a wait cursor.
			this.Cursor = Cursors.WaitCursor;

			// Reset status bar.
			this.statusBarPanel1.Text			= "Counting...";
			this.statusBar.ProgressBar.Value	= 0;
			this.statusBar.ProgressBar.Maximum	= _files.Count;
			this.statusBar.ProgressBar.Visible	= true;

			// Disable controls so no one tries any monkey business.
            this.SetControls(false);

			// Reset counters.
			_lineCounts		= new LineCounts();
			_fileCount		= 0;
			_currentFile	= 0;

			// Store the filter index in case a wise guy decides to change it before the counting
			// has started.  The count threads retrieve this value to determine the commenting style
			// to use.
			_winRegistryAccess.LastCommentingStyle		= this.cmbbxCommentStyle.SelectedItem.ToString();

			// Store the comment style that was used.
			_winRegistryAccess.CommentMode		= _commentMode;

			// Log file.
			_log = new StreamWriter(_logFile, false);

			// Initiate threads.
			_startedThreadJoin = false;
			for (int i = 0; i < _nProcessors; i++)
			{
				// Create the thread.
				_threads[i]				= new Thread(new ThreadStart(CountLines));

				// We use the thread number as the name.  That way we can uniquely trigger one of the 
				// reset events once a thread is finished processing.
				_threads[i].Name		= i.ToString();

				// A manual reset event is used because it won't set back to the initial state like the auto
				// reset event.  We are waiting for all events to set before continuing.
				_threadDoneEvents[i]	= new ManualResetEvent(false);

				// Start the thread.
				_threads[i].Start();
			}
		}
Example #3
0
		/// <summary>
		/// Count the lines in a file.
		/// </summary>
		/// <param name="filename">Name of the file.</param>
		/// <returns>The counts in a LineCounts object.</returns>
		public LineCounts Count(string filename)
		{
			// Line counts.
			LineCounts linecounts = new LineCounts();
			linecounts.IncrementFileCount();

			// Open the file.
			System.IO.StreamReader reader = System.IO.File.OpenText(filename);

			// Loop over the lines in the file.
			string line;
			while ((line = reader.ReadLine()) != null)
			{
				// Count the total number of lines counted.  Should equal comments+blanks+code.
				linecounts.IncrementLineCount();

				// Check for comments.
				if (IsComment(line))
				{
					linecounts.IncrementCommentLineCount();
					continue;
				}

				// Check for blank lines.  Need to do this after checking for comments so that we can count
				// blank lines in long comments as comments.
				if (line.Trim() == "")
				{
					linecounts.IncrementBlankLineCount();
				}
			}

			// Close the file.
			reader.Close();

			return linecounts;
		}
Example #4
0
		/// <summary>
		/// Worker function for line counting threads.
		/// </summary>
		private void CountLines()
		{
			// Loop through file names.  When all of the file names have been processed
			// a break is called to exit the loop.
			while (true)
			{
				string filename;

				// Acquire the next file name, insuring we don't miss a name by using a
				// lock to limit access to one thread at a time.
				_fileNameLock.AcquireWriterLock(-1);
				if (_currentFile >= _files.Count)
				{
					// No more files, release the lock and break out of while loop.
					_fileNameLock.ReleaseWriterLock();

					// Figure out which thread we are and signal the event that says we are done with
					// our work.  We have to wait here until all threads are done because each thread
					// updates the GUI with it's results after a file has been processed and the next
					// step is to 
					int name = System.Convert.ToInt32(Thread.CurrentThread.Name);
					_threadDoneEvents[name].Set();
					WaitHandle.WaitAll(_threadDoneEvents);

					// We are locking this part with a semaphore to make sure only one gets access at a
					// time.  That way we don't have a race condition to calling the thread joining and
					// final GUI update.  Note, because of this semaphore it might not be strickly necessary
					// to join the threads (they are done with their work by that time), but it doesn't matter
					// anyway.
					_jointhreadsemaphore.WaitOne();

					// Make sure we don't try to rejoin threads and reactive the controls once they 
					// have already been joined.
					if (!_startedThreadJoin)
					{
						_startedThreadJoin = true;
						this.BeginInvoke(new UICallBack(JoinThreads));
					}
					_jointhreadsemaphore.Release();
					break;
				}

				filename = _files[_currentFile++].ToString();
				_fileNameLock.ReleaseWriterLock();

				// Use local counters so that we can process an entire file and then update the
				// master counters and gui.  This limits the number of read/write locks required
				// and the number of gui updates to a reasonable amount so that the counting isn't
				// done too slowly.
				LineCounts linecounts = _fileTypes.Count(filename);

				// Update the line counters and display.
				_lineCountLock.AcquireWriterLock(-1);
				_lineCounts += linecounts;

				// Update the file counter and display.
				_fileCount++;
				_lineCountLock.ReleaseWriterLock();

				// Do callback to update the user interface.
				this.Invoke(new UICallBack(UpdateUICounts));
			}
		}