git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Dan Holmsand <holmsand@gmail.com>
To: git@vger.kernel.org
Subject: Re: [PATCH Cogito] Improve option parsing for cg-log
Date: Fri, 13 May 2005 13:32:51 +0200	[thread overview]
Message-ID: <42849063.1040003@gmail.com> (raw)
In-Reply-To: <20050513054140.GF16464@pasky.ji.cz>

[-- Attachment #1: Type: text/plain, Size: 442 bytes --]

Petr Baudis wrote:
> The -r option still must be after all the other options.
> 

I've been thinking about option parsing as well, and I think cogito 
could use a more "getopt-like" handling of options. "cg-log -cf"
or "cg-diff -rorigin" is just so much easier to type...

The attached patch implements that for cg-log and cg-diff, by means of 
two new helper functions in cg-Xlib. It also improves error-handling a bit.

How about it?

/dan

[-- Attachment #2: optparse.patch --]
[-- Type: text/x-patch, Size: 5284 bytes --]

Better option parsing in cg-diff and cg-log. Uses a new function, optparse,
in cg-Xlib, that allows for getopt-style option parsing.

This means that "cg-log -cf" is equivalent to "cg-log -c -f", as is
"cg-log -fc" and "cg-log -fc -rHEAD --" and even
"cg-log --file-list --color --revision=HEAD".

---

 cg-Xlib |   33 ++++++++++++++++++++++++++++++
 cg-diff |   53 ++++++++++++++++++++++---------------------------
 cg-log  |   69 ++++++++++++++++++++++++----------------------------------------
 3 files changed, 83 insertions(+), 72 deletions(-)

Index: cg-Xlib
===================================================================
--- de641904363cd3759f132ee7c0dfaf8a2ee58388/cg-Xlib  (mode:100755)
+++ 048128149b56f55427713c78a8a3ca9da811e589/cg-Xlib  (mode:100755)
@@ -62,6 +62,39 @@
 	fi
 done
 
+# option parsing
+
+opts=($@)
+
+optshift() {
+	unset opts[0]
+	opts=("${opts[@]}")
+	[ -z "$1" -o -n "$opts" ] || die "option \`$1' requires an argument"
+}
+
+optparse() {
+	[ -z "$1" ] && case $opts in
+		--) optshift; return 1 ;;
+		-*) return 0 ;;
+		*)  return 1 ;;
+	esac
+
+	local match=${1%=} minmatch=${2:-1} o=$opts val
+	[[ $1 == *= ]] && val=$match
+	case $match in
+	--*)	[ "$val" ] && o=${opts%%=*}
+		[ ${#o} -ge $((2 + $minmatch)) -a \
+			"${match:0:${#o}}" = "$o" ] || return 1
+		[[ -n "$val" && "$opts" == *=* ]] && opts[0]=${opts#*=} \
+			|| optshift $val ;;
+	-?)	[[ $o == $match* ]] || return 1
+		[[ $o != -?-* || -n "$val" ]] || die "unrecognized option \`$o'"
+		opts[0]=${o#$match}
+		[ "$opts" ] && { [ "$val" ] || opts[0]=-${opts}; } \
+			|| optshift $val ;;
+	*)	die "optparse cannot handle $1" ;;
+	esac
+}
 
 # Compatibility hacks:
 # 2005-04-26
Index: cg-diff
===================================================================
--- de641904363cd3759f132ee7c0dfaf8a2ee58388/cg-diff  (mode:100755)
+++ 048128149b56f55427713c78a8a3ca9da811e589/cg-diff  (mode:100755)
@@ -19,34 +19,33 @@
 . ${COGITO_LIB}cg-Xlib
 
 
-id1=" "
-id2=" "
-parent=
+unset id1 id2 parent
 
+while optparse; do
+	if optparse -p || optparse --parent; then
+		parent=1
+	elif optparse -r= || optparse --revision=; then
+		if [ set != "${id1+set}" ]; then
+			id1=$opts
+			if [[ "$id1" == *:* ]]; then
+				id2=${id1#*:}
+				id1=${id1%:*}
+			fi
+		else
+			[ set != "${id2+set}" ] || die "too many versions"
+			id2=$opts
+		fi
+		optshift
+	else
+		die "unrecognized option \`$opts'"
+	fi
+done
+shift $(( $# - ${#opts[*]} ))
 
-# FIXME: The commandline parsing is awful.
-
-if [ "$1" = "-p" ]; then
-	shift
-	parent=1
-fi
-
-if [ "$1" = "-r" ]; then
-	shift
-	id1=$(echo "$1": | cut -d : -f 1)
-	[ "$id1" != "$1" ] && id2=$(echo "$1": | cut -d : -f 2)
-	shift
-fi
-
-if [ "$1" = "-r" ]; then
-	shift
-	id2="$1"
-	shift
-fi
 
 if [ "$parent" ]; then
 	id2="$id1"
-	id1=$(parent-id "$id2" | head -n 1)
+	id1=$(parent-id "$id2" | head -n 1) || exit 1
 fi
 
 
@@ -58,12 +57,8 @@
 	done
 fi
 
-if [ "$id2" = " " ]; then
-	if [ "$id1" != " " ]; then
-		tree=$(tree-id "$id1")
-	else
-		tree=$(tree-id)
-	fi
+if [ set != "${id2+set}" ]; then
+	tree=$(tree-id "${id1:-HEAD}") || exit 1
 
 	# Ensure to only diff modified files
 	git-update-cache --refresh
Index: cg-log
===================================================================
--- de641904363cd3759f132ee7c0dfaf8a2ee58388/cg-log  (mode:100755)
+++ 048128149b56f55427713c78a8a3ca9da811e589/cg-log  (mode:100755)
@@ -30,18 +30,11 @@
 # at least somewhere it does. Bash is broken.
 trap exit SIGPIPE
 
-colheader=
-colauthor=
-colcommitter=
-colfiles=
-colsignoff=
-coldefault=
-list_files=
-user=
-while [ "$1" ]; do
-	# TODO: Parse -r here too.
-	case "$1" in
-	-c)
+unset colheader colauthor colcommitter colfiles colsignoff coldefault
+unset list_files log_start log_end files user
+
+while optparse; do
+	if optparse -c || optparse --color; then
 		# See terminfo(5), "Color Handling"
 		colheader="$(tput setaf 2)"    # Green
 		colauthor="$(tput setaf 6)"    # Cyan
@@ -49,21 +42,28 @@
 		colfiles="$(tput setaf 4)"     # Blue
 		colsignoff="$(tput setaf 3)"   # Yellow
 		coldefault="$(tput op)"        # Restore default
-		shift
-		;;
-	-f)
+	elif optparse -f || optparse --file-list; then
 		list_files=1
-		shift
-		;;
-	-u*)
-		user="${1#-u}"
-		shift
-		;;
-	*)
-		break
-		;;
-	esac
+	elif optparse -u= || optparse --user=; then
+		user=$opts
+		optshift
+	elif optparse -r= || optparse --revision=; then
+		if [ set != "${log_start+set}" ]; then
+			log_start=$opts
+			if [[ "$log_start" == *:* ]]; then
+				log_end=${log_start#*:}
+				log_start=${log_start%:*}
+			fi
+		else
+			[ set != "${log_end+set}" ] || die "too many revisions"
+			log_end=$opts
+		fi
+		optshift
+	else
+		die "unrecognized option \`$opts'"
+	fi
 done
+shift $(( $# - ${#opts[*]} ))
 
 list_commit_files()
 {
@@ -92,24 +92,7 @@
 	echo "$coldefault:"
 }
 
-log_start=
-log_end=
-if [ "$1" = "-r" ]; then
-	shift
-	log_start="$1"
-	shift
-	if echo "$log_start" | grep -q ':'; then
-		log_end=$(echo "$log_start" | cut -d : -f 2)
-		log_start=$(echo "$log_start" | cut -d : -f 1)
-	fi
-fi
-if [ "$1" = "-r" ]; then
-	shift
-	log_end="$1"
-	shift
-fi
-
-if [ "$log_end" ]; then
+if [ set = "${log_end+set}" ]; then
 	id1="$(commit-id $log_start)" || exit 1
 	id2="$(commit-id $log_end)" || exit 1
 	revls="git-rev-tree $id2 ^$id1"

      parent reply	other threads:[~2005-05-13 11:28 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-05-12 20:51 [PATCH Cogito] Improve option parsing for cg-log Marcel Holtmann
2005-05-12 21:13 ` Petr Baudis
2005-05-12 21:49   ` Marcel Holtmann
2005-05-13  5:41     ` Petr Baudis
2005-05-13  9:05       ` Marcel Holtmann
2005-05-17 20:16         ` Petr Baudis
2005-05-13 11:32       ` Dan Holmsand [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=42849063.1040003@gmail.com \
    --to=holmsand@gmail.com \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).