Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

Thursday, September 09, 2010

CVS: Web GUI by FreeBSD CVSweb

Introduction

CVSweb is a WWW interface for CVS repositories with which you can browse a file hierarchy on your browser to view each file's revision history in a very handy manner.

Installation

# Web interface for CVS repositories 
yum install cvsweb

# Runtime Logging for C++ 
yum install rlog

# Revision Control System (RCS) file version management tools 
yum install rcs

# CVS/RCS repository grapher 
yum install cvsgraph

# A plain ASCII to PostScript converter 
yum install enscript

Configuration: Repository

Update the repository setting in CVSweb configuration file:

vi /etc/cvsweb/cvsweb.conf
@CVSrepositories = (
      'local'   => ['Local Repository', '/var/cvs'],
#       'freebsd' => ['FreeBSD',          '/var/ncvs'],
#       'openbsd' => ['OpenBSD',          '/var/ncvs'],
#       'netbsd'  => ['NetBSD',           '/var/ncvs'],
#       'ruby'    => ['Ruby',             '/var/anoncvs/ruby'],
);

Configuration: Web Server

CVSweb is a cgi program runs on Apache, the Apache configuration should configuration similar to this:

ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"

Make sure the CVSweb cgi is place in the path specify in ScriptAlias.

Configuration: Syntax Highlighter

The syntax highlighter works if enscript package is installed. CVSweb keep the enscript configuration in /etc/cvsweb/cvsweb.conf.

The following example specify Delphi as syntax highlighter for pascal (.pas) file.

vi /etc/cvsweb/cvsweb.conf
%enscript_types =
(
 'ada'          => qr/\.ad(s|b|a)$/o,
 'asm'          => qr/\.[Ss]$/o,
 'awk'          => qr/\.awk$/o,
 'bash'         => qr/\.(bash(_profile|rc)|inputrc)$/o,
 'c'            => qr/\.(c|h)$/o,
 'changelog'    => qr/^changelog$/io,
 'cpp'          => qr/\.(c\+\+|C|H|cpp|cc|cxx)$/o,
 'csh'          => qr/\.(csh(rc)?|log(in|out)|history)$/o,
 'elisp'        => qr/\.e(l|macs)$/o,
 'fortran'      => qr/\.[fF]$/o,
 'haskell'      => qr/\.(l?h|l?g)s$/o,
 'html'         => qr/\.x?html?$/o,
 'idl'          => qr/\.idl$/o,
 'inf'          => qr/\.inf$/io,
 'java'         => qr/\.java$/o,
 'javascript'   => qr/\.(js|pac)$/o,
 'ksh'          => qr/\.ksh$/o,
 'm4'           => qr/\.m4$/o,
 'makefile'     => qr/(GNU)?[Mm]akefile(?!\.PL\b)|\.(ma?ke?|am)$/o,
 'matlab'       => qr/\.m$/o,
 'nroff'        => qr/\.man$/o,
 'delphi'       => qr/\.p(as|p)?$/io,
 'perl'         => qr/\.p(m|(er)?l)$/io,
 'postscript'   => qr/\.e?ps$/io,
 'python'       => qr/\.py$/o,
 'rfc'          => qr/\b((rfc|draft)\..*\.txt)$/o,
 'scheme'       => qr/\.(scm|scheme)$/o,
 'sh'           => qr/\.sh$/o,
 'skill'        => qr/\.il$/o,
 'sql'          => qr/\.sql$/o,
 'states'       => qr/\.st$/o,
 'synopsys'     => qr/\.s(cr|yn(th)?)$/o,
 'tcl'          => qr/\.tcl$/o,
 'tcsh'         => qr/\.tcshrc$/o,
 'tex'          => qr/\.tex$/o,
 'vba'          => qr/\.vba$/o,
 'verilog'      => qr/\.(v|vh)$/o,
 'vhdl'         => qr/\.vhdl?$/o,
 'vrml'         => qr/\.wrl$/o,
 'wmlscript'    => qr/\.wmls(cript)?$/o,
 'zsh'          => qr/\.(zsh(env|rc)|z(profile|log(in|out)))$/o,
);

Using CVSweb

Launch your favorite web browser and navigate to

http://<cvs-host>/cgi-bin/cvsweb.cgi

Troubleshoot: CVS folders doesn’t show up

The CVS folder specify in local repository of cvsweb.conf may not have appropriate access permission for cvsweb.cgi. You may use the following command to change the folder permission:

chmod o+rx <cvs-folder>

