baseline

yet another open-source distributed versioning control system
Log | Files | Refs

cmd-log.c (4526B)


      1 /*
      2  * Copyright (c) 2014 Mohamed Aslan <maslan@sce.carleton.ca>
      3  *
      4  * Permission to use, copy, modify, and distribute this software for any
      5  * purpose with or without fee is hereby granted, provided that the above
      6  * copyright notice and this permission notice appear in all copies.
      7  *
      8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     15  */
     16 
     17 #include <stdio.h> /* printf(3) */
     18 #include <stdlib.h> /* EXIT_SUCCESS, strtonum(3) */
     19 #include <string.h> /* strdup(3) */
     20 #include <time.h> /* ctime(3) */
     21 #include <unistd.h> /* getopt(3) */
     22 #include <err.h> /* errx(3) */
     23 #include <limits.h> /* INT_MAX */
     24 
     25 #include "cmd.h"
     26 #include "session.h"
     27 
     28 #include "objects.h"
     29 
     30 static char *default_fmt =
     31 	"commit: %i\n"
     32 	"author:\n"
     33 	"\tname: %an\n"
     34 	"\temail: %ae\n"
     35 	"\ttime: %at\n"
     36 	"committer:\n"
     37 	"\tname: %cn\n"
     38 	"\temail: %ce\n"
     39 	"\ttime: %ct\n"
     40 	"message:\n%m\n";
     41 
     42 
     43 int
     44 cmd_log(int argc, char **argv)
     45 {
     46 	char *head = NULL, *fmtstr = NULL;
     47 	char timestr[26];
     48 	const char *errstr;
     49 	int ch, done = 0, i, k = 0, kmax = 0;
     50 	int fmt = 0, limited = 0, explicit = 0;
     51 	struct session s;
     52 	struct commit *comm;
     53 
     54 	baseline_session_begin(&s, 0);
     55 
     56 	/* parse command line options */
     57 	while ((ch = getopt(argc, argv, "f:n:c:")) != -1) {
     58 		switch (ch) {
     59 		case 'f':
     60 			fmt = 1;
     61 			fmtstr = strdup(optarg);
     62 			break;
     63 		case 'n':
     64 			limited = 1;
     65 			kmax = strtonum(optarg, 0, INT_MAX, &errstr);
     66 			if (errstr != NULL)
     67 				errx(EXIT_FAILURE, "error, number (%s) is %s.", optarg, errstr);
     68 			break;
     69 		case 'c':
     70 			explicit = 1;
     71 			head = strdup(optarg);
     72 			break;
     73 		default:
     74 			exit(EXIT_FAILURE);
     75 		}
     76 	}
     77 	argc -= optind;
     78 	argv += optind;
     79 
     80 	if (!explicit) {
     81 		s.db_ops->branch_get_head(s.db_ctx, s.branch, &head);
     82 		if (head == NULL)
     83 			goto ret;
     84 	}
     85 
     86 	if (!fmt)
     87 		fmtstr = default_fmt;
     88 
     89 	do {
     90 		k++;
     91 		if ((limited) && (k > kmax))
     92 			break;
     93 		comm = baseline_commit_new();
     94 		s.db_ops->select_commit(s.db_ctx, head, comm);
     95 		for (i = 0 ; i<strlen(fmtstr) ; i++) {
     96 			if ((i < strlen(fmtstr) - 1) && (fmtstr[i] == '%') && (fmtstr[i + 1] == 'n')) {
     97 				printf("%d", k);
     98 				i++;
     99 			}
    100 			else if ((i < strlen(fmtstr) - 1) && (fmtstr[i] == '%') && (fmtstr[i + 1] == 'i')) {
    101 				printf("%s", comm->id);
    102 				i++;
    103 			}
    104 			else if ((i < strlen(fmtstr) - 2) && (fmtstr[i] == '%') && (fmtstr[i + 1] == 'a') && (fmtstr[i+2] == 'n')) {
    105 				printf("%s", comm->author.name);
    106 				i += 2;
    107 			}
    108 			else if ((i < strlen(fmtstr) - 2) && (fmtstr[i] == '%') && (fmtstr[i + 1] == 'a') && (fmtstr[i+2] == 'e')) {
    109 				printf("%s", comm->author.email);
    110 				i += 2;
    111 			}
    112 			else if ((i < strlen(fmtstr) - 2) && (fmtstr[i] == '%') && (fmtstr[i + 1] == 'a') && (fmtstr[i+2] == 't')) {
    113 				bzero(timestr, sizeof(timestr));
    114 				ctime_r(&(comm->author.timestamp), timestr);
    115 				timestr[sizeof(timestr) - 2] = '\0';
    116 				printf("%s", timestr);
    117 				i += 2;
    118 			}
    119 			else if ((i < strlen(fmtstr) - 2) && (fmtstr[i] == '%') && (fmtstr[i + 1] == 'c') && (fmtstr[i+2] == 'n')) {
    120 				printf("%s", comm->committer.name);
    121 				i += 2;
    122 			}
    123 			else if ((i < strlen(fmtstr) - 2) && (fmtstr[i] == '%') && (fmtstr[i + 1] == 'c') && (fmtstr[i+2] == 'e')) {
    124 				printf("%s", comm->committer.email);
    125 				i += 2;
    126 			}
    127 			else if ((i < strlen(fmtstr) - 2) && (fmtstr[i] == '%') && (fmtstr[i + 1] == 'c') && (fmtstr[i+2] == 't')) {
    128 				bzero(timestr, sizeof(timestr));
    129 				ctime_r(&(comm->committer.timestamp), timestr);
    130 				timestr[sizeof(timestr) - 2] = '\0';
    131 				printf("%s", timestr);
    132 				i += 2;
    133 			}
    134 			else if ((i < strlen(fmtstr) - 1) && (fmtstr[i] == '%') && (fmtstr[i + 1] == 'm')) {
    135 				printf("%s", comm->message);
    136 				i++;
    137 			}
    138 			else if ((i < strlen(fmtstr) - 1) && (fmtstr[i] == '\\') && (fmtstr[i + 1] == 'n')) {
    139 				printf("\n");
    140 				i++;
    141 			}
    142 			else if ((i < strlen(fmtstr) - 1) && (fmtstr[i] == '\\') && (fmtstr[i + 1] == 't')) {
    143 				printf("\t");
    144 				i++;
    145 			}
    146 			else
    147 				printf("%c", fmtstr[i]);
    148 		}
    149 		if (comm->n_parents == 0)
    150 			done = 1;
    151 		else
    152 			head = strdup(comm->parents[0]);
    153 		baseline_commit_free(comm);
    154 	} while (!done);
    155 
    156 ret:
    157 	free(head);
    158 	if (fmt)
    159 		free(fmtstr);
    160 	baseline_session_end(&s);
    161 	return EXIT_SUCCESS;
    162 }
    163