Using header files without include?

hi..
i have an external library that i need to adapt for arduino.
one of the issues i have is that it has several sources files based on includes.
for example
_WIN32 is part of the compiler, but it i'm compiling for arduino
stpncpy.h header file is actualy located in another library
so 2 questions here.
how do i undef _WIN32 outside the source code (i'm assumign i would need to use undef in my own code
assuming i do manage to undef it.
how is it expected to actually work? i mean there is still a call to stpncpy function in this code but it would fail without a header file ?
so is there a way to say that for this source file?

btw a similar issue is for all those arrays, while in normal c they would work
but for parshahchar array for example, alll those strings would need to written with PSTR to save space on ram.
so how i can alter this header file to be flexible and compilable for both normal pc and arudino?

#include <string.h>
#include <stdio.h>
#include "hebrewcalendar.h"
#include "hdateformat.h"
#ifdef _WIN32
#include <stpncpy.h>
#endif

const char* hchar[]={ "׆", "א", "ב", "ג", "ד", "ה", "ו", "ז", "ח", "ט", "י", "כ", "ל", "מ", "נ", "ס", "ע", "פ", "צ", "ק", "ר", "ש", "ת", "״", "׳"};
const char* hmonth[]={ "אדר א׳", "ניסן", "אייר", "סיון", "תמוז", "אב", "אלול", "תשרי", "חשון", "כסלו", "טבת", "שבט", "אדר", "אדר ב׳"};
const char* hwday[]={ "שביעי", "ראשון", "שני", "שלישי", "רביעי", "חמישי", "שישי", "שבת"};
const char* parshahchar[]={"\0", "בראשית", "נח", "לך לך", "וירא", "חיי שרה", "תולדות", "ויצא", "וישלח", "וישב", "מקץ", "ויגש", "ויחי", "שמות", "וארא", "בא", "בשלח", "יתרו", "משפטים", "תרומה", "תצוה", "כי תשא", "ויקהל", "פקודי", "ויקרא", "צו", "שמיני", "תזריע", "מצורע", "אחרי מות", "קדושים", "אמור", "בהר", "בחוקותי", "במדבר", "נשא", "בהעלותך", "שלח", "קרח", "חקת", "בלק", "פינחס", "מטות", "מסעי", "דברים", "ואתחנן", "עקב", "ראה", "שופטים", "כי תצא", "כי תבוא", "נצבים", "וילך", "האזינו", "וזאת הברכה", "ויקהל - פקודי", "תזריע - מצורע", "אחרי מות - קדושים", "בהר - בחוקותי", "חקת - בלק", "מטות - מסעי", "נצבים - וילך"};

not clear.

don't understand? "outside" the source code ??

"_WIN32" may be defined by a compiler to enable code. it's not defined in gcc running on my Windows laptop and doubt it's defined by avr_gcc. so there doesn't appear to be any need to undef _WIN32. which PC compiler are you using?

if the above code is in your source and _WIN32 is not defined, remove the ifdef/endif

but i'm not sure i completely understand the issue

vscode sure seems to think so,
undef outside the source code, i meant undef it outside the library, so it won't be affected

image

so let's say i've found a way to undef it, so that means stpncpy.h won't be included.
but there's still call for that, so i need to provide that header file

i have a library which has several source folder, ontop of that standard src and include folders it has windows folders (which contains the stpncpy files) and extra folders which also contain source code )

the whole thing is governed by a makefile but i need to use library.json to also make it a proper platormio library , so i cant' exactly use makefile
the only other altnerative is to create pre_compile python script that would simply copy all the files i want from that libary to mine .

declare directly

char *stpncpy(char *dest, const char *src, size_t n);

yea, that's gonna be an issue, besides there could be more src files i need to copy
like the ones on extra folder


the problme those files refer to each using " notation rather than < > so they all assume they will be in the same libray as far as i can see essentially i need the mall in the same folder to be compiled

i'm puzzled by the environment you're working in.

  • what are these files that you're copying, where are they coming from that you have these issues (e.g. _WIN32)

  • why are you using vscode (Visual Studio) and why would it un/define _WIN32? is it just the editor or are you using it's libraries? i use an external editor (vi)

  • why not use strncpy() instead of stpncpy()?