Troubleshoot: Encounter permission denied when browse a CVS tree

A CVS repository tree may contain arbitrary levels of folder. The tree may not have appropriate access permission for cvsweb.cgi. You may use the following command to change all the sub folders found in CVS repository:

find . -type d -exec chmod o+rx '{}' \;

Reference

  1. FreeBDS CVSweb Project. URL: http://www.freebsd.org/projects/cvsweb.html

Wednesday, September 08, 2010

CVS: Branching, Merging and Tagging

Introduction

CVS a.k.a. concurrent version system is the software version control in the field of software development.  Branching and Merging features in CVS allow developer to manage same piece of source file for several release and develop these release in parallel without interrupting each others.

Please note that the examples shown below are using WinCVS 1.2.

CVS Branching

For example, I have a file in CVS repository: App.DIY.Reg.pas.  The latest version for the file is 1.2 (The graph view is triggered with Ctrl+G Graph Selection):

1

Let look at the following scenario to see how could CVS branching manage the case:

I would like to make changes to a file.  These new changes is not yet ready for release to public. It may stay in CVS repository as internal or beta version for some time.  It will merge with main branch of the source file until it is mature.  However, the main branch may change due to bugs reported during the beta release period.  The bug fixed in main branch may merge with sub branch too during the beta release period.

The main trunk of a file in CVS is termed as “HEAD”.  You should define a meaningful name or tag to other branches but not the “HEAD” tag.  “HEAD” a reserve tag for main trunk.

Let us make some changes to local working versio of the file.  It will turn to red color once I make some changes:

2

The new changes is not ready for main release yet.  I am going to create a branch call BETA in version 1.2.  Please note that branch tag is case sensitive.

There are 2 ways to create a branch:

  1. Access via main menu.  Modify | Create a branch on selection... :

    4
  2. Click the Fork Selection of Tags tool bar icon:

    3

A windows with title “Create branch settings” prompt out:

5

Enter branch name and press OK button to create a “BETA” branch for the file.  We will leave an option “Check that the files are unmodified before branching” unchecked in this case.

The version of the file in graph view has a BETA branch shown:

6

Now everything seems ready and we are going to commit the local changes to BETA branch.  We will in trouble if we commit the changes now.  The changes we commit will stay in main trunk as version 1.3:

8

This is due to the sticky tag for the file in local copy is not mark as “BETA” tag.  It simply means we are working with the copy of main trunk in our local repository.  Whatever changes we commit will stay with main trunk:

7

We may update our local copy stick with "BETA” tag with CVS Update Selection:

9

Enter the stick tag “BETA” and press OK button to update your copy of file as BETA.

A

You will notice there is a tag BETA stick to the file after Update Selection.  Commit the local changes now and it will shown in BETA branch.  Please note also the file revision will update to 1.2.2.1 in this case:

B

We may remove the sticky tag and back to main trunk by checking an option “Reset any sticky date/tag/’-k' options” in Update Selection:

C

The local copy will become version 1.2 in this case:

D

We may always switch between HEAD and BETA branch by:

  1. “Reset any sticky date/tag/’-k' options” in Update Selection
  2. Retrieve rev./tag/branch of Stick options in Update Selection

respectively.

Now, assume we have another local working copy of the source with version 1.2 and empty sticky tag (a.k.a main trunk).  Perform Update Selection to this file will remain as 1.2.  It won’t update to 1.2.2.1 of BETA branch. unless we update the sticky tag to BETA.  We may continue making changes to version 1.2 and commit it as version 1.3, 1.4 or 1.5 and so:

E

CVS Merging

Let us back to version 1.2.2.1 of BETA branch.  We decided to merge the changes of 1.5 in main trunk to 1.2.2.1 of BETA branch.

Use the “Merge options” of Update Selection to merge main trunk into BETA branch:

F

Press OK button to proceed the merge operation.  Your local copy will then merge with main trunk.  You may decide to commit under BETA branch.  The following graph shows the result of commit work:

G

Now we decide to end the BETA branch and merge all changes from BETA branch to main trunk.  Let’s back to main trunk copy and perform the merging work:

H

After commit the changes, CVS repository will have the following version:

I

The version 1.6 is result of the merge of 1.5 in main trunk and 1.2.2.2 BETA branch.

CVS Tagging

CVS tagging allows you to mark an indication to a file for future reference.  A common usage for tagging is tag the source files with release or build number for future reference.  You may check out particular tag of source files for debugging purpose in future.

