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