Welcome to "Porting Code", a topic that I wished schools and tutorials would spend more time teaching.

A symbol like _WIN32 would normally get defined somewhere in the build environment, rather than in any of the source code. That basically means either the compiler itself or the Makefile (passing some argument to the compiler.)

Your job is to figure out where it is being set, and remove it (since an arduino is definitely not a WIN32 system!) Then you start fixing the resulting errors, figuring out which symbols need to be defined, and whether they need to be defined differently for an Arduino vs Win32. (it may depend on which Arduino. The Arduino IDE defines several symbols that are used similarly: -DARDUINO=10607 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR) Repeat until done.

  • why not use strncpy() instead of stpncpy()?

Despite being widely recommended as a more secure form of strcpy(), strncpy() is usually NOT the correct function to use for copying strings around. It doesn't guarantee null termination of the destination. I prefer strlcpy(), but it looks like stpncpy() is similar (different return value?)

@westfw @gcjr
i'm assuming _WIN32 is defined by default by the compiler (casue it's _)

what i'm trying to do is use this project as a library for arduino
the author said he has no intention to change for arduino, but said is willling PR
so i checkout is library from source , and trying turn it into platfrom.io library using library.json
so that any changes i'll make it would be consoldiate as the pr commit thus makign the library consumable for any other project that uses arduino

essentially all that i require from the library are hdateformat.h, hdateformat.c , hebrewcalendar.h and hebrewcalendar.c
hebrewcalendar.* seems to be working fine (after i have to change some data types from int to long int because the move to arduino truncates those values)

but the most problematic file is actually this file below

the first thing is every build fails with
ccdOvK9f.ltrans0.ltrans.o: In function addchar.constprop.53': <artificial>:(.text+0x27e6): undefined reference to stpncpy
which means it can't find the stpncpy.c (even though it can find the header which is in the the same folder)

but assuming i'll solve those issues i one major issue is with all the strings.
i have one function there called yomtovformat which uses a lot of switch case returning strings, just including that one, causes memory issues in arduino, so i would to make all those strings into PSTR ones
i also have other isseues in the string values in the array that uses some charachters that won't display well on arduino LCD.
so those need to be changed as well.

the most tempting thing seems to be excluding this file completely , and re-build it in my project but it also has other functions like gethchar,addchar and numtohchar and others which i'm not entirely sure how they work and i dont' won't to duplicate them

what i was thinking is maybe create a MACRO that in the event of AVR would use PSTR for those strings, and in the event of no AVR would be a no op MACRO
i'm not entirely sure how those things usually get resolved in C/C++.

library.json is a file tha platfrom io framework can work with to make any other project a platfromio library .
this is the current one i'm writing , the most imporatnt elemetn is buid element that allows you to specify various folder for include and source folder

the

{
  "$schema": "https://raw.githubusercontent.com/platformio/platformio-core/develop/platformio/assets/schema/library.json",
  "name": "Libzmanim",
  "version": "1.0-1",
  "description": "a C library for zmanim and hebrew dates",
  "repository": {
    "type": "git",
    "url": "git://github.com/yparitcher/libzmanim"
  },
  "build": {
    "includeDir": "."
    ,"flags": [
       "-I include"
      ,"-I windows"      
    ]
    ,"srcDir": "."
    ,"srcFilter": "+<*> +<src*> +<windows*> -<extra> -<test> -<ffi-cdecl>"
  },
  "authors": [
    {
      "name": "Yparitcher",
      "email": "support@paritcher.com",
      "url": "https://paritcher.com/"
    }
  ],
  "license": "MIT",
  "frameworks": "*",
  "platforms": "*"
}

stpncpy() seems to be a somewhat standardized function.
It's just not in avr-libc. You could copy code from elsewhere, say newlib/stpncpy.c at 2a63fa0fd26ffb6603f69d9e369e944fe449c246 · eblot/newlib · GitHub

i have the source for stpncpy, but the issue is that it's still doesn't get linked for some reason i still undefined reference to `stpncpy'

thanks for the explanation. i've often struggled with header files when porting code.

have these comments

  • _WIN32 is not likely defined by default in the compiler, it's defined in the Makefile (i.e. make -D_WIN32)

  • using stdint.h and specific var types (e.g. uint32_t) avoids any confusion about variable size and makes code more portable

  • i hope it's clear that a .h is not a library, that it simply provides declarations for symbols in some other file linked into the code. the name of the .h may also be used in the Arduiono IDE to locate the files (i.e. libraries). so using symbols in a .h also requires having the corresponding .cpp files

  • looks like stpncpy is just used once in the github file you referenced

and these questions

  • why are you using your own makefile and not using the Arduino IDE to build the files? (finding the location of all the libraries is tedious)

  • what is ccdOvK9f.ltrans0.ltrans? it must be one of the source files in your makefile

  • again, why used stpncpy() instead of strncpy()? maybe define stpncpy as strncpy in a local stpncpy.h

  • my understanding is Arduino "String" is more like the Java than C++ implementation. is this causing problems?

  • is memory becoming an issue that you need to use PSTR (i.e. F() macro)?

i'm not the author of said library and all is types are long int, the make file is not my own either.
Essentially I'm not using any make file but relying on platform.io's framework to build it.
by default it relies on a directory structure where you src folder for all the code and include folder for all the headers, so all you would have needed was just to plant a library.json file with library name and version in the root of that library.
which ALMOST what happens here, the only issue being the additional windows folder that contains the stpncpy files.
btw the stpncpy.c doesn't contain a reference to the header file which makes me wonder if the fact that they are in the same folder also causes problems.

yes, memory is becoming an issues like it can go up to 90% from memory,

once again, the .h provides declarations (telling the compiler what the argument and return type are). of course there's no need for the .h in the .cpp file containing the definitions of those symbols.

i usually include the .h in the .cpp of local source to make sure the declarations match the definitions which often change during development, but this isn't common practive

at least on most unix/linux/cygwin environments, the .h files are under /usr include and most libraries (.a files) are under /usr/lib. the .a files are precompiled for the machine (the PC) . .cpp files are considered libraries for the Arduino IDE because they need to be compiled for each processor (ATmege328p, esp32, ...)

Actually, I think it is a pretty common practice from what I've seen. And, a good one.

these are actually C files, that's why i understand you need to use extern "C" to include them in cpp files
i was just wondering what can be problem of it not finding specficially this file

presumably stpncpy.c? does it exist? where?

in the same project unde windows folder
but make file doesn't make use of it, there's a windows batch file which i believe makes a dll out of it.

i think i'm gonna give up here, and hack something ugly perhaps even give up completly on contributing changes to original library
i can now see that even if i have all the files directly inside the project as though they regular
source code i still get the crap stpncpy error.
the only thing the allows it compile is if i rename all the files from c to cpp
(and not do extern) i read somewhere this is bad practive and may cause other issues
but this looks like a mix of c and c++ issue .

it's almsot like some parts needs to be compiled with a compiler others with cpp compiler

images don't convey much info

again unsure of the environment you're working in -- can understand your frustration

  • see extern "C" which is added to C++ files

  • why is a batch file involved? is the makefile building a PC executable?

  • and again, why not build using the Arduino IDE

  • certainly .c and .cpp files need to be compiled differently. gcc usually handled either

i'm using platfrom io which is an extension of microsoft vscode instead of arduino IDE, it is considered superiour in many ways to arduino IDE , and so far i didn't have any issues with it, i elieve the same problems would arise with arduino IDE .
the makefile doesn't build a pc executable, it makes the library itself
the batch file is used to make the library into a dll
this project also has other bindings like lua and python bindings to library itself.

this is from the page's readme.md

Indeed.

Are you using GitHub - yparitcher/libzmanim: C library for zmanim & hebrew calendar ?

Try replacing the line:

			char* end = stpncpy(year, gethchar(charnum), len);

With

			char* end = year + strncpy(year, gethchar(charnum), len);