Here, we continue with CVS branching and merging example to use the CVS tagging feature to mark both 1.2.2.2 and 1.6 as “BETA_END”  and “BETA_MERGE” respectively.

To tag a version, use either:

  1. Access via main menu.  Modify | Create a tag on selection... :

    M
  2. Click the Tag Selection of Tags tool bar icon:

    L

A windows with title “Create tag settings” prompt out:

K

The following graph show the result of tagging:

J

The tagging is for reference only.  Remember that version 1.2.2.2 still exist in the CVS repository.  We may always go back to it anytime.

Working with main trunk and branch together in difference folders

When we start using branch in CVS repository, there may be a need to work with main trunk and difference branches together in same machine.  Check out a local copy from main trunk is easy:  Just check out as usual without any sticky tag.

Check out a local copy from branch may need extra care.  In real world example, only some of the source files may have branch.  Majority of source files may not have branch or already merge to main trunk.  If we check out a module with sticky options:

N

You will only get files with BETA tag:

O

This is not what we want in most situation.  We still need other files from main trunk in order to build a complete BETA release.  To check out the files from main trunk, check the option “If no matching revision is found, use the most recent one” :

P

Press the OK button and the local source copy will have:

Q

The same usage is also applicable to Update Selection.

Now, you will see all files in your local copy have BETA sticky tag.  However, this doesn’t mean all files have BETA branch in CVS repository.  In the example, only App.DIY.Reg.pas has BETA branch and the rest are not.  This always confuse the CVS user.

Now, if you make changes to a file App.DIY.pas and you decide to put it in BETA branch.  If you attempt to commit the local changes in this example, you will encounter:

