Dear Richard, All,

Finally, I've found a bit of time to implement the first draft of the
ranges functionality I was posting a couple of months ago
(http://www.mail-archive.com/fossil-users@lists.fossil-scm.org/msg07419.html).

This is my first contribution to the project so apologize if anything
is not that clean and tidy as it should be.

>From a user point of view the patch changes the way users can do
commits. First 'fossil changes' lists changes with additional column
indicating the row number, e.g.:

  1 EDITED     src/checkin.c
  2 EDITED     src/main.mk
  3 EDITED     src/makemake.tcl
  4 ADDED      src/ranges.c
  5 EDITED     win/Makefile.dmc
  6 EDITED     win/Makefile.mingw
  7 EDITED     win/Makefile.msc

Then using 'fossil commit --range|-r RANGE_LIST' the user can easily
pick only these files they want to check-in, e.g. 'fossil commit -r
1,3-4 -m "added an extension to..."' is equivalent to 'fossil commit
-m "added an extension to..." src/checkin.c src/makemake.tcl
src/ranges.c'

Internally, 'fossil changes' creates a "temporary" table in _FOSSIL_
where it stores row numbers, vfile.id and pathname. This is enough to
restore the proper file ids during 'fossil commit -r ...' and also
detect some circumstances which prevent from "safe" commit using
ranges. For example, if after above 'fossil changes' the user issues
'fossil rm src/main.mk' and then 'fossil commit -r 2', the code will
complain and guide the user to refresh the changes list.

I'd be glad if anyone can have a look on this and exercise the code to
see if the approach is reasonable.

If you like it, the next target might be 'fossil rm' and then 'fossil
extra' and 'fossil add'.

P.S. After patching the code please issue 'tclsh makemake.tcl' in the
'src' directory to regenerate src/main.mk and win makefiles.

  Cheers,
  Jacek

Attachment: ranges.patch
Description: Binary data

#include "config.h"
#include "ranges.h"
#include <errno.h>

/*
**
**
*/
static int parse_file_range_token(const char* rangeString, int* range, int startIndex) {
  char* endptr;
  errno = 0;
  range[startIndex] = strtol(rangeString, &endptr, 10);

  if (errno != 0 || range[startIndex] <= 0) {
    fossil_fatal("error parsing ranges");
  } else if (*endptr == '-') {
    char* upper = endptr;
    range[startIndex + 1] = strtol(upper, &endptr, 10);

    if (errno != 0 || *endptr != '\0' || range[startIndex + 1] == 0) {
      fossil_fatal("error parsing ranges");
    }

    return 2;
  } else if (*endptr != '\0') {
    fossil_fatal("error parsing ranges");
  }

  return 1;
}


/*
** Parses a string into an array of integers denoting value ranges. 
** The acceptable input string is in form: \d+((-\d+)?(,\d+)?)* 
** For example: '1', '1,2', '1-5,7', '1-3,20-25,9' are all acceptable.
**
** The returned array is zero-terminated and allocated on the heap.
** Negative values indicate an upper bound of a range and must be preceded by
** a positive value -- the lower bound.
**
** For the above examples the function will return following arrays:
** [1], [1, 2], [1, -5, 7], [1, -3, 20, -25, 9]
**
*/
int* parse_file_range(const char* rangeString) {
  /* An arbitraty initial value; must be larger than 2. */
  int reallocLimit = 20;
  char *comma;
  int *range = fossil_malloc(sizeof(int) * reallocLimit);
  int n = 0;
  while ((comma = strchr(rangeString, ',')) != NULL) {
    *comma = 0;
    n += parse_file_range_token(rangeString, range, n);
    *comma = ',';
    rangeString = comma + 1;

    if (n >= reallocLimit - 2) {
      reallocLimit *= 2;
      range = realloc(range, sizeof(int) * reallocLimit);
	 }
  }

  n += parse_file_range_token(rangeString, range, n);
  range[n] = 0;
  return range;
}


/*
** This is a helper function that prints contents of an integer range on 
** standard output.
**
*/
void print_file_range(int* range) {
  int i = 0;
  printf("Range: ");
  while (range[i] != 0) {
    printf("%d ", range[i++]);
  }
  printf("\n");
}

_______________________________________________
fossil-users mailing list
fossil-users@lists.fossil-scm.org
http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users

Reply via email to