program define labmap
*! NJC 1.0.0 12 June 2001
	version 6
	gettoken vallbl 0 : 0, parse(" ,")

	syntax , Values(numlist min=1 int) [ Labels(numlist min=1) /*
	*/ First(numlist min=1 max=1) Step(numlist min=1 max=1) /*
	*/ Maximum(numlist min=1 max=1) Add modify nofix /*
	*/ PREfix(str) POSTfix(str) List ]

	local nvals : word count `values'
	tokenize `values'

	* do labels exist?
	capture label list `vallbl'
	local exists = _rc == 0

	* if so, can we change them?
	if `exists' {
		if "`add'`modify'" == "" { Onerror 1 }
		else if "`modify'" == "" {
			local i = 1
			while `i' <= `nvals' {
				local exlabel : label `vallbl' ``i''
				if "`exlabel'" != "``i''" {
					Onerror 2
				}
				local i = `i' + 1
			}
		}
	}

	* correct syntax for new labels?
	if "`labels'" == "" {
		if "`first'" == "" | "`step'" == "" { Onerror 3 }
	}
	else {
		if "`first'`step'" != "" { Onerror 3 }
	}

	* # of values == # of labels?
	if "`labels'" != "" {
		local nlabs : word count `labels'
		if `nvals' != `nlabs' { Onerror 4 }
	}

	* OK to set up -label- arguments
	local i = 1
	if "`labels'" != "" {
		while `i' <= `nvals' {
			local l : word `i' of `labels'
		        local largs `"`largs' ``i'' "`prefix'`l'`postfix'""'
			local i = `i' + 1
		}
	}
	else {
		local l "`first'"
		local s "`step'"
		local m "`maximum'"
		if "`m'" == "" { local m = . }

		while `i' <= `nvals' {
			local largs `"`largs' ``i'' "`prefix'`l'`postfix'""'
		local l = cond(`l' + `s' <= `m', `l' + `s', mod(`l' + `s', `m'))
        		local i = `i' + 1
		}
	}

	* now change labels
	label def `vallbl' `largs', `nofix' modify

	* list if desired
	if "`list'" != "" {
		di
		la li `vallbl'
	}

end

program define Onerror
	args code

	if `code' == 1 {
		di in r "need to specify add or modify option"
	}
	else if `code' == 2 {
		di in r "need to specify modify option"
	}
	else if `code' == 3 {
		di in r "must choose between labels() and first() step()"
	}
	else if `code' == 4 {
		di in r "number of values does not match number of labels"
	}

	exit 198
end