cvs commit: file `App.DIY.pas' had a conflict and has not been modified
cvs [commit aborted]: correct above errors first!

This is due to App.DIY.pas doesn’t has BETA branch in CVS repository, you have to create a new BETA branch for it first before you can commit.  Refer to CVS Branching in early section of this article.

Wednesday, April 07, 2010

ANT: Java Heap Space Error

From time to time, when we use ANT script to perform jobs that drag some how longer time.  We may encounter Java heap space out of memory error.

The default heap space allocated for Java heap could be 128MB.  You may adjust the Java heap size from ANT via environment variable ANT_OPTS:

set ANT_OPTS=–Xmx512m

You may try to set in the system environment variable that is available to all users.  If it fail with message “Incompatible minimum and maximum heap sizes specified”, try remove the ANT_OPTS in system environment variable and set it in your home user account.

Friday, March 27, 2009

BITs operation in SQL

Introduction

The BIT we talk here is the smallest unit in binary: 0 and 1.

Using bit for attributes

If we want to assign a set of attributes to an item, a common practice is using mutually exclusive bit value to indicate each attribute and using “SUM” or “OR” operator to group assigned attributes as a single integer value.  This solution is neat and fast to be implement in programming.

For example, a file in a file system may have attributes of

  • READ
  • WRITE
  • EXECUTE

We may assign READ, READ and WRITE , READ and EXECUTE, or any combination of attributes to the file.  We may use only a single 32 bits (or 64 bits) integer to indicate these attributes.  This design allow us to expand the attribute set in future.  This is a more practical approach compare to using one field for each attribute design.

In the above example, we may define

  • 1 (0001) – READ
  • 2 (0010) – WRITE
  • 4 (0100) – EXECUTE
  • 8 (1000) - HIDDEN

Note that each attribute should occupy a bit position and it shouldn’t overlap with other attributes else we will not able to identify their actual attributes in later stage.

Thus,

  • 5 (0101) indicate READ + EXECUTE
  • 2 (0010) indicate WRITE
  • 7 (0111) indicate READ + WRITE + EXECUTE
  • 6 (0110) indicate EXECUTE + WRITE
  • 0 (0000) indicate No attributes defined

Using bits for states

In some situation we need a range of bits to indicate some kind of states.  The one bit one attribute design doesn’t fit well here.

For example, a document may have one of the following states but never possess more than one state at a time:

  • Draft
  • Waiting for approval
  • Approved
  • Rejected
  • Canceled

There are 5 states above, we may use 4 bits (3 bits is sufficient for above case) to present the state as

  • 1 (0001) – Draft
  • 2 (0010) – Waiting for approval
  • 3 (0011) – Approved
  • 4 (0100) – Rejected
  • 5 (0101) - Canceled

Programming attributes in programming language

We may use only a single variable of type INTEGER to indicate an attribute sets.  This design allow the attribute sets to expand in future without changing much in old codes.

Define attributes and states

Assume bit 0-3 (4 bits) is reserved for states and bit 4-7 (4 bits) is reserved for attributes.

const
  at_READ    = $10;
  at_WRITE   = $20;
  at_EXECUTE = $40;
  at_HIDDEN  = $80;

  st_Draft    = 1;
  st_Waiting  = 2;
  st_Approved = 3;
  st_Rejected = 4;
  st_Canceled = 5;

Set attributes

Use bit operator OR to set attribute:

  • B := at_READ OR at_WRITE;  // assign READ and WRITE
  • B := B OR at_READ;  // assign READ to B regardless of B READ attribute or not

Unset attribute

Use bit operator AND NOT to unset attribute:

  • B := B AND (NOT at_READ) // unset READ of B
  • B := B AND (NOT at_READ) AND (NOT at_WRITE) // unset READ and WRITE of B

Test an attribute is set

Use AND operator to check if READ attribute is set:

  • (B and at_READ) = at_READ

Test state

Bits 0-3 is reserve for states, to test if the item is canceled:

  • B and $0F = st_Canceled

Set State

Set state to st_Rejected (4):

  • B := B and $F0 + st_Rejected

Programming attributes in SQL

It wasn’t easy to perform the above operations in SQL unless the SQL service support bit operator or function.  The following solution is using normal mathematical operation to achieve the same bit operation as programming language without using special function.

Division operator in SQL

The division operator ( / ) in SQL has different behavior for integer and floating point division.  For example:

  • Integer division:
    • 1 / 2 is 0
    • 2 / 2 is 1
  • Floating point division:
    • 1 / 2.0 is 0.5
    • 2 / 2.0 is 1.0

An integer value divided by 2 is similar as performing a right shift operation for binary value.  For example,

  • 10 / 2 = 5
  • 9 / 2 = 4

Perform a right shift in binary for above numbers:

  • 1010 shr 1 = 101 (5 in decimal)
  • 1001 shr 1 = 100 (4 in decimal)

Likewise,

  • perform 2 right shifts is dividing the value by 4
  • perform 3 right shifts is dividing the value by 8
  • perform n right shifts is dividing the value by 2^n

Multiplication operator in SQL

The multiplication operator ( * ) for integer works similarly as performing a left shift operation for binary value.  For example,

  • 5 * 2 = 10
  • 7 * 2 = 14

Perform a left shift in binary for above numbers:

  • 101 shl 1 = 1010 (10 in decimal)
  • 111 shl 1 = 1110 (14 in decimal)

Likewise,

  • perform 2 left shifts is multiplying the value by 4
  • perform 3 left shifts is multiplying the value by 8
  • perform n left shifts is multiplying the value by 2^n

Test the value of least significant bit

The least significant bit of a number is the right most bit in binary presentation of the number.  For example, the least significant bit of 10 (1010 in binary) is 0 and 9 (1001 in binary) is 1.

We may use both integer or floating point division to check the least significant bit of a number:

i = (n / 2) – (n / 2.0)

i = 0 indicate least significant bit is off
i <> 0 indicate least significant bit is on

For example,

  • 10 / 2 – 10 / 2.0 = 5 – 5.0 = 0 (least significant bit is 0)
  • 9 / 2 – 9 / 2.0 = 4 – 4.5 = –0.5 (least significant bit is 1)

Test an attribute is set

To check if an at_EXECUTE ($40) attribute is set in SQL, we may use

WHERE ((Attribute / 64 / 2) - (Attribute / 64 / 2.0) <> 0

Set attribute

The following SQL set at_EXECUTE ($40) for rows that don’t have at_EXECUTE set:

UPDATE Table
   SET Attribute = Attribute + 64
WHERE ((Attribute / 64 / 2) - (Attribute / 64 / 2.0) = 0

Unset attribute

The following SQL unset at_EXECUTE ($40) for rows that have at_EXECUTE set:

UPDATE Table
   SET Attribute = Attribute – 64
WHERE ((Attribute / 64 / 2) - (Attribute / 64 / 2.0) <> 0

Test States

The following SQL retrieve all rows that has state of st_Canceled (5):

SELECT *
  FROM Table
WHERE Attribute – (Attribute / 16) * 16 = 5

Set States

The following SQL set all rows to state of st_Canceled (5):

UPDATE Table
   SET Attribute = (Attribute / 16) * 16 + 5