8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 12:03:02 +01:00
firebird-mirror/src/config/InputFile.cpp
2006-06-16 12:36:09 +00:00

218 lines
4.8 KiB
C++

/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
// InputFile.cpp: implementation of the InputFile class.
//
//////////////////////////////////////////////////////////////////////
#ifndef _WIN32
#include <unistd.h>
#else
#include <io.h> // for unlink
#endif
#include <stdio.h>
#include <string.h>
#include "firebird.h"
#include "../common/classes/alloc.h"
#include "InputFile.h"
#include "AdminException.h"
#define ISLOWER(c) (c >= 'a' && c <= 'z')
#define ISUPPER(c) (c >= 'A' && c <= 'Z')
#define ISDIGIT(c) (c >= '0' && c <= '9')
#ifndef UPPER
#define UPPER(c) ((ISLOWER (c)) ? c - 'a' + 'A' : c)
#endif
#define MAX_FILE_NAME 256
#define BACKUP_FILES 5
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
InputFile::InputFile(const char *name)
{
changes = NULL;
if (!openInputFile (name))
throw AdminException ("can't open file \"%s\"", name);
}
InputFile::InputFile(void)
{
changes = NULL;
}
InputFile::~InputFile()
{
close();
for (FileChange *change; change = changes;)
{
changes = change->next;
delete change;
}
}
void InputFile::close()
{
if (file)
{
fclose ((FILE*) file);
file = NULL;
}
}
const char* InputFile::getSegment()
{
if (!file)
throw AdminException ("file has been closed");
if (!fgets (buffer, sizeof (buffer), (FILE*) file))
return NULL;
//++lineNumber;
segmentLength = (int) strlen (buffer);
return buffer;
}
const char* InputFile::getFileName()
{
return fileName;
}
InputFile* InputFile::getInputFile()
{
return this;
}
void InputFile::postChange(int line, int skip, JString insertion)
{
FileChange *change = new FileChange;
change->lineNumber = line;
change->linesSkipped = skip;
change->insertion = insertion;
for (FileChange **p = &changes;; p = &(*p)->next)
{
FileChange *next = *p;
if (!next || next->lineNumber > change->lineNumber)
{
change->next = *p;
*p = change;
break;
}
}
}
void InputFile::rewrite()
{
FILE *input = fopen (fileName, "r");
if (!input)
throw AdminException ("can't open \"%s\" for input", (const char*) fileName);
char tempName [MAX_FILE_NAME];
sprintf (tempName, "%s.tmp", (const char*) fileName);
FILE *output = fopen (tempName,"w");
if (!output)
throw AdminException ("can't open \"%s\" for output", tempName);
char temp [1024];
int line = 0;
for (FileChange *change = changes; change; change = change->next)
{
for (; line < change->lineNumber; ++line)
if (fgets (temp, sizeof (temp), input))
fputs (temp, output);
//fputs ("#insertion starts here\n", output);
fputs (change->insertion, output);
//fputs ("#insertion end here\n", output);
for (int n = 0; n < change->linesSkipped; ++n)
fgets (temp, sizeof (temp), input);
line += change->linesSkipped;
}
while (fgets (temp, sizeof (temp), input))
fputs (temp, output);
fclose (input);
fclose (output);
char filename1 [MAX_FILE_NAME];
char filename2 [MAX_FILE_NAME];
for (int n = BACKUP_FILES; n >= 0; --n)
{
sprintf (filename1, "%s.%d", (const char*) fileName, n);
if (n)
sprintf (filename2, "%s.%d", (const char*) fileName, n - 1);
else
strcpy (filename2, fileName);
if (n == BACKUP_FILES)
unlink (filename1);
rename (filename2, filename1);
}
if (rename (tempName, fileName))
perror ("rename");
}
bool InputFile::pathEqual(const char *path1, const char *path2)
{
#ifdef _WIN32
for (; *path1 && *path2; ++path1, ++path2)
if (*path1 != *path2 &&
UPPER (*path1) != UPPER (*path2) &&
!((*path1 == '/' || *path1 == '\\') &&
(*path2 == '/' || *path2 == '\\')))
return false;
#else
for (; *path1 && *path2; ++path1, ++path2)
if (*path1 != *path2)
return false;
#endif
return *path1 == 0 && *path2 == 0;
}
bool InputFile::openInputFile(const char* name)
{
if (!(file = fopen (name, "r")))
return false;
fileName = name;
segment = buffer;
changes = NULL;
return true;
}