Is it possible to have a header file compile differently in two different source files by using defines in the source files?
For example, if i have a single header included in two source files as in:
header.h:
#if FOO
#define BAR(x) f(x)
#else
#define BAR(x) g(x)
#endif
source1.cpp:
#define FOO 1
#include "header.h"
void a(int x) {
BAR(x); // f(x)?
}
source2.cpp
#include "header.h"
void b(int x) {
BAR(x); // g(x)?
}
Should this not compile so that function a performs f and function b performs g?
I'm trying to do this in XCode and Objective-C++. Both a and b perform g as if source1.cpp didn't define FOO.
Your macro is defined incorrectly correctly. The mistake is that it should be However I prefer to use #ifdef and not #if
#ifdef FOO
#define BAR(x) f(x)
#else
#define BAR(x) g(x)
#endif
In addition you do not have to give FOO a value, all you need to do is to #define it in source1.cpp
#define FOO
#include "header.h"
In source2.cpp I would also ensure that FOO is not defined (as a carry over from any other includes) by doing:
#ifdef FOO
#undef FOO
#endif
#include "header.h"
EDIT
I was a bit quick to say that the macro was wrong. As per this SO question What is the value of an undefined constant used in #if? (C++) the #if should work as given by the OP, as the value of FOO should decay to 0 when it is not defined.
However I think that using #ifdef provides more context as to what is actually desired.
Thus I suspect that the definition of FOO is sneaking in unexpectedly somewhere.
For your case, The best way to differentiate based on macros is, using the toggle method:
#ifdef FOO
#define BAR(x) f(x)
#undef FOO
#else
#define BAR(x) g(x)
#endif
source1.cpp:
#define FOO
#include "header.h"
void a(int x) {
BAR(x); // f(x)?
}
source2.cpp
#undef FOO
#include "header.h"
void b(int x) {
BAR(x); // g(x)?
}
For more control try this:
#ifdef FOO
#if FOO == 1
#define BAR(x) f(x)
#undef FOO
#elif FOO == 2
#define BAR(x) g(x)
#undef FOO
#endif
#endif
And write like this:
source1.cpp:
#undef FOO
#define FOO 1
#include "header.h"
void a(int x) {
BAR(x); // f(x)?
}
source2.cpp
#undef FOO
#define FOO 2
#include "header.h"
void b(int x) {
BAR(x); // g(x)?
}
There are several ways you can achieve, what you asked.
Hope this helps.
The problem was that the header was after all indirectly included in the precompiled headers. XCode seems to include the precompiled headers automatically to every compilation unit, therefore only one version of the macro was available. The version precompiled was the one without the definition i.e. the #else-branch because no source files has been read at the time of the precompilation.
I will accept Peter M's answer as he came to the right conclusion about this.
The toggle method by askmish didn't help in my case, but that's the way i'll do this in the future, since that would have lead to the solution immediately.
Related
I'm a new to use CMAKE. I want to use the kernels in cuda as a static library and use " extern "C" void function();" to call it. Finally I will use cmake to compile the whole project. But its running speed in GPU didn't satisfied me. So I used Nsight eclispe to run it severally in debug and release. After analyzing them in NVVP.I found the default mode of cmake in static library is debug mode.
So how can I change the debug mode to release in static library?
Firstly, I create a project in Nsight eclipse.
Below is the example of the file structure that I have.
Test_in_stack
-release
-debug
-src
--GPU.cu
--simpleCUFFT.cu
-lib
--GPU.cuh
--Kernels.h
The content of src/simpleCUFFT.cu is:
// includes, system
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
// includes, project
// #include <Kernels.h>
#include <GPU.cuh>
#include <cuda_runtime.h>
#include <cufft.h>
#include <cufftXt.h>
#include <helper_functions.h>
#include <helper_cuda.h>
#include <device_functions.h>
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/sort.h>
#include <thrust/generate.h>
#include <thrust/sequence.h>
#include <thrust/device_ptr.h>
#include <thrust/extrema.h>
#include <thrust/execution_policy.h>
#include <thrust/equal.h>
#include <thrust/for_each.h>
// Complex data type
typedef float2 Complex;
#define FFT_NUM 1024
#define RANGE_NUM 1024
#define SIGNAL_SIZE RANGE_NUM*FFT_NUM
extern "C" void GPU_Pro(Complex *h_signal,int *h_count);
////////////////////////////////////////////////////////////////////////////////
// Program main
////////////////////////////////////////////////////////////////////////////////
int main()
{
Complex *h_signal = (Complex *)malloc(sizeof(Complex) * SIGNAL_SIZE);
int *h_count = (int *)malloc(sizeof(int) * SIGNAL_SIZE);
// Initialize the memory for the signal
for (unsigned int i = 0; i < SIGNAL_SIZE; ++i)
{
h_signal[i].x = rand() / (float)RAND_MAX;
h_signal[i].y = rand() / (float)RAND_MAX;
h_count[i]=i/FFT_NUM;
}
GPU_Pro(h_signal,h_count);
cudaDeviceReset();
}
The content of src/GPU.cu is:
#include <Kernels.h>
#include <GPU.cuh>
#include <cuda_runtime.h>
#include <cufft.h>
#include <cufftXt.h>
#include <helper_functions.h>
#include <helper_cuda.h>
#include <device_functions.h>
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/sort.h>
#include <thrust/generate.h>
#include <thrust/sequence.h>
#include <thrust/device_ptr.h>
#include <thrust/extrema.h>
#include <thrust/execution_policy.h>
#include <thrust/equal.h>
#include <thrust/for_each.h>
typedef float2 Complex;
#define FFT_NUM 1024
#define RANGE_NUM 1024
#define SIGNAL_SIZE RANGE_NUM*FFT_NUM
void GPU_Pro(Complex *h_signal,int *h_count)
{
Complex *d_signal;
float *d_signal_float;
int *d_count;
cudaMalloc((void **)&d_signal, SIGNAL_SIZE*sizeof(Complex));
cudaMalloc((void **)&d_count, SIGNAL_SIZE*sizeof(int));
cudaMalloc((void **)&d_signal_float, SIGNAL_SIZE*sizeof(float));
cufftHandle plan;
checkCudaErrors(cufftPlan1d(&plan, FFT_NUM, CUFFT_C2C, 1));
dim3 dimblock(32, 32);
dim3 dimgrid(FFT_NUM / 32, RANGE_NUM / 32);
// Copy host memory to device
checkCudaErrors(cudaMemcpy(d_signal, h_signal, SIGNAL_SIZE*sizeof(Complex),
cudaMemcpyHostToDevice));
checkCudaErrors(cudaMemcpy(d_count, h_count, SIGNAL_SIZE*sizeof(int),
cudaMemcpyHostToDevice));
for(int i=0;i<RANGE_NUM;i++)
{
checkCudaErrors(cufftExecC2C(plan, d_signal+i*RANGE_NUM, d_signal+i*RANGE_NUM, CUFFT_FORWARD));
}
MatAbsNaive_float<<<dimgrid,dimblock>>>(d_signal,d_signal_float,FFT_NUM,RANGE_NUM);
thrust::stable_sort_by_key(thrust::device_pointer_cast(d_signal_float),thrust::device_pointer_cast(d_signal_float)+SIGNAL_SIZE,thrust::device_pointer_cast(d_count));
thrust::stable_sort_by_key(thrust::device_pointer_cast(d_count),thrust::device_pointer_cast(d_count)+SIGNAL_SIZE,thrust::device_pointer_cast(d_signal_float));
cudaDeviceReset();
}
The content of lib/Kernels.h is:
/*
* Kernels.h
*
* Created on: Jan 10, 2019
* Author: root
*/
#include "iostream"
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include "stdio.h"
#include <stdlib.h>
#include <string.h>
#include "math.h"
#include <mat.h>
#include "cuComplex.h"
#include "cublas.h"
#include <cufft.h>
#include <cufftXt.h>
#include <time.h>
#include <cublas_v2.h>
__global__ void MatAbsNaive_float(cuComplex *idata, float *odata, int M, int N)
{
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
if ((x < M) && (y < N))
{
odata[x + M*y] = sqrt(idata[x + M*y].x * idata[x + M*y].x + idata[x + M*y].y * idata[x + M*y].y);
}
}
The content of lib/GPU.cuh is:
#ifndef GPU_CUH
#define GPU_CUH
#include <stdio.h>
#include "cuComplex.h"
typedef float2 Complex;
extern "C"
void GPU_Pro(Complex *h_signal,int *h_count);
#endif
The result of NVVP in debug and release are as follows:
debug
release
Then I put the same files in cmake.
Below is the example of the file structure that I have.
Test_in_stack
-CMakeLists(1).txt
-build
-src
--CMakeLists(2).txt
--simpleCUFFT.cpp
-lib
--CMakeLists(3).txt
--GPU.cu
--GPU.cuh
--Kernels.h
The (1)、(2)、(3) are labels, the real file names are both CMakeLists.txt. And the content of simpleCUFFT.cu and simpleCUFFT.cpp are the same.
The content of CMakeLists(1).txt is:
cmake_minimum_required (VERSION 2.6)
PROJECT(GPU_MODE C CXX)
#PROJECT(GPU_MODE)
ADD_SUBDIRECTORY(src bin)
ADD_SUBDIRECTORY(lib)
The content of CMakeLists(2).txt is:
INCLUDE_DIRECTORIES(
${eclipse_home}VSPS/include
/usr/include
${eclipse_home}PetDCPS/include
/user/include/c++
/usr/local/cuda-8.0/include
)
INCLUDE_DIRECTORIES(/root/Chenjie/cuda-workspace/Test_in_stack/lib
/usr/local/cuda-8.0/samples/common/inc
/usr/local/cuda-8.0/include)
LINK_DIRECTORIES(/usr/local/cuda-8.0/lib64/)
SET(CPU_LIST simpleCUFFT.cpp)
FIND_PACKAGE(CUDA REQUIRED)
SET(EXTRA_LIBS ${EXTRA_LIBS} gpu ${CUDA_LIBRARIES})
ADD_EXECUTABLE(CPUProcessTest ${CPU_LIST})
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/src)
TARGET_LINK_LIBRARIES(CPUProcessTest optimized ${EXTRA_LIBS} vsip_c)
The content of CMakeLists(3).txt is:
#for cuda
PROJECT(gpu)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
INCLUDE_DIRECTORIES(/root/Chenjie/cuda-workspace/Test_in_stack/lib
/usr/local/cuda-8.0/samples/common/inc
/usr/local/cuda-8.0/include)
FIND_PACKAGE(CUDA QUIET REQUIRED)
#SET(CUDA_NVCC_FLAGS -03;-G;-g)
SET(CUDA_NVCC_FLAGS -gencode arch=compute_52,code=sm_52;-G;-g;-lcufft;-lcudart;-lcublas)
SET(CMAKE_CUDA_FLAGS ${CUDA_NVCC_FLAGS_RELEASE})
FILE(GLOB_RECURSE CURRENT_HEADERS *.h *.hpp *.cuh)
FILE(GLOB CURRENT_SOURCES *.cpp *.cu)
SOURCE_GROUP("Include" FILES ${CURRENT_HEADERS})
SOURCE_GROUP("Source" FILES ${CURRENT_SOURCES})
INCLUDE_DIRECTORIES(/usr/local/cuda-8.0/include)
LINK_DIRECTORIES(/usr/local/cuda-8.0/lib64/)
LINK_LIBRARIES(cufft cublas)
#TARGET_LINK_LIBRARIES(gpu ${CUDA_LIBRARIES})
#CUDA_ADD_LIBRARY(gpu SHARED ${CURRENT_HEADERS} ${CURRENT_SOURCES})
CUDA_ADD_LIBRARY(gpu STATIC ${CURRENT_HEADERS} ${CURRENT_SOURCES} ${CUDA_LIBRARIES} ${CUDA_CUFFT_LIBRARIES})
I used the command line in /built as follows:
cmake -DCMAKE_BUILD_TYPE=Release ..
make
But it didn't work. It seems it still run in debug as the NVVP result shows:
cmake result
So how can I change to compile flag to release in static library of cuda.
I'm using Red Hat Enterprise Linux Server 7.1(Maipo)、cuda 8.0 、cmake version 2.8.12.2、GNU Make 3.82.
Update in 2019.01.12
I added MESSAGE(STATUS "Build type:" ${CMAKE_BUILD_TYPE}") in CMakeLists(2).txt. And the result is:
[root#node2 build]# cmake -DCMAKE_BUILD_TYPE=Release ..
-- Build type: Release
-- Configuring done
-- Generating done
But the result in NVVP didn't change.
Well, I have found out a way to solve it.
I change the line 10 and line 11 in CMakeLists(3).txt to
SET(CUDA_NVCC_FLAGS -gencode arch=compute_52,code=sm_52;-lcufft;-lcudart;-lcublas)
SET(CMAKE_CUDA_FLAGS ${CUDA_NVCC_FLAGS} -O3 -DNDEBUG)
After doing
cmake -DCMAKE_BUILD_TYPE=Release ..
make clean
make
The result in NVVP shows it is compiled with Release mode.
I'm using the CocoaLumberjack logging framework 2.0.0 for logging with different levels. In my Prefix.pch (I know that this file is deprecated, but it should work nevertheless) I include Cocoalumberjack and set the global log level as suggested here:
#ifdef DEBUG
static const DDLogLevel ddLogLevel = DDLogLevelDebug;
#else
static const DDLogLevel ddLogLevel = DDLogLevelWarn;
#endif
I have a DDLogVerbose statement on a few methods, that should not be logged by default. Problem: However, they are getting logged.
Inspecting the ddLogLevel in an init-function shows 00001111, which equals DDLogLevelDebug. Nevertheless, a verbose logging statement directly after this is executed. (1)
Preprocessing the line DDLogVerbose(#"I AM VERBOSE") shows this code:
do {
if(DDLogLevelVerbose & DDLogFlagVerbose)
[DDLog log : __objc_yes
level : DDLogLevelVerbose
flag : DDLogFlagVerbose
context : 0
file : "....m"
function : __PRETTY_FUNCTION__
line : 59
tag : ((void *)0)
format : (#"I AM VERBOSE")];
} while(0);
which means, that the LogLevel after preprocessing is Verbose. (2) I found out that this level is the default in CocoaLumberjack in case, no log level is defined:
#ifndef LOG_LEVEL_DEF
#ifdef ddLogLevel
#define LOG_LEVEL_DEF ddLogLevel
#else
#define LOG_LEVEL_DEF DDLogLevelVerbose
#endif
#endif
But: Debugging this shows that the first path is executed, i.e. LOG_LEVEL_DEF (which is checked against the level of the statement to determine if it should be logged or not) is assigned the correct level (Debug).
Question: I didn't find out, why (1) shows the LogLevel Debug and, after preprocessing, it switched to Verbose (2). Could this be a matter of the order in which headers are included? Or am I missing some important point?
I didn't solve this issue, so I wrote my own header file for logging:
// Create Logging Messages by calling the functions:
// * DDLogFatal(...)
// * DDLogError(...)
// * DDLogWarn(...)
// * DDLogInfo(...)
// * DDLogDebug(...)
// * DDLogTrace(...)
// * DDLogTrace()
// Only the functions that match Log Level (defined beneath) and above this level will lead to an output.
//
// NOTE: For this file to work, the option "Treat warnings as errors" must be turned off!
/*********************************
* CURRENT LOG LEVEL ***
*********************************/
#define LOG_LEVEL LOG_LEVEL_DEBUG
/* Default Log Level */
#ifndef LOG_LEVEL
#ifdef DEBUG
#define LOG_LEVEL LOG_LEVEL_DEBUG
#else
#define LOG_LEVEL LOG_LEVEL_WARN
#endif
#endif
/* List of Log Levels */
#define LOG_LEVEL_OFF 0 // 0000 0000
#define LOG_LEVEL_FATAL 1 // 0000 0001
#define LOG_LEVEL_ERROR 3 // 0000 0011
#define LOG_LEVEL_WARN 7 // 0000 0111
#define LOG_LEVEL_INFO 15 // 0000 1111
#define LOG_LEVEL_DEBUG 31 // 0001 1111
#define LOG_LEVEL_TRACE 63 // 0011 1111
#define LOG_FLAG_FATAL 1 // 0000 0001
#define LOG_FLAG_ERROR 2 // 0000 0010
#define LOG_FLAG_WARN 4 // 0000 0100
#define LOG_FLAG_INFO 8 // 0000 1000
#define LOG_FLAG_DEBUG 16 // 0001 0000
#define LOG_FLAG_TRACE 32 // 0010 0000
#if (LOG_LEVEL & LOG_FLAG_FATAL) > 0
#define DDLogFatal(...) ALog(#"FATAL", __VA_ARGS__)
#else
#define DDLogFatal(...)
#endif
#if (LOG_LEVEL & LOG_FLAG_ERROR) > 0
#define DDLogError(...) ALog(#"ERROR", __VA_ARGS__)
#else
#define DDLogError(...)
#endif
#if (LOG_LEVEL & LOG_FLAG_WARN) > 0
#define DDLogWarn(...) ALog(#"WARNING", __VA_ARGS__)
#else
#define DDLogWarn(...)
#endif
#if (LOG_LEVEL & LOG_FLAG_INFO) > 0
#define DDLogInfo(...) ALog(#"INFO", __VA_ARGS__)
#else
#define DDLogInfo(...)
#endif
#if (LOG_LEVEL & LOG_FLAG_DEBUG) > 0
#define DDLogDebug(...) ALog(#"DEBUG", __VA_ARGS__)
#else
#define DDLogDebug(...)
#endif
#if (LOG_LEVEL & LOG_FLAG_TRACE) > 0
#define DDLogTrace(...) ALog(#"TRACE", __VA_ARGS__)
#define DDLogEntry() ALog(#"TRACE", #"->")
#else
#define DDLogTrace(...)
#define DDLogEntry()
#endif
#define ALog(logLevel, fmt, ...) NSLog((#"%s [Line %d] %#: " fmt), __PRETTY_FUNCTION__, __LINE__, logLevel, ##__VA_ARGS__)
Include this file wherever Logging is needed. Hope this helps someone!
So I'm not sure if this is the same issue you were running into, but I had a similar symptom, i.e. my log levels being ignored. What was happening for me is that the cocoa lumberjack folks made it easier in v2 for new users to get started by not having to specify a log level at all to get the framework to work.
As per the lumberjack docs, to actually use ddLogLevel I needed to #define it before importing the CocoaLumberjack.h file:
Using ddLogLevel to start using
the library is now optional. If you define it add #define
LOG_LEVEL_DEF ddLogLevel before #import
and make change its type to
DDLogLevel
In my case, I'm doing that in the .pch file, so it looks like:
// ProjectX.pch
#define LOG_LEVEL_DEF ddLogLevel // this is the crucial bit!
#import "CocoaLumberjack/CocoaLumberjack.h"
// Then the normal definitions...
#ifdef DEBUG
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"
static DDLogLevel ddLogLevel = DDLogLevelWarning;
#pragma clang diagnostic pop
#else
static const DDLogLevel ddLogLevel = DDLogLevelWarning;
#endif
#define LOG_LEVEL_DEF ddLogLevel
CocoaLumberjack has 4 log levels
Error
Warning
Info
Verbose
The "ddLogLevel" determines which logs are to be executed and which to be ignored.
If you do not want DDLogVerbose to be executed change to lower levels like Info.
Change your DEBUG macro as follows
#ifdef DEBUG
static const int ddLogLevel = LOG_LEVEL_INFO;
#else
static const int ddLogLevel = LOG_LEVEL_ERROR;
#endif
Hope this solves your issue.
I'd like to use
#define IS_APP_FULL_VERSION NO
and the code
isAppFullVersion = IS_APP_FULL_VERSION;
to set instance variable. But is there a way to also do
#if IS_APP_FULL_VERSION == "NO"
// add some methods here
#endif
but it would give a compile error, and so is #if (IS_APP_FULL_VERSION == "NO"). Is there a way to check it against YES and NO? (check against the substitution value)
Update: it seems like > and == 0 is allowed, such as
#if IS_APP_FULL_VERSION == 0
so we can actually use 0 and 1 for false and true, and use == 1 to test, but it will be better if YES and NO can be used.
Update 2:
One possible solution turns out to be:
#define IS_APP_FULL_VERSION 1
#if IS_APP_FULL_VERSION
// add some methods here
#endif
isAppFullVersion = IS_APP_FULL_VERSION;
will all work, and we can just change 1 to 0 to toggle the code.
Your basic problem is that the macro processor #if statement only has one data type -- integer. All #if expressions are evaluated in integer, with undefined symbols being replaced with zero. String expressions (including comparisons) cannot be evaluated.
Actually, normally, I would just use a flag macro rather than a value one, since there's only two cases here:
#define APP_IS_FULL_VERSION
Either define or don't define that macro. Then, if you later wanted to include/exclude code based on that, you can use:
#ifdef APP_IS_FULL_VERSION
// Do something
#endif
(or #ifndef for the opposite case, obviously).
For the code segment, it's a simple matter of using that to select the correct code:
#ifdef APP_IS_FULL_VERSION
isAppFullVersion = YES;
#else
isAppFullVersion = NO;
#endif
I think, you're some confused comparison MACRO.
#define format is following it.
#define MACRO_NAME VALUE (VALUE is blank spaces are also fine. MACRO_NAME need is.)
if you want comparison compile-time following like it. this is comparison mean only defined vs no defined. not YES vs NO
#define IS_APP_FULL_VERSION 1
#if defined IS_APP_FULL_VERSION
NSLog(#"full-verison");
#endif
#define IS_APP_FULL_VERSION blahblah
#if defined IS_APP_FULL_VERSION
NSLog(#"full-verison");
#endif
If you want to build separate versions of. refer a following like it.
#define IS_APP_FREE_VERSION
#if defined IS_APP_FREE_VERSION
NSLog(#"free-version");
#endif
#define IS_APP_FULL_VERSION
#if defined IS_APP_FULL_VERISON
NSLog(#"full-version");
#endif
if you want comparison runtime following like it. this is comparsion normally.
#define IS_APP_FULL_VERSION 1
if(IS_APP_FULL_VERSION)
{
NSLog(#"full-verison");
}
#define IS_APP_FULL_VERSION 0
if(!IS_APP_FULL_VERSION)
{
NSLog(#"no full-version");
}
I am compiling the following code with the -ffast-math option:
#include <limits>
#include <cmath>
#include <iostream>
int main() {
std::cout << std::isnan(std::numeric_limits<double>::quiet_NaN() ) << std::endl;
}
I am getting 0 as output. How can my code tell whether a floating point number is NaN when it is compiled with -ffast-math?
Note: On linux, std::isnan works even with -ffast-math.
Since -ffast-math instructs GCC not to handle NaNs, it is expected that isnan() has an undefined behaviour. Returning 0 is therefore valid.
You can use the following fast replacement for isnan():
#if defined __FAST_MATH__
# undef isnan
#endif
#if !defined isnan
# define isnan isnan
# include <stdint.h>
static inline int isnan(float f)
{
union { float f; uint32_t x; } u = { f };
return (u.x << 1) > 0xff000000u;
}
#endif
On linux, the gcc flag -ffast-math breaks isnan(), isinf() and isfinite() - there may be other related functions that are also broken that I have not tested.
The trick of wrapping the function/macro in parentheses also did not work (ie. (isnan)(x))
Removing -ffast-math works ;-)
I am installing mod_mono with Apache 2 on FreeBSD and I get the following error when Apache tries to load the mod_mono.so module.
Cannot load
/usr/local/apache/modules/mod_mono.so
into server:
/usr/local/apache/modules/mod_mono.so:
Undefined symbol "strndup"
The prefix I set for Apache is /usr/local/apache and I have PHP and other modules working already. I found that strndup is referenced in roken.h in /usr/include and I tried the following additions to configure command but it did not work.
--libdir=/usr/lib --includedir=/usr/include
I also tried...
--with-mono-prefix=/usr
I do not know what to try next. It does not appear that mod_mono has many build options. Since Mono and XSP are both built successfully I just need mod_mono to work.
I appreciate any tips to get this working.
Add strndup via implementing it:
ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#if !_LIBC
# include "strndup.h"
#endif
#include <stdlib.h>
#include <string.h>
#if !_LIBC
# include "strnlen.h"
# ifndef __strnlen
# define __strnlen strnlen
# endif
#endif
#undef __strndup
#if _LIBC
# undef strndup
#endif
#ifndef weak_alias
# define __strndup strndup
#endif
char *
__strndup (s, n)
const char *s;
size_t n;
{
size_t len = __strnlen (s, n);
char *new = malloc (len + 1);
if (new == NULL)
return NULL;
new[len] = '\0';
return memcpy (new, s, len);
}
#ifdef libc_hidden_def
libc_hidden_def (__strndup)
#endif
#ifdef weak_alias
weak_alias (__strndup, strndup)
#endif