mirror of
https://github.com/reactos/reactos.git
synced 2025-05-06 18:31:26 +00:00
Cross-platform tools added to Makefiles.
svn path=/trunk/; revision=3061
This commit is contained in:
parent
6ab0a870c1
commit
63ea3fb94c
7 changed files with 429 additions and 22 deletions
|
@ -33,18 +33,23 @@ OUTPUT_DIR = $(OBJDIR)/$(TARGET)
|
||||||
#############################################
|
#############################################
|
||||||
# COMPILER AND LINKER PROGRAMS
|
# COMPILER AND LINKER PROGRAMS
|
||||||
#
|
#
|
||||||
|
TOOLSDIR = $(SRCDIR)/../tools
|
||||||
|
|
||||||
CC = gcc
|
CC = gcc
|
||||||
LD = ld
|
LD = ld
|
||||||
AR = ar
|
AR = ar
|
||||||
NM = nm
|
NM = nm
|
||||||
RM = cmd /C del
|
RM = $(TOOLSDIR)/rdel
|
||||||
CP = cmd /C copy
|
CP = $(TOOLSDIR)/rcopy
|
||||||
MKDIR = cmd /C md
|
MKDIR = $(TOOLSDIR)/rmkdir
|
||||||
RMDIR = cmd /C rd
|
RMDIR = $(TOOLSDIR)/rrmdir
|
||||||
NASM_CMD = nasm
|
NASM_CMD = nasm
|
||||||
OBJCOPY = objcopy
|
OBJCOPY = objcopy
|
||||||
DEPTOOL = $(SRCDIR)/../tools/deptool
|
DEPTOOL = $(TOOLSDIR)/deptool
|
||||||
TOOLSDIR = $(SRCDIR)/../tools
|
HOSTTOOL = $(TOOLSDIR)/hosttype
|
||||||
|
TOOLS = $(DEPTOOL) $(HOSTTOOL)
|
||||||
|
|
||||||
|
HOST = $(shell $(HOSTTOOL))
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------------------------------
|
||||||
# TEST IF WE ARE IN THE TARGET DIRECTORY
|
# TEST IF WE ARE IN THE TARGET DIRECTORY
|
||||||
|
@ -53,6 +58,8 @@ TOOLSDIR = $(SRCDIR)/../tools
|
||||||
#ifeq (,$(filter $(CURDIR)/$(OUTPUT_DIR),$(notdir $(CURDIR))))
|
#ifeq (,$(filter $(CURDIR)/$(OUTPUT_DIR),$(notdir $(CURDIR))))
|
||||||
ifneq ($(CURDIR), $(SRCDIR)/$(OUTPUT_DIR))
|
ifneq ($(CURDIR), $(SRCDIR)/$(OUTPUT_DIR))
|
||||||
|
|
||||||
|
SRCDIR = $(CURDIR)
|
||||||
|
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
|
|
||||||
#############################################
|
#############################################
|
||||||
|
@ -63,6 +70,7 @@ MAKETARGET = $(MAKE) --no-print-directory -C $(OUTPUT_DIR) \
|
||||||
|
|
||||||
.PHONY: CHANGE_TO_TARGET
|
.PHONY: CHANGE_TO_TARGET
|
||||||
CHANGE_TO_TARGET: $(OBJDIR) $(OBJDIR)/$(TARGET)
|
CHANGE_TO_TARGET: $(OBJDIR) $(OBJDIR)/$(TARGET)
|
||||||
|
@$(MAKE) --no-print-directory -C $(TOOLSDIR)
|
||||||
@echo Calculating source file dependencies...
|
@echo Calculating source file dependencies...
|
||||||
+@$(MAKETARGET)
|
+@$(MAKETARGET)
|
||||||
|
|
||||||
|
@ -71,8 +79,9 @@ $(OBJDIR):
|
||||||
@$(MKDIR) $(OBJDIR)
|
@$(MKDIR) $(OBJDIR)
|
||||||
|
|
||||||
$(OBJDIR)/$(TARGET): $(OBJDIR)
|
$(OBJDIR)/$(TARGET): $(OBJDIR)
|
||||||
@echo Creating directory: $(OBJDIR)\$(TARGET)
|
@echo Creating directory: $(OBJDIR)/$(TARGET)
|
||||||
@$(MKDIR) $(OBJDIR)\$(TARGET)
|
@$(MKDIR) $(OBJDIR)/$(TARGET)
|
||||||
|
|
||||||
|
|
||||||
Makefile : ;
|
Makefile : ;
|
||||||
|
|
||||||
|
@ -82,10 +91,11 @@ Makefile : ;
|
||||||
|
|
||||||
.PHONY : clean
|
.PHONY : clean
|
||||||
clean:
|
clean:
|
||||||
@echo Cleaning directory $(OBJDIR)\$(TARGET)
|
@$(MAKE) --no-print-directory -C $(TOOLSDIR)
|
||||||
@-$(RM) /Q $(OBJDIR)\$(TARGET)\*.*
|
@echo Cleaning directory $(OBJDIR)/$(TARGET)
|
||||||
@echo Removing directory $(OBJDIR)\$(TARGET)
|
@-$(RM) $(OBJDIR)/$(TARGET)/*
|
||||||
@-$(RMDIR) $(OBJDIR)\$(TARGET)
|
@echo Removing directory $(OBJDIR)/$(TARGET)
|
||||||
|
@-$(RMDIR) $(OBJDIR)/$(TARGET)
|
||||||
@-$(RMDIR) $(OBJDIR)
|
@-$(RMDIR) $(OBJDIR)
|
||||||
@echo Clean ALL done.
|
@echo Clean ALL done.
|
||||||
|
|
||||||
|
@ -129,10 +139,23 @@ CFLAGS = $(COMPILER_OPTIONS) \
|
||||||
LINKER_OPTIONS = -N -Ttext=0x8000 -s
|
LINKER_OPTIONS = -N -Ttext=0x8000 -s
|
||||||
|
|
||||||
#############################################
|
#############################################
|
||||||
# LINKERS FLAGS
|
# LINKER FLAGS
|
||||||
#
|
#
|
||||||
LFLAGS = $(LINKER_OPTIONS)
|
LFLAGS = $(LINKER_OPTIONS)
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
# NASM FLAGS
|
||||||
|
#
|
||||||
|
ifeq ($(HOST), dos)
|
||||||
|
NASMFLAGS = -f coff
|
||||||
|
else
|
||||||
|
ifeq ($(HOST), win32)
|
||||||
|
NASMFLAGS = -f win32
|
||||||
|
else
|
||||||
|
NASMFLAGS = -f elf
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
#############################################
|
#############################################
|
||||||
# LIST ALL THE OBJECT FILE GROUPS
|
# LIST ALL THE OBJECT FILE GROUPS
|
||||||
#
|
#
|
||||||
|
@ -235,16 +258,11 @@ VPATH = $(SRCDIR)/ \
|
||||||
|
|
||||||
#############################################
|
#############################################
|
||||||
|
|
||||||
all : $(DEPTOOL) freeldr.sys
|
all : freeldr.sys
|
||||||
@echo Make ALL done.
|
@echo Make ALL done.
|
||||||
|
|
||||||
#############################################
|
#############################################
|
||||||
|
|
||||||
$(DEPTOOL) :
|
|
||||||
@$(MAKE) --no-print-directory -C $(TOOLSDIR)
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
|
|
||||||
freeldr.sys : $(OBJS)
|
freeldr.sys : $(OBJS)
|
||||||
@echo ===================================================== LINKING $@
|
@echo ===================================================== LINKING $@
|
||||||
# @$(LD) -N -Ttext=0x8000 --oformat=binary -s -o freeldr.sys $(OBJS)
|
# @$(LD) -N -Ttext=0x8000 --oformat=binary -s -o freeldr.sys $(OBJS)
|
||||||
|
@ -265,7 +283,7 @@ freeldr.sys : $(OBJS)
|
||||||
|
|
||||||
%.o :: %.asm
|
%.o :: %.asm
|
||||||
@echo ===================================================== Assembling $*
|
@echo ===================================================== Assembling $*
|
||||||
@$(NASM_CMD) -o $@ -f coff $<
|
@$(NASM_CMD) $(NASMFLAGS) -o $@ $<
|
||||||
|
|
||||||
#############################################
|
#############################################
|
||||||
|
|
||||||
|
|
|
@ -22,16 +22,24 @@
|
||||||
# PROGRAMS
|
# PROGRAMS
|
||||||
#
|
#
|
||||||
CC = gcc
|
CC = gcc
|
||||||
RM = cmd /C del
|
RM = rdel
|
||||||
|
|
||||||
#############################################
|
#############################################
|
||||||
|
|
||||||
TOOLS = deptool \
|
TOOLS = deptool \
|
||||||
bin2c
|
bin2c \
|
||||||
|
hosttype \
|
||||||
|
rdel \
|
||||||
|
rcopy \
|
||||||
|
rmkdir \
|
||||||
|
rrmdir
|
||||||
|
|
||||||
#############################################
|
#############################################
|
||||||
|
|
||||||
all : $(TOOLS)
|
all : $(TOOLS)
|
||||||
|
@echo Tools are up to date.
|
||||||
|
|
||||||
|
% :: all
|
||||||
|
|
||||||
#############################################
|
#############################################
|
||||||
|
|
||||||
|
|
19
freeldr/tools/hosttype.c
Normal file
19
freeldr/tools/hosttype.c
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
//
|
||||||
|
// hosttype.c
|
||||||
|
// Copyright (C) 2002 by Brian Palmer <brianp@sginet.com>
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
#if defined (__DJGPP__)
|
||||||
|
printf("dos\n");
|
||||||
|
#elif defined (__WIN32__)
|
||||||
|
printf("win32\n");
|
||||||
|
#else
|
||||||
|
printf("linux\n");
|
||||||
|
#endif // defined __DJGPP__
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
93
freeldr/tools/rcopy.c
Normal file
93
freeldr/tools/rcopy.c
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#if defined (__DJGPP__) || defined (__WIN32__)
|
||||||
|
#define DOS_PATHS
|
||||||
|
#else
|
||||||
|
#define UNIX_PATHS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char* convert_path(char* origpath)
|
||||||
|
{
|
||||||
|
char* newpath;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
newpath = strdup(origpath);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (newpath[i] != 0)
|
||||||
|
{
|
||||||
|
#ifdef UNIX_PATHS
|
||||||
|
if (newpath[i] == '\\')
|
||||||
|
{
|
||||||
|
newpath[i] = '/';
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#ifdef DOS_PATHS
|
||||||
|
if (newpath[i] == '/')
|
||||||
|
{
|
||||||
|
newpath[i] = '\\';
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return(newpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TRANSFER_SIZE (65536)
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
char* path1;
|
||||||
|
char* path2;
|
||||||
|
FILE* in;
|
||||||
|
FILE* out;
|
||||||
|
char* buf;
|
||||||
|
int n_in;
|
||||||
|
int n_out;
|
||||||
|
|
||||||
|
if (argc != 3)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Too many arguments\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
path1 = convert_path(argv[1]);
|
||||||
|
path2 = convert_path(argv[2]);
|
||||||
|
|
||||||
|
in = fopen(path1, "rb");
|
||||||
|
if (in == NULL)
|
||||||
|
{
|
||||||
|
perror("Cannot open input file");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
out = fopen(path2, "wb");
|
||||||
|
if (out == NULL)
|
||||||
|
{
|
||||||
|
perror("Cannot open output file");
|
||||||
|
fclose(in);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = malloc(TRANSFER_SIZE);
|
||||||
|
|
||||||
|
while (!feof(in))
|
||||||
|
{
|
||||||
|
n_in = fread(buf, 1, TRANSFER_SIZE, in);
|
||||||
|
n_out = fwrite(buf, 1, n_in, out);
|
||||||
|
if (n_in != n_out)
|
||||||
|
{
|
||||||
|
perror("Failed to write to output file\n");
|
||||||
|
free(buf);
|
||||||
|
fclose(in);
|
||||||
|
fclose(out);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
91
freeldr/tools/rdel.c
Normal file
91
freeldr/tools/rdel.c
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
/* $Id: rdel.c,v 1.1 2002/06/13 00:39:49 bpalmer Exp $
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROGRAMMER: Rex Jolliff (rex@lvcablemodem.com)
|
||||||
|
* PURPOSE: Platform independant delete command
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
convertPath (char * pathToConvert)
|
||||||
|
{
|
||||||
|
while (*pathToConvert != 0)
|
||||||
|
{
|
||||||
|
if (*pathToConvert == '\\')
|
||||||
|
{
|
||||||
|
*pathToConvert = '/';
|
||||||
|
}
|
||||||
|
pathToConvert++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
getDirectory (const char *filename, char * directorySpec)
|
||||||
|
{
|
||||||
|
int lengthOfDirectory;
|
||||||
|
|
||||||
|
if (strrchr (filename, '/') != 0)
|
||||||
|
{
|
||||||
|
lengthOfDirectory = strrchr (filename, '/') - filename;
|
||||||
|
strncpy (directorySpec, filename, lengthOfDirectory);
|
||||||
|
directorySpec [lengthOfDirectory] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy (directorySpec, ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
getFilename (const char *filename, char * fileSpec)
|
||||||
|
{
|
||||||
|
if (strrchr (filename, '/') != 0)
|
||||||
|
{
|
||||||
|
strcpy (fileSpec, strrchr (filename, '/') + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy (fileSpec, filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char* argv[])
|
||||||
|
{
|
||||||
|
int justPrint = 0;
|
||||||
|
int idx;
|
||||||
|
int returnCode;
|
||||||
|
|
||||||
|
for (idx = 1; idx < argc; idx++)
|
||||||
|
{
|
||||||
|
convertPath (argv [idx]);
|
||||||
|
|
||||||
|
if (justPrint)
|
||||||
|
{
|
||||||
|
printf ("delete %s\n", argv [idx]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
returnCode = remove (argv [idx]);
|
||||||
|
if (returnCode != 0 && errno != ENOENT)
|
||||||
|
{
|
||||||
|
/* Continue even if there is errors */
|
||||||
|
#if 0
|
||||||
|
printf ("Unlink of %s failed. Unlink returned %d.\n",
|
||||||
|
argv [idx],
|
||||||
|
returnCode);
|
||||||
|
return returnCode;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
85
freeldr/tools/rmkdir.c
Normal file
85
freeldr/tools/rmkdir.c
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#define DOS_PATH_CHAR '\\'
|
||||||
|
#define UNIX_PATH_CHAR '/'
|
||||||
|
|
||||||
|
#if defined (__DJGPP__) || defined (__WIN32__)
|
||||||
|
#define DOS_PATHS
|
||||||
|
#define PATH_CHAR '\\'
|
||||||
|
#define PATH_CHAR_STR "\\"
|
||||||
|
#else
|
||||||
|
#define UNIX_PATHS
|
||||||
|
#define PATH_CHAR '/'
|
||||||
|
#define PATH_CHAR_STR "/"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void ConvertPathCharacters(char *Path)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (Path[i] != 0)
|
||||||
|
{
|
||||||
|
if (Path[i] == DOS_PATH_CHAR || Path[i] == UNIX_PATH_CHAR)
|
||||||
|
{
|
||||||
|
Path[i] = PATH_CHAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int MakeDirectory(char *Directory)
|
||||||
|
{
|
||||||
|
char CurrentDirectory[1024];
|
||||||
|
|
||||||
|
getcwd(CurrentDirectory, 1024);
|
||||||
|
|
||||||
|
if (chdir(Directory) == 0)
|
||||||
|
{
|
||||||
|
chdir(CurrentDirectory);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined (UNIX_PATHS) || defined (__DJGPP__)
|
||||||
|
if (mkdir(Directory, 0755) != 0)
|
||||||
|
{
|
||||||
|
perror("Failed to create directory");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (mkdir(Directory) != 0)
|
||||||
|
{
|
||||||
|
perror("Failed to create directory");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (chdir(Directory) != 0)
|
||||||
|
{
|
||||||
|
perror("Failed to change directory");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
chdir(CurrentDirectory);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Wrong number of arguments\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConvertPathCharacters(argv[1]);
|
||||||
|
|
||||||
|
return MakeDirectory(argv[1]);
|
||||||
|
}
|
93
freeldr/tools/rrmdir.c
Normal file
93
freeldr/tools/rrmdir.c
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/* $Id: rrmdir.c,v 1.1 2002/06/13 00:39:49 bpalmer Exp $
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROGRAMMER: Rex Jolliff (rex@lvcablemodem.com)
|
||||||
|
* Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||||
|
* PURPOSE: Platform independant remove directory command
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
convertPath (char * pathToConvert)
|
||||||
|
{
|
||||||
|
while (*pathToConvert != 0)
|
||||||
|
{
|
||||||
|
if (*pathToConvert == '\\')
|
||||||
|
{
|
||||||
|
*pathToConvert = '/';
|
||||||
|
}
|
||||||
|
pathToConvert++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
getDirectory (const char *filename, char * directorySpec)
|
||||||
|
{
|
||||||
|
int lengthOfDirectory;
|
||||||
|
|
||||||
|
if (strrchr (filename, '/') != 0)
|
||||||
|
{
|
||||||
|
lengthOfDirectory = strrchr (filename, '/') - filename;
|
||||||
|
strncpy (directorySpec, filename, lengthOfDirectory);
|
||||||
|
directorySpec [lengthOfDirectory] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy (directorySpec, ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
getFilename (const char *filename, char * fileSpec)
|
||||||
|
{
|
||||||
|
if (strrchr (filename, '/') != 0)
|
||||||
|
{
|
||||||
|
strcpy (fileSpec, strrchr (filename, '/') + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy (fileSpec, filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char* argv[])
|
||||||
|
{
|
||||||
|
int justPrint = 0;
|
||||||
|
int idx;
|
||||||
|
int returnCode;
|
||||||
|
|
||||||
|
for (idx = 1; idx < argc; idx++)
|
||||||
|
{
|
||||||
|
convertPath (argv [idx]);
|
||||||
|
|
||||||
|
if (justPrint)
|
||||||
|
{
|
||||||
|
printf ("remove %s\n", argv [idx]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
returnCode = rmdir (argv [idx]);
|
||||||
|
if (returnCode != 0 && errno != ENOENT)
|
||||||
|
{
|
||||||
|
/* Continue even if there is errors */
|
||||||
|
#if 0
|
||||||
|
printf ("Rmdir of %s failed. Rmdir returned %d.\n",
|
||||||
|
argv [idx],
|
||||||
|
returnCode);
|
||||||
|
return returnCode;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue