Artifact eddef3fa44be35c2d5915af0b962ccd783d073bf:
- File
src/add.c
— part of check-in
[f66f414fd3]
at
2010-08-28 06:59:10
on branch windowscompilers
—
This is the first check-in on the windowscompilers branch and it adds the Digital Mars C compiler
The user should have dmc installed in c:\DM with zlib in c:\DM\extra\lib and c:\DM\extra\include.
typing c:\DM\bin\make -f win\Makefile.dmc builds fossil.exe in dmcobj
The following files were edited or added:
(user: renez size: 10159) [more...]Checks if one of the windows compilers is used. If so we define _WIN32. Defining _WIN32 is normally done by
#include <windows.h>
However most of the time we don't use windows.h.Adding an other windows compiler is done by adding
"|| defined(__COMPILER_IDENTIFIER__)"
and maybe some special things in the files below. LikeThese have all __MINGW32__ replaced by _WIN32. And in some places special processing for either MINGW32 or DMC
In popen2 the _open_osfHandle call first parameter is cast to a long. DMC refused to compile without the cast.
DMC complained that it didn't knew of time_t in rss.h. time.h came after rss.h. Switching the two solved it!
added tcl code to generate Makefile.dmc. tclsh src/makemake.tcl dmc prints to stdout the makefile. As a convienience to the end-user I added the win/Makefile.dmc to the repository. There are few changeable variables in there for adjusting path, CFLAGS LIBS etc.
These are needed because DMC and MSVC doesn't provided them. dirent.h is copied verbatim from the net. unistd.h I found on the net too, but added some defines.
The problem with windows it doesn't have AWK standard installed. version.c creates VERSION.h. It is a very simple C-program and doesn't do a lot of checking.
/* ** Copyright (c) 2007 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) ** This program is distributed in the hope that it will be useful, ** but without any warranty; without even the implied warranty of ** merchantability or fitness for a particular purpose. ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** ** This file contains code used to check-out versions of the project ** from the local repository. */ #include "config.h" #include "add.h" #include <assert.h> #include <dirent.h> /* ** Set to true if files whose names begin with "." should be ** included when processing a recursive "add" command. */ static int includeDotFiles = 0; /* ** Add a single file */ static void add_one_file(const char *zName, int vid, Blob *pOmit){ Blob pathname; const char *zPath; file_tree_name(zName, &pathname, 1); zPath = blob_str(&pathname); if( strcmp(zPath, "manifest")==0 || strcmp(zPath, "_FOSSIL_")==0 || strcmp(zPath, "_FOSSIL_-journal")==0 || strcmp(zPath, "_FOSSIL_-wal")==0 || strcmp(zPath, "_FOSSIL_-shm")==0 || strcmp(zPath, ".fos")==0 || strcmp(zPath, ".fos-journal")==0 || strcmp(zPath, ".fos-wal")==0 || strcmp(zPath, ".fos-shm")==0 || strcmp(zPath, "manifest.uuid")==0 || blob_compare(&pathname, pOmit)==0 ){ fossil_warning("cannot add %s", zPath); }else{ if( !file_is_simple_pathname(zPath) ){ fossil_fatal("filename contains illegal characters: %s", zPath); } #if defined(_WIN32) if( db_exists("SELECT 1 FROM vfile" " WHERE pathname=%Q COLLATE nocase", zPath) ){ db_multi_exec("UPDATE vfile SET deleted=0" " WHERE pathname=%Q COLLATE nocase", zPath); } #else if( db_exists("SELECT 1 FROM vfile WHERE pathname=%Q", zPath) ){ db_multi_exec("UPDATE vfile SET deleted=0 WHERE pathname=%Q", zPath); } #endif else{ db_multi_exec( "INSERT INTO vfile(vid,deleted,rid,mrid,pathname)" "VALUES(%d,0,0,0,%Q)", vid, zPath); } printf("ADDED %s\n", zPath); } blob_reset(&pathname); } /* ** All content of the zDir directory to the SFILE table. */ void add_directory_content(const char *zDir){ DIR *d; int origSize; struct dirent *pEntry; Blob path; blob_zero(&path); blob_append(&path, zDir, -1); origSize = blob_size(&path); d = opendir(zDir); if( d ){ while( (pEntry=readdir(d))!=0 ){ char *zPath; if( pEntry->d_name[0]=='.' ){ if( !includeDotFiles ) continue; if( pEntry->d_name[1]==0 ) continue; if( pEntry->d_name[1]=='.' && pEntry->d_name[2]==0 ) continue; } blob_appendf(&path, "/%s", pEntry->d_name); zPath = blob_str(&path); if( file_isdir(zPath)==1 ){ add_directory_content(zPath); }else if( file_isfile(zPath) ){ db_multi_exec("INSERT INTO sfile VALUES(%Q)", zPath); } blob_resize(&path, origSize); } } closedir(d); blob_reset(&path); } /* ** Add all content of a directory. */ void add_directory(const char *zDir, int vid, Blob *pOmit){ Stmt q; add_directory_content(zDir); db_prepare(&q, "SELECT x FROM sfile ORDER BY x"); while( db_step(&q)==SQLITE_ROW ){ const char *zName = db_column_text(&q, 0); add_one_file(zName, vid, pOmit); } db_finalize(&q); db_multi_exec("DELETE FROM sfile"); } /* ** COMMAND: add ** ** Usage: %fossil add FILE... ** ** Make arrangements to add one or more files to the current checkout ** at the next commit. ** ** When adding files recursively, filenames that begin with "." are ** excluded by default. To include such files, add the "--dotfiles" ** option to the command-line. */ void add_cmd(void){ int i; int vid; Blob repo; includeDotFiles = find_option("dotfiles",0,0)!=0; db_must_be_within_tree(); vid = db_lget_int("checkout",0); if( vid==0 ){ fossil_panic("no checkout to add to"); } db_begin_transaction(); if( !file_tree_name(g.zRepositoryName, &repo, 0) ){ blob_zero(&repo); } db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)"); #if defined(_WIN32) db_multi_exec( "CREATE INDEX IF NOT EXISTS vfile_pathname " " ON vfile(pathname COLLATE nocase)" ); #endif for(i=2; i<g.argc; i++){ char *zName; int isDir; zName = mprintf("%/", g.argv[i]); isDir = file_isdir(zName); if( isDir==1 ){ add_directory(zName, vid, &repo); }else if( isDir==0 ){ fossil_fatal("not found: %s", zName); }else if( access(zName, R_OK) ){ fossil_fatal("cannot open %s", zName); }else{ add_one_file(zName, vid, &repo); } free(zName); } db_end_transaction(0); } /* ** Remove all contents of zDir */ void del_directory_content(const char *zDir){ DIR *d; int origSize; struct dirent *pEntry; Blob path; blob_zero(&path); blob_append(&path, zDir, -1); origSize = blob_size(&path); d = opendir(zDir); if( d ){ while( (pEntry=readdir(d))!=0 ){ char *zPath; if( pEntry->d_name[0]=='.'){ if( !includeDotFiles ) continue; if( pEntry->d_name[1]==0 ) continue; if( pEntry->d_name[1]=='.' && pEntry->d_name[2]==0 ) continue; } blob_appendf(&path, "/%s", pEntry->d_name); zPath = blob_str(&path); if( file_isdir(zPath)==1 ){ del_directory_content(zPath); }else if( file_isfile(zPath) ){ char *zFilePath; Blob pathname; file_tree_name(zPath, &pathname, 1); zFilePath = blob_str(&pathname); if( !db_exists( "SELECT 1 FROM vfile WHERE pathname=%Q AND NOT deleted", zFilePath) ){ printf("SKIPPED %s\n", zPath); }else{ db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zPath); printf("DELETED %s\n", zPath); } blob_reset(&pathname); } blob_resize(&path, origSize); } } closedir(d); blob_reset(&path); } /* ** COMMAND: rm ** COMMAND: delete ** ** Usage: %fossil rm FILE... ** or: %fossil delete FILE... ** ** Remove one or more files from the tree. ** ** This command does not remove the files from disk. It just marks the ** files as no longer being part of the project. In other words, future ** changes to the named files will not be versioned. */ void delete_cmd(void){ int i; int vid; db_must_be_within_tree(); vid = db_lget_int("checkout", 0); if( vid==0 ){ fossil_panic("no checkout to remove from"); } db_begin_transaction(); for(i=2; i<g.argc; i++){ char *zName; zName = mprintf("%/", g.argv[i]); if( file_isdir(zName) == 1 ){ del_directory_content(zName); } else { char *zPath; Blob pathname; file_tree_name(zName, &pathname, 1); zPath = blob_str(&pathname); if( !db_exists( "SELECT 1 FROM vfile WHERE pathname=%Q AND NOT deleted", zPath) ){ fossil_fatal("not in the repository: %s", zName); }else{ db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zPath); printf("DELETED %s\n", zPath); } blob_reset(&pathname); } free(zName); } db_multi_exec("DELETE FROM vfile WHERE deleted AND rid=0"); db_end_transaction(0); } /* ** Rename a single file. ** ** The original name of the file is zOrig. The new filename is zNew. */ static void mv_one_file(int vid, const char *zOrig, const char *zNew){ printf("RENAME %s %s\n", zOrig, zNew); db_multi_exec( "UPDATE vfile SET pathname='%s' WHERE pathname='%s' AND vid=%d", zNew, zOrig, vid ); } /* ** COMMAND: mv ** COMMAND: rename ** ** Usage: %fossil mv|rename OLDNAME NEWNAME ** or: %fossil mv|rename OLDNAME... DIR ** ** Move or rename one or more files within the tree ** ** This command does not rename the files on disk. This command merely ** records the fact that filenames have changed so that appropriate notations ** can be made at the next commit/checkin. */ void mv_cmd(void){ int i; int vid; char *zDest; Blob dest; Stmt q; db_must_be_within_tree(); vid = db_lget_int("checkout", 0); if( vid==0 ){ fossil_panic("no checkout rename files in"); } if( g.argc<4 ){ usage("OLDNAME NEWNAME"); } zDest = g.argv[g.argc-1]; db_begin_transaction(); file_tree_name(zDest, &dest, 1); db_multi_exec( "UPDATE vfile SET origname=pathname WHERE origname IS NULL;" ); db_multi_exec( "CREATE TEMP TABLE mv(f TEXT UNIQUE ON CONFLICT IGNORE, t TEXT);" ); if( file_isdir(zDest)!=1 ){ Blob orig; if( g.argc!=4 ){ usage("OLDNAME NEWNAME"); } file_tree_name(g.argv[2], &orig, 1); db_multi_exec( "INSERT INTO mv VALUES(%B,%B)", &orig, &dest ); }else{ if( blob_eq(&dest, ".") ){ blob_reset(&dest); }else{ blob_append(&dest, "/", 1); } for(i=2; i<g.argc-1; i++){ Blob orig; char *zOrig; int nOrig; file_tree_name(g.argv[i], &orig, 1); zOrig = blob_str(&orig); nOrig = blob_size(&orig); db_prepare(&q, "SELECT pathname FROM vfile" " WHERE vid=%d" " AND (pathname='%s' OR pathname GLOB '%s/*')" " ORDER BY 1", vid, zOrig, zOrig ); while( db_step(&q)==SQLITE_ROW ){ const char *zPath = db_column_text(&q, 0); int nPath = db_column_bytes(&q, 0); const char *zTail; if( nPath==nOrig ){ zTail = file_tail(zPath); }else{ zTail = &zPath[nOrig+1]; } db_multi_exec( "INSERT INTO mv VALUES('%s','%s%s')", zPath, blob_str(&dest), zTail ); } db_finalize(&q); } } db_prepare(&q, "SELECT f, t FROM mv ORDER BY f"); while( db_step(&q)==SQLITE_ROW ){ const char *zFrom = db_column_text(&q, 0); const char *zTo = db_column_text(&q, 1); mv_one_file(vid, zFrom, zTo); } db_finalize(&q); db_end_transaction(0); }