Sat, 22 Aug 2015 13:04:58 +0300
Commit work on scripting
/* updaterevision.c * * Public domain. This program uses the svnversion command to get the * repository revision for a particular directory and writes it into * a header file so that it can be used as a project's build number. */ #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <errno.h> // [BB] New #includes. #include <sys/stat.h> #include <time.h> int main(int argc, char **argv) { const char *name = "svnout"; char currev[64], lastrev[64], run[256], *rev; unsigned long urev; FILE *stream = NULL; int gotrev = 0, needupdate = 1; // [BB] Are we working with a SVN checkout? int svnCheckout = 0; char hgdateString[64]; time_t hgdate = 0; char hgHash[13]; hgHash[0] = '\0'; if (argc != 3) { fprintf (stderr, "Usage: %s <repository directory> <path to svnrevision.h>\n", argv[0]); return 1; } // [BB] Try to figure out whether this is a SVN or a Hg checkout. { struct stat st; char filename[1024]; sprintf ( filename, "%s/.svn/entries", argv[1] ); if ( stat ( filename, &st ) == 0 ) svnCheckout = 1; // [BB] If stat failed we have to manually clear errno, otherwise the code below doesn't work. else errno = 0; } // Use svnversion to get the revision number. If that fails, pretend it's // revision 0. Note that this requires you have the command-line svn tools installed. // [BB] Depending on whether this is a SVN or Hg checkout we have to use the appropriate tool. if ( svnCheckout ) sprintf (run, "svnversion -cn %s", argv[1]); else sprintf (run, "hg identify -n"); // if ((name = tempnam(NULL, "svnout")) != NULL) { #ifdef __APPLE__ // tempnam will return errno of 2 even though it is successful for our purposes. errno = 0; #endif if((stream = freopen(name, "w+b", stdout)) != NULL && system(run) == 0 && #ifndef __FreeBSD__ errno == 0 && #endif fseek(stream, 0, SEEK_SET) == 0 && fgets(currev, sizeof currev, stream) == currev && (isdigit(currev[0]) || (currev[0] == '-' && currev[1] == '1'))) { gotrev = 1; // [BB] Find the date the revision of the working copy was created. if ( ( svnCheckout == 0 ) && ( system("hg log -r. --template \"{date|hgdate} {node|short}\"") == 0 ) && ( fseek(stream, strlen(currev), SEEK_SET) == 0 ) && ( fgets(hgdateString, sizeof ( hgdateString ), stream) == hgdateString ) ) { // [BB] Find the hash in the output and store it. char *p = strrchr ( hgdateString, ' ' ); strncpy ( hgHash, p ? ( p+1 ) : "hashnotfound" , sizeof( hgHash ) - 1 ); hgHash[ sizeof ( hgHash ) - 1 ] = '\0'; // [BB] Extract the date from the output and store it. hgdate = atoi ( hgdateString ); } } } if (stream != NULL) { fclose (stream); remove (name); } /*if (name != NULL) { free (name); }*/ if (!gotrev) { fprintf (stderr, "Failed to get current revision: %s\n", strerror(errno)); strcpy (currev, "0"); rev = currev; } else { rev = strchr (currev, ':'); if (rev == NULL) { rev = currev; } else { rev += 1; } } // [BB] Create date version string. if ( gotrev && ( svnCheckout == 0 ) ) { char *endptr; unsigned long parsedRev = strtoul(rev, &endptr, 10); unsigned int localChanges = ( *endptr == '+' ); struct tm *lt = gmtime( &hgdate ); if ( localChanges ) sprintf ( rev, "%d%02d%02d-%02d%02dM", lt->tm_year - 100, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min); else sprintf ( rev, "%d%02d%02d-%02d%02d", lt->tm_year - 100, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min); } stream = fopen (argv[2], "r"); if (stream != NULL) { if (!gotrev) { // If we didn't get a revision but the file does exist, leave it alone. fprintf( stderr, "No revision found.\n" ); fclose (stream); return 0; } // Read the revision that's in this file already. If it's the same as // what we've got, then we don't need to modify it and can avoid rebuilding // dependant files. if (fgets(lastrev, sizeof lastrev, stream) == lastrev) { if (lastrev[0] != '\0') { // Strip trailing \n lastrev[strlen(lastrev) - 1] = '\0'; } if (strcmp(rev, lastrev + 3) == 0) { needupdate = 0; } } fclose (stream); } if (needupdate) { stream = fopen (argv[2], "w"); if (stream == NULL) { return 1; } // [BB] Use hgdate as revision number. if ( hgdate ) urev = hgdate; else urev = strtoul(rev, NULL, 10); fprintf (stream, "// %s\n" "//\n" "// This file was automatically generated by the\n" "// updaterevision tool. Do not edit by hand.\n" "\n" "#define SVN_REVISION_STRING \"%s\"\n" "#define SVN_REVISION_NUMBER %lu\n", rev, rev, urev); // [BB] Also save the hg hash. if ( svnCheckout == 0 ) fprintf (stream, "#define HG_REVISION_HASH_STRING \"%s\"\n", hgHash); fclose (stream); fprintf (stderr, "%s updated to revision %s.\n", argv[2], rev); } else { fprintf (stderr, "%s is up to date at revision %s.\n", argv[2], rev); } return 0; }