LAB: Kill storage.h
This commit is contained in:
parent
62ceb496a9
commit
3a8cafa41e
14 changed files with 28 additions and 141 deletions
|
@ -28,9 +28,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lab/storage.h"
|
|
||||||
#include "lab/parsetypes.h"
|
|
||||||
#include "lab/stddefines.h"
|
#include "lab/stddefines.h"
|
||||||
|
#include "lab/parsetypes.h"
|
||||||
|
|
||||||
namespace Lab {
|
namespace Lab {
|
||||||
|
|
||||||
|
@ -65,7 +64,7 @@ bool initRoomBuffer(void) {
|
||||||
|
|
||||||
CurMarker = 0;
|
CurMarker = 0;
|
||||||
|
|
||||||
if (allocate((void **)&RoomBuffer, ROOMBUFFERSIZE)) {
|
if ((RoomBuffer = calloc(ROOMBUFFERSIZE, 1))) {
|
||||||
MemPlace = RoomBuffer;
|
MemPlace = RoomBuffer;
|
||||||
MemLeftInBuffer = ROOMBUFFERSIZE;
|
MemLeftInBuffer = ROOMBUFFERSIZE;
|
||||||
|
|
||||||
|
@ -85,7 +84,7 @@ bool initRoomBuffer(void) {
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
void freeRoomBuffer(void) {
|
void freeRoomBuffer(void) {
|
||||||
if (RoomBuffer)
|
if (RoomBuffer)
|
||||||
deallocate(RoomBuffer, ROOMBUFFERSIZE);
|
free(RoomBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
#include "lab/vga.h"
|
#include "lab/vga.h"
|
||||||
#include "lab/timing.h"
|
#include "lab/timing.h"
|
||||||
#include "lab/text.h"
|
#include "lab/text.h"
|
||||||
#include "lab/storage.h"
|
|
||||||
#include "lab/parsefun.h"
|
#include "lab/parsefun.h"
|
||||||
#include "lab/interface.h"
|
#include "lab/interface.h"
|
||||||
#include "lab/mouse.h"
|
#include "lab/mouse.h"
|
||||||
|
@ -264,7 +263,7 @@ bool setUpScreens(void) {
|
||||||
if (MovePanelBufferSize == 0L)
|
if (MovePanelBufferSize == 0L)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!allocate((void **) &MovePanelBuffer, MovePanelBufferSize))
|
if (!(MovePanelBuffer = (byte *)calloc(MovePanelBufferSize, 1)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Common::File *file = openPartial("P:Control");
|
Common::File *file = openPartial("P:Control");
|
||||||
|
@ -329,7 +328,7 @@ bool setUpScreens(void) {
|
||||||
if (InvPanelBufferSize == 0L)
|
if (InvPanelBufferSize == 0L)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!allocate((void **) &InvPanelBuffer, InvPanelBufferSize))
|
if (!(InvPanelBuffer = (byte *)calloc(InvPanelBufferSize, 1)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
file = openPartial("P:Inv");
|
file = openPartial("P:Inv");
|
||||||
|
@ -1010,8 +1009,8 @@ from_crumbs:
|
||||||
|
|
||||||
IsHiRes = !IsHiRes;
|
IsHiRes = !IsHiRes;
|
||||||
|
|
||||||
deallocate(MovePanelBuffer, MovePanelBufferSize);
|
free(MovePanelBuffer);
|
||||||
deallocate(InvPanelBuffer, InvPanelBufferSize);
|
free(InvPanelBuffer);
|
||||||
freeButtonList(MoveGadgetList);
|
freeButtonList(MoveGadgetList);
|
||||||
freeButtonList(InvGadgetList);
|
freeButtonList(InvGadgetList);
|
||||||
MoveGadgetList = NULL;
|
MoveGadgetList = NULL;
|
||||||
|
@ -1534,18 +1533,18 @@ from_crumbs:
|
||||||
deleteSet(RoomsFound);
|
deleteSet(RoomsFound);
|
||||||
|
|
||||||
if (Rooms)
|
if (Rooms)
|
||||||
deallocate(Rooms, (ManyRooms + 1) * sizeof(RoomData));
|
free(Rooms);
|
||||||
|
|
||||||
if (Inventory) {
|
if (Inventory) {
|
||||||
for (Code = 1; Code <= NumInv; Code++) {
|
for (Code = 1; Code <= NumInv; Code++) {
|
||||||
if (Inventory[Code].name)
|
if (Inventory[Code].name)
|
||||||
deallocate(Inventory[Code].name, strlen(Inventory[Code].name) + 1);
|
free(Inventory[Code].name);
|
||||||
|
|
||||||
if (Inventory[Code].BInvName)
|
if (Inventory[Code].BInvName)
|
||||||
deallocate(Inventory[Code].BInvName, strlen(Inventory[Code].BInvName) + 1);
|
free(Inventory[Code].BInvName);
|
||||||
}
|
}
|
||||||
|
|
||||||
deallocate(Inventory, (NumInv + 1) * sizeof(InventoryData));
|
free(Inventory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
|
|
||||||
#include "lab/stddefines.h"
|
#include "lab/stddefines.h"
|
||||||
#include "lab/interface.h"
|
#include "lab/interface.h"
|
||||||
#include "lab/storage.h"
|
|
||||||
#include "lab/timing.h"
|
#include "lab/timing.h"
|
||||||
#include "lab/mouse.h"
|
#include "lab/mouse.h"
|
||||||
#include "lab/vga.h"
|
#include "lab/vga.h"
|
||||||
|
@ -45,7 +44,7 @@ Common::KeyState _keyPressed;
|
||||||
struct Gadget *createButton(uint16 x, uint16 y, uint16 id, uint16 key, Image *im, Image *imalt) {
|
struct Gadget *createButton(uint16 x, uint16 y, uint16 id, uint16 key, Image *im, Image *imalt) {
|
||||||
Gadget *gptr;
|
Gadget *gptr;
|
||||||
|
|
||||||
if (allocate((void **)&gptr, sizeof(struct Gadget))) {
|
if ((gptr = (Gadget *)calloc(sizeof(struct Gadget), 1))) {
|
||||||
gptr->x = x;
|
gptr->x = x;
|
||||||
gptr->y = y;
|
gptr->y = y;
|
||||||
gptr->GadgetID = id;
|
gptr->GadgetID = id;
|
||||||
|
@ -71,7 +70,7 @@ void freeButtonList(Gadget *gptrlist) {
|
||||||
gptr = next;
|
gptr = next;
|
||||||
next = next->NextGadget;
|
next = next->NextGadget;
|
||||||
|
|
||||||
deallocate(gptr, sizeof(struct Gadget));
|
free(gptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
|
|
||||||
#include "lab/labfun.h"
|
#include "lab/labfun.h"
|
||||||
#include "lab/mouse.h"
|
#include "lab/mouse.h"
|
||||||
#include "lab/storage.h"
|
|
||||||
#include "common/file.h"
|
#include "common/file.h"
|
||||||
|
|
||||||
namespace Lab {
|
namespace Lab {
|
||||||
|
@ -306,8 +305,7 @@ void resetBuffer(void) {
|
||||||
/* Initializes the buffer. */
|
/* Initializes the buffer. */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
bool initBuffer(uint32 BufSize, bool IsGraphicsMem) {
|
bool initBuffer(uint32 BufSize, bool IsGraphicsMem) {
|
||||||
if (!allocate((void **) &buffer, BufSize))
|
buffer = (byte *)calloc(BufSize, 1);
|
||||||
buffer = NULL;
|
|
||||||
|
|
||||||
buffersize = BufSize;
|
buffersize = BufSize;
|
||||||
realbuffersize = buffersize;
|
realbuffersize = buffersize;
|
||||||
|
@ -328,7 +326,7 @@ void freeBuffer(void) {
|
||||||
freeAllStolenMem();
|
freeAllStolenMem();
|
||||||
|
|
||||||
if (buffer)
|
if (buffer)
|
||||||
deallocate(buffer, buffersize);
|
free(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lab/stddefines.h"
|
#include "lab/stddefines.h"
|
||||||
#include "lab/storage.h"
|
|
||||||
#include "lab/labfun.h"
|
#include "lab/labfun.h"
|
||||||
#include "lab/timing.h"
|
#include "lab/timing.h"
|
||||||
#include "lab/mouse.h"
|
#include "lab/mouse.h"
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
|
|
||||||
#include "lab/stddefines.h"
|
#include "lab/stddefines.h"
|
||||||
#include "lab/labfun.h"
|
#include "lab/labfun.h"
|
||||||
#include "lab/storage.h"
|
|
||||||
|
|
||||||
namespace Lab {
|
namespace Lab {
|
||||||
|
|
||||||
|
@ -44,7 +43,7 @@ const uint32 LargeSetSIZE = sizeof(LargeSetRecord) - 2;
|
||||||
bool createSet(LargeSet *set, uint16 last) {
|
bool createSet(LargeSet *set, uint16 last) {
|
||||||
last = (((last + 15) >> 4) << 4);
|
last = (((last + 15) >> 4) << 4);
|
||||||
|
|
||||||
if (allocate((void **) set, (last >> 3) + LargeSetSIZE)) {
|
if ((*set = (LargeSet)calloc((last >> 3) + LargeSetSIZE, 1))) {
|
||||||
(*set)->lastElement = last;
|
(*set)->lastElement = last;
|
||||||
return true;
|
return true;
|
||||||
} else /* Not Enough Memory! */
|
} else /* Not Enough Memory! */
|
||||||
|
@ -59,8 +58,8 @@ bool createSet(LargeSet *set, uint16 last) {
|
||||||
/* Deletes a large set. */
|
/* Deletes a large set. */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
void deleteSet(LargeSet set) {
|
void deleteSet(LargeSet set) {
|
||||||
if (set != NULL)
|
if (set)
|
||||||
deallocate(set, (set->lastElement >> 3) + LargeSetSIZE);
|
free(set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lab/stddefines.h"
|
#include "lab/stddefines.h"
|
||||||
#include "lab/storage.h"
|
|
||||||
#include "lab/labfun.h"
|
#include "lab/labfun.h"
|
||||||
|
|
||||||
namespace Lab {
|
namespace Lab {
|
||||||
|
@ -67,7 +66,7 @@ static void setString(char **string) {
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
bool initLabText(void) {
|
bool initLabText(void) {
|
||||||
if ((SizeOfMemChunk = sizeOfFile(LABTEXTFILE)))
|
if ((SizeOfMemChunk = sizeOfFile(LABTEXTFILE)))
|
||||||
if (allocate((void **) &BeginOfMemChunk, SizeOfMemChunk)) {
|
if ((BeginOfMemChunk = (char *)calloc(SizeOfMemChunk, 1))) {
|
||||||
Common::File *file = openPartial(LABTEXTFILE);
|
Common::File *file = openPartial(LABTEXTFILE);
|
||||||
|
|
||||||
if (file) {
|
if (file) {
|
||||||
|
@ -146,7 +145,7 @@ bool initLabText(void) {
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
void freeLabText(void) {
|
void freeLabText(void) {
|
||||||
if (SizeOfMemChunk && BeginOfMemChunk)
|
if (SizeOfMemChunk && BeginOfMemChunk)
|
||||||
deallocate(BeginOfMemChunk, SizeOfMemChunk);
|
free(BeginOfMemChunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lab/storage.h"
|
#include "lab/stddefines.h"
|
||||||
#include "lab/labfun.h"
|
#include "lab/labfun.h"
|
||||||
#include "lab/diff.h"
|
#include "lab/diff.h"
|
||||||
#include "lab/vga.h"
|
#include "lab/vga.h"
|
||||||
|
@ -38,7 +38,6 @@
|
||||||
#include "lab/parsetypes.h"
|
#include "lab/parsetypes.h"
|
||||||
#include "lab/interface.h"
|
#include "lab/interface.h"
|
||||||
#include "lab/text.h"
|
#include "lab/text.h"
|
||||||
#include "lab/stddefines.h"
|
|
||||||
|
|
||||||
namespace Lab {
|
namespace Lab {
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@ MODULE_OBJS := \
|
||||||
savegame.o \
|
savegame.o \
|
||||||
savegamepalmap.o \
|
savegamepalmap.o \
|
||||||
special.o \
|
special.o \
|
||||||
storage.o \
|
|
||||||
text.o \
|
text.o \
|
||||||
timing.o \
|
timing.o \
|
||||||
undiff.o \
|
undiff.o \
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
#include "lab/labfun.h"
|
#include "lab/labfun.h"
|
||||||
#include "lab/parsetypes.h"
|
#include "lab/parsetypes.h"
|
||||||
#include "lab/parsefun.h"
|
#include "lab/parsefun.h"
|
||||||
#include "lab/storage.h"
|
|
||||||
#include "lab/stddefines.h"
|
#include "lab/stddefines.h"
|
||||||
|
|
||||||
namespace Lab {
|
namespace Lab {
|
||||||
|
@ -56,7 +55,7 @@ static uint16 allocroom;
|
||||||
|
|
||||||
static bool rallocate(void **Ptr, uint32 Size) {
|
static bool rallocate(void **Ptr, uint32 Size) {
|
||||||
if (UseMemory)
|
if (UseMemory)
|
||||||
return allocate(Ptr, Size);
|
return ((*Ptr = calloc(Size, 1)) != 0);
|
||||||
else {
|
else {
|
||||||
allocRoom(Ptr, (uint16) Size, allocroom);
|
allocRoom(Ptr, (uint16) Size, allocroom);
|
||||||
return true;
|
return true;
|
||||||
|
@ -89,7 +88,7 @@ bool readRoomData(const char *fileName) {
|
||||||
swapUShortPtr(&HighestCondition, 1);
|
swapUShortPtr(&HighestCondition, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (allocate((void **) &Rooms, (ManyRooms + 1) * sizeof(RoomData))) {
|
if ((Rooms = (RoomData *)calloc(ManyRooms + 1, sizeof(RoomData)))) {
|
||||||
for (Counter = 1; Counter <= ManyRooms; Counter++) {
|
for (Counter = 1; Counter <= ManyRooms; Counter++) {
|
||||||
readBlock(&(Rooms[Counter].NorthDoor), 2L, file);
|
readBlock(&(Rooms[Counter].NorthDoor), 2L, file);
|
||||||
readBlock(&(Rooms[Counter].SouthDoor), 2L, file);
|
readBlock(&(Rooms[Counter].SouthDoor), 2L, file);
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
/* ScummVM - Graphic Adventure Engine
|
|
||||||
*
|
|
||||||
* ScummVM is the legal property of its developers, whose names
|
|
||||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
||||||
* file distributed with this source distribution.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This code is based on Labyrinth of Time code with assistance of
|
|
||||||
*
|
|
||||||
* Copyright (c) 1993 Terra Nova Development
|
|
||||||
* Copyright (c) 2004 The Wyrmkeep Entertainment Co.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "lab/stddefines.h"
|
|
||||||
|
|
||||||
namespace Lab {
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/* Allocates a chunk of memory. */
|
|
||||||
/*****************************************************************************/
|
|
||||||
bool allocate(void **Ptr, uint32 Size) {
|
|
||||||
(*Ptr) = malloc(Size);
|
|
||||||
|
|
||||||
if (*Ptr)
|
|
||||||
memset(*Ptr, 0, (size_t) Size);
|
|
||||||
|
|
||||||
return (*Ptr != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/* Deallocates a piece of memory. */
|
|
||||||
/*****************************************************************************/
|
|
||||||
void deallocate(void *Ptr, uint32 Size) {
|
|
||||||
if (Ptr)
|
|
||||||
free(Ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // End of namespace Lab
|
|
|
@ -1,44 +0,0 @@
|
||||||
/* ScummVM - Graphic Adventure Engine
|
|
||||||
*
|
|
||||||
* ScummVM is the legal property of its developers, whose names
|
|
||||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
||||||
* file distributed with this source distribution.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This code is based on Labyrinth of Time code with assistance of
|
|
||||||
*
|
|
||||||
* Copyright (c) 1993 Terra Nova Development
|
|
||||||
* Copyright (c) 2004 The Wyrmkeep Entertainment Co.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "lab/stddefines.h"
|
|
||||||
|
|
||||||
#ifndef LAB_STORAGE_H
|
|
||||||
#define LAB_STORAGE_H
|
|
||||||
|
|
||||||
namespace Lab {
|
|
||||||
|
|
||||||
bool allocate(void **Ptr, uint32 Size);
|
|
||||||
|
|
||||||
void deallocate(void *Ptr, uint32 Size);
|
|
||||||
|
|
||||||
} // End of namespace Lab
|
|
||||||
|
|
||||||
#endif /* LAB_STORAGE_H */
|
|
|
@ -30,7 +30,6 @@
|
||||||
|
|
||||||
#include "lab/stddefines.h"
|
#include "lab/stddefines.h"
|
||||||
#include "lab/labfun.h"
|
#include "lab/labfun.h"
|
||||||
#include "lab/storage.h"
|
|
||||||
#include "lab/text.h"
|
#include "lab/text.h"
|
||||||
#include "lab/vga.h"
|
#include "lab/vga.h"
|
||||||
|
|
||||||
|
@ -81,7 +80,7 @@ bool openFont(const char *TextFontPath, struct TextFont **tf) {
|
||||||
char header[5];
|
char header[5];
|
||||||
int32 filesize, headersize = 4L + 2L + 256 * 3 + 4L;
|
int32 filesize, headersize = 4L + 2L + 256 * 3 + 4L;
|
||||||
|
|
||||||
if (allocate((void **)tf, sizeof(struct TextFont))) {
|
if ((*tf = (TextFont *)calloc(sizeof(struct TextFont), 1))) {
|
||||||
filesize = sizeOfFile(TextFontPath);
|
filesize = sizeOfFile(TextFontPath);
|
||||||
file = g_music->newOpen(TextFontPath);
|
file = g_music->newOpen(TextFontPath);
|
||||||
|
|
||||||
|
@ -102,14 +101,14 @@ bool openFont(const char *TextFontPath, struct TextFont **tf) {
|
||||||
#endif
|
#endif
|
||||||
skip(file, 4L);
|
skip(file, 4L);
|
||||||
|
|
||||||
if (allocate((void **) & ((*tf)->data), (*tf)->DataLength)) {
|
if (((*tf)->data = (byte *)calloc((*tf)->DataLength, 1))) {
|
||||||
readBlock((*tf)->data, (*tf)->DataLength, file);
|
readBlock((*tf)->data, (*tf)->DataLength, file);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deallocate(*tf, sizeof(struct TextFont));
|
free(*tf);
|
||||||
}
|
}
|
||||||
|
|
||||||
*tf = NULL;
|
*tf = NULL;
|
||||||
|
@ -123,9 +122,9 @@ bool openFont(const char *TextFontPath, struct TextFont **tf) {
|
||||||
void closeFont(struct TextFont *tf) {
|
void closeFont(struct TextFont *tf) {
|
||||||
if (tf) {
|
if (tf) {
|
||||||
if (tf->data && tf->DataLength)
|
if (tf->data && tf->DataLength)
|
||||||
deallocate(tf->data, tf->DataLength);
|
free(tf->data);
|
||||||
|
|
||||||
deallocate(tf, sizeof(struct TextFont));
|
free(tf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
|
|
||||||
#include "lab/vga.h"
|
#include "lab/vga.h"
|
||||||
#include "lab/stddefines.h"
|
#include "lab/stddefines.h"
|
||||||
#include "lab/storage.h"
|
|
||||||
#include "lab/mouse.h"
|
#include "lab/mouse.h"
|
||||||
|
|
||||||
#include "graphics/palette.h"
|
#include "graphics/palette.h"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue