File input not working - file-io

I have this C++ program that will get key code and store it as a string in a text file. After I run the program the file is supposed to appear alongside my cpp file but I doesn't appear. I think is got to do with the Save function where the file input and output is happening. Does anyone notices any errors(I get none while compiling).
#include <iostream>
#include <Windows.h>
#include <Winuser.h>
#include <fstream>
using namespace std;
int Save (int Key_Stroke, char *file);
int main(){
char i;
while(1){
for(i = 8; i <= 190; i++){
if(GetAsyncKeyState(i) == -32767){
Save(i, "LOG.TXT");
}
}
}
system("PAUSE");
return 0;
}
int Save (int Key_Stroke, char *file){
if((Key_Stroke == 1) || (Key_Stroke == 2) || (Key_Stroke == 5))
return 0;
FILE *OUTPUT_FILE;
OUTPUT_FILE = fopen(file, "a+");
fprintf(OUTPUT_FILE, "%s", &Key_Stroke);
fclose(OUTPUT_FILE);
cout << Key_Stroke << endl;
return 0;
}

When using C fprintf (this isn't typically used in C++, see ofstream) you don't use reference operator & because you are passing value to function, not address. Also formatting string is wrong, you want to write int %d, not array of chars %s (more here)
Your Save function should look like
int Save(int Key_Stroke, const char *file)
{
if((Key_Stroke == 1) || (Key_Stroke == 2) || (Key_Stroke == 5))
return 0;
FILE *OUTPUT_FILE = fopen(file, "a+");
if(OUTPUT_FILE != NULL)
{
fprintf(OUTPUT_FILE, "%d", Key_Stroke);
fclose(OUTPUT_FILE);
}
cout << Key_Stroke << endl;
return 0;
}
Also notice const keyword in second argument of the function. This should be used to avoid writing to constant area of memory - directly written array of chars "LOG.TXT" .
Next thing, you should always check if the file you are trying to write to is correctly opened if(OUTPUT_FILE != NULL) .

Related

why scip making an extra branching decision after calling SCIPincludeBranchRrule?

Now I want to do something on the branch and bound using SCIP, and begin from the branching rule. While I tracking the branching process I found something I cannot understand. Begining from getting the branching variable candidates using SCIPgetLPBranchCands, I get the SCIP_VAR** lpcands, then I select the first variable to branch using SCIPbranchVar. This branching rule works on each focused node.
Consider the branch decision at the number 1 node (the root node), after executing SCIPbranchVar function, SCIPgetChildren return two child nodes (2 and 3), but the child node number of root node changed, two or more child node appeared. Suppose node selector selected the node of number 2 to branch, SCIPgetSiblings return 3 siblings (3, 4, and 5).
To make it clear that what happened, I print the branching decision path using SCIPprintNodeRootPath, and print the relationship between nodes. The result shows that after I branching at a node on the selected variable, the SCIIP branching at the same node on another variable which I don't know.
I have print these information generated by scipoptsuite-7.0.1/scip/examples/Binpacking, no more branching decision is made. But more child nodes appearing after I replace the ryanfoster rule using the branching on the first variable. After that, I try the create child node branching style for my procedure, extra nodes appeared anyway.
I cannot find out what happened and how to totally control the branching process, it is very important for my work in the future for it determined how to design the branching rule. I have even try to read the source code of SCIP, unfortunately, it's too hard for me to read.
My procedure as follows:
main.cpp
/* standard library includes */
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
/* scip includes */
#include "objscip/objscip.h"
#include "objscip/objscipdefplugins.h"
/*user file includes*/
#include "branch_rule.h"
/* namespace usage */
using namespace std;
using namespace scip;
static
SCIP_RETCODE execmain()
{
SCIP* scip = NULL;
/* initialize SCIP environment */
SCIP_CALL( SCIPcreate(&scip) );
SCIP_CALL( SCIPincludeBranchRrule(scip) );
/* include default plugins */
SCIP_CALL( SCIPincludeDefaultPlugins(scip) );
SCIP_CALL( SCIPsetIntParam(scip,"presolving/maxrestarts",0) );
SCIP_CALL( SCIPsetSeparating(scip, SCIP_PARAMSETTING_OFF, TRUE) );
SCIP_CALL(SCIPreadProb(scip, "map18.mps.gz", NULL));
SCIP_CALL( SCIPsolve(scip) );
return SCIP_OKAY;
}
int main(int argc, char** argv)
{
return execmain() != SCIP_OKAY ? 1 : 0;
}
branch_rule.h
#ifndef VRP_BRANCH_RULE_H
#define VRP_BRANCH_RULE_H
#include "scip/scip.h"
#include <vector>
SCIP_RETCODE SCIPincludeBranchRrule(
SCIP* scip
);
#endif //VRP_BRANCH_RULE_H
branch_rule.cpp
#include "branch_rule.h"
#include <assert.h>
#include <string.h>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <fstream>
#include "scip/struct_tree.h"
#include "scip/type_var.h"
using namespace std;
/**#name Branching rule properties
*
* #{
*/
#define BRANCHRULE_NAME "branch rule test"
#define BRANCHRULE_DESC "branch rule test"
#define BRANCHRULE_PRIORITY 50000
#define BRANCHRULE_MAXDEPTH -1
#define BRANCHRULE_MAXBOUNDDIST 1.0
void printBranchTreeNode(SCIP_NODE *node, SCIP_NODE **siblings, int nsiblings){
ofstream f1("branch_path/node_information.txt", ios::app);
if(!f1)return;
f1 << "node number:" << node->number << ", sibling number: " << nsiblings;
if(NULL==node->parent)
f1 << std::endl;
else{
f1 << ", parent number: " << node->parent->number << std::endl;
}
f1 << setw(20) << "siblings:" << std::endl;
for(int i = 0; i < nsiblings; ++i){
f1 << setw(20) << "node number:" << siblings[i]->number << ", sibling number: " << nsiblings << ", parent number: " << siblings[i]->parent->number << endl;
}
f1.close();
}
static
SCIP_DECL_BRANCHEXECLP(branchExeclpTest)
{
assert(scip != NULL);
assert(branchrule != NULL);
assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0);
assert(result != NULL);
SCIP_NODE *current_node = SCIPgetCurrentNode(scip) ;
SCIP_NODE **leaves = NULL;
int nleaves;
SCIP_CALL( SCIPgetLeaves (scip, &leaves, &nleaves) );
std::vector<SCIP_NODE*> leaves_vector;
for(int i =0; i < nleaves; ++i){
leaves_vector.push_back(leaves[i]);
}
SCIP_NODE **current_node_slibings = NULL;
int ncurrent_node_slibings;
SCIP_CALL( SCIPgetSiblings(scip, &current_node_slibings, &ncurrent_node_slibings) );
std::vector<SCIP_NODE*> slibings_vector;
for(int i =0; i < ncurrent_node_slibings; ++i){
slibings_vector.push_back(current_node_slibings[i]);
}
printBranchTreeNode(current_node, current_node_slibings, ncurrent_node_slibings);
SCIP_NODE **childrens;
int nchildrens;
SCIP_CALL( SCIPgetChildren(scip, &childrens, &nchildrens) );
std::vector<SCIP_NODE*> childrens_vector;
for(int i =0; i < nchildrens; ++i){
childrens_vector.push_back(childrens[i]);
}
stringstream filename;
filename.str("");
filename << "branch_path/branch_path_to_node_" << current_node->number <<".dat";
std::string stringFileName = filename.str();
FILE *fp = fopen(stringFileName.c_str(), "wt+");
SCIP_CALL( SCIPprintNodeRootPath(scip, current_node, fp) );
fclose(fp);
// create child node branching style
SCIP_NODE *childsame;
SCIP_NODE *childdiffer;
SCIP_CALL( SCIPcreateChild(scip, &childsame, 0.0, SCIPgetLocalTransEstimate(scip)) );
SCIP_CALL( SCIPcreateChild(scip, &childdiffer, 0.0, SCIPgetLocalTransEstimate(scip)) );
/*
// SCIPbranchVar branching style
SCIP_VAR** lpcands;
SCIP_Real* lpcandssol;
SCIP_Real* lpcandsfrac;
int nlpcands;
int npriolpcands;
int nfracimplvars;
SCIP_CALL( SCIPgetLPBranchCands(scip, &lpcands, &lpcandssol, &lpcandsfrac, &nlpcands, &npriolpcands, &nfracimplvars) );
SCIP_NODE* downchild;
SCIP_NODE* eqchild;
SCIP_NODE* upchild;
SCIP_CALL( SCIPbranchVar(scip, lpcands[0], &downchild, &eqchild, &upchild) );
// SCIP_CALL( SCIPbranchVar(scip, var, NULL, NULL, NULL) );
SCIP_CALL( SCIPgetLeaves (scip, &leaves, &nleaves) );
int numLeaves = SCIPgetNLeaves(scip);
SCIP_CALL( SCIPgetSiblings(scip, &current_node_slibings, &ncurrent_node_slibings) );
slibings_vector.clear();
for(int i =0; i < ncurrent_node_slibings; ++i){
slibings_vector.push_back(current_node_slibings[i]);
}
SCIP_CALL( SCIPgetChildren(scip, &childrens, &nchildrens) );
childrens_vector.clear();
for(int i =0; i < nchildrens; ++i){
childrens_vector.push_back(childrens[i]);
}
*/
return SCIP_OKAY;
}
SCIP_RETCODE SCIPincludeBranchRrule(
SCIP* scip /**< SCIP data structure */
){
SCIP_BRANCHRULEDATA* branchruledata;
SCIP_BRANCHRULE* branchrule;
branchruledata = NULL;
branchrule = NULL;
// include branching rule
SCIP_CALL( SCIPincludeBranchruleBasic(scip, &branchrule, BRANCHRULE_NAME, BRANCHRULE_DESC, BRANCHRULE_PRIORITY, BRANCHRULE_MAXDEPTH,
BRANCHRULE_MAXBOUNDDIST, branchruledata) );
assert(branchrule != NULL);
SCIP_CALL( SCIPsetBranchruleExecLp(scip, branchrule, branchExeclpTest) );
return SCIP_OKAY;
}
Does anyone can help me to solve this problem?
so the first thing I notice when looking at your code is that you do not set the result pointer. After branching, you need to set *result = SCIP_BRANCHED;.
Can you please try that and check if it fixes your problem?

How to skip a line from an infile

I have this code that allows the user to load an input file (option 1), display the contents of the input file (option2) and they have the option to exit (option 3). Is there any way that I can skip the first line of the input file from being couted?
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
using namespace std;
int main ()
{ char selection = ' ';
char fileName[25];
ifstream file;
string line;
cout<< "Choose an action"<<endl;
string myMenu[3]={" 1 - Load An Exam ", " 2 - Display Exam ", " 3 - Quit " };
for (int i=0; i<3; i++)
{ cout<<myMenu[i]<<endl;}
cin>>selection;
switch(selection)
{
case '1':
cout<<"Please enter the file name"<<endl;
cin>>fileName,25;
file.open(fileName);
if (file.fail())
{cout<<"Unable to open file"<<endl;
cout<<"Please enter the file name"<<endl;
cin>>fileName,25;
file.open(fileName); }
break;
case '2':
if (file.good())
{
while (getline(file, line))
{cout<<line<<"\n";}
file.close();
}
else cout<<"Unable to open file";
break;
case '3':
cout<<"Thank you!"<<endl;
break;
}
Just continue inside the while loop. This will re-trigger the getLine function, which will move the pointer forward 1 line.
while (getline(file, line))
{
if ( skipLineCondition ) { continue; }
cout<<line<<"\n";
}
Also, please try to post better formatted code. We are here to help, but you should focus more effort into making it easy for everyone to help you.

CGAL-4.8.1 Arrangements - Bezier Curves Save Arrangement to File Error

I am new to CGAL.
I tried to modify Examples/Arrangement_on_surfaces_2 Bezier_curves.cpp to save arrangement to file as shown below:
//! \file examples/Arrangement_on_surface_2/Bezier_curves.cpp
// Constructing an arrangement of Bezier curves.
#include <fstream>
#include <CGAL/basic.h>
#ifndef CGAL_USE_CORE
#include <iostream>
int main ()
{
std::cout << "Sorry, this example needs CORE ..." << std::endl;
return 0;
}
#else
#include <CGAL/Cartesian.h>
#include <CGAL/CORE_algebraic_number_traits.h>
#include <CGAL/Arr_Bezier_curve_traits_2.h>
#include <CGAL/Arrangement_2.h>
#include <CGAL/IO/Arr_iostream.h>
#include "arr_inexact_construction_segments.h"
#include "arr_print.h"
typedef CGAL::CORE_algebraic_number_traits Nt_traits;
typedef Nt_traits::Rational NT;
typedef Nt_traits::Rational Rational;
typedef Nt_traits::Algebraic Algebraic;
typedef CGAL::Cartesian<Rational> Rat_kernel;
typedef CGAL::Cartesian<Algebraic> Alg_kernel;
typedef Rat_kernel::Point_2 Rat_point_2;
typedef CGAL::Arr_Bezier_curve_traits_2<Rat_kernel, Alg_kernel, Nt_traits>
Traits_2;
typedef Traits_2::Curve_2 Bezier_curve_2;
typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
//typedef CGAL::Arrangement_2<Traits_2> Arrangement;
int main (int argc, char *argv[])
{
// Get the name of the input file from the command line, or use the default
// Bezier.dat file if no command-line parameters are given.
const char *filename = (argc > 1) ? argv[1] : "Bezier.dat";
const char *outfilename = (argc > 1) ? argv[1] : "BezierOut.dat";
// Open the input file.
std::ifstream in_file (filename);
if (! in_file.is_open()) {
std::cerr << "Failed to open " << filename << std::endl;
return 1;
}
// Read the curves from the input file.
unsigned int n_curves;
std::list<Bezier_curve_2> curves;
Bezier_curve_2 B;
unsigned int k;
in_file >> n_curves;
for (k = 0; k < n_curves; k++) {
// Read the current curve (specified by its control points).
in_file >> B;
curves.push_back (B);
std::cout << "B = {" << B << "}" << std::endl;
}
in_file.close();
// Construct the arrangement.
Arrangement_2 arr;
insert (arr, curves.begin(), curves.end());
// Print the arrangement size.
std::ofstream out_file;
out_file.open(outfilename);
out_file << "The arrangement size:" << std::endl
<< " V = " << arr.number_of_vertices()
<< ", E = " << arr.number_of_edges()
<< ", F = " << arr.number_of_faces() << std::endl;
out_file << arr;
out_file.close();
return 0;
}
#endif
If I comment out the line out_file << arr; it works fine. Otherwise it generates a C2678 error in read_x_monotone_curve in Arr_text_formtter.h
I am using Visual Studio 15 x86.
Thank you for any help.
I solve this by modifying the print_arrangement(arr) routine in arr_print.h to save_arrangement(arr) with a std::ofstream in place of std::cout.
It appears that the << operator does not work.
If someone else has a better solution I am open to it.
Points of intersections in an arrangement of Bezier curves cannot be represented in an exact manner. Therefore, such an arrangement cannot be saved using the default export (<<) operator and the standard format.
The easiest solution is to store the curves, but this means that the arrangement must be recomputed each time the curves are read. Perhaps other solution could be devised, but they are not implemented.

Storing int values in an uint8_t array in code composer studio vs 5.4

I have a string in a uint8_t str[] array and I am trying to store the positions of characters within the str in another variable called uint8_t pos[]. The code is written in Code Composer Studio vs 5.4
I tried using sprintf(), type casting as well as changing the type of uint8_t pos[] to int pos[] as well as unsigned int pos[]. None of these work.
The code breaks at the sprintf statement and comes to a halt by reaching an undefined memory location. When I run in assembly after reaching sprintf statement, it gives an error saying that a source code for sprint.c cannot be found in location.
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "tm4c123gh6pm.h"
#include <stdio.h>
void initHw()
{
.
.
}
int main(void)
{
// Initialize hardware
initHw();
char strRx[80];
int count =0;
int count_enter=0;
uint8_t posStr[80];
uint8_t typeStr[80];
int pos=0;
int len;
unsigned int j=0, argCount=0;
while(1)
{
if(count == 0)
{
putsUart0("Enter characters for the string\r\n");
}
if(count <= 80)
{
char c = getcUart0();
if(c=='\b')
if(count>0)
count--;
else
break;
if(c>=' ')
{
strRx[count]=c;
count++;
}
if(count==80 || c==13)//'\r')
{
count_enter++;
if(count_enter==1) //count==80 before carriage return
{
len = count;
strRx[count]='\0';
while(count!=80)
strRx[count++]='\0';
count_enter=0;
putsUart0("\r\nEntered string is:\r\n");
putsUart0(strRx);
putsUart0("\r\n");
}
j=0;
//char a[10];
for(pos=0; pos!=len; pos++)// strRx[pos]!='\0'; pos++)
{
char a[80];
if((strRx[pos]>='A' && strRx[pos]<='Z') || (strRx[pos]>='a' && strRx[pos]<='z'))
{
typeStr[j]='a';
//posStr[j]=pos;
a[j]=pos;
sprintf(a,"%u",pos); //source not found
//a[j]=pos;
//posStr[j]=sprintf("%c",a);
//posStr[j]=(uint8_t)a;//a;
while(strRx[pos]!='\0'&&((strRx[pos]>='A' && strRx[pos]<='Z') || (strRx[pos]>='a' && strRx[pos]<='z')))
{
pos++;
}
pos--;
j++;
}
else if(strRx[pos]>='0' && strRx[pos]<='9')
{
typeStr[j]='n';
a[j]=pos;
sprintf(a,"%u",pos);
//posStr[j]=pos;//a;
while(strRx[pos]!='\0'&&((strRx[pos]>='0' && strRx[pos]<='9')))
{
pos++;
}
pos--;
j++;
}
else
{
while(strRx[pos]!='\0'&&((strRx[pos]<'A' && strRx[pos]>'Z') && (strRx[pos]<'a' && strRx[pos]>'z') && (strRx[pos+1]<'0' && strRx[pos+1]>'9')))
pos++;
}
}
argCount=j;
while(j!=80)
{
typeStr[j++]='\0';
posStr[j++]='\0';
}
count = 0;
}//if(count==80 || c==13)//'\r')
}//if count<=80
}//while(1)
}//main
The "unable to locate sprintf.c" error probably just means that the debugger cannot locate the source file, which means it cannot show the source code in the debugger window. It's possible that you don't have the source code for sprintf.c and all you have is the precompiled library. Or maybe you do have the source code and the debugger is simply looking in the wrong path. If you have the source code then there may be a way to tell the debugger which path to find it.
But that is just a debugger display issue -- It is not what is causing your program to crash. The problem may be in your code but you'd have to share your code for us to identify that. Or the problem may be a couple other issues that can occur with the printf related routines.
1) printf routines can use a relatively large amount of stack space. So check for a stack overflow and increase the stack size if necessary.
2) Some embedded libraries provide multiple implementations of the printf routines such as "small", "no-float", and "full". The limited implementations use less code space but don't support all of the format specifiers. So make sure the implementation of sprintf that you've linked with supports all the format specifiers that you're actually using. Look through the project settings under linker or libraries for an option to select which version of printf is used.

What does PKCS5_PBKDF2_HMAC_SHA1 return value mean?

I'm attempting to use OpenSSL's PKCS5_PBKDF2_HMAC_SHA1 method. I gather that it returns 0 if it succeeds, and some other value otherwise. My question is, what does a non-zero return value mean? Memory error? Usage error? How should my program handle it (retry, quit?)?
Edit: A corollary question is, is there any way to figure this out besides reverse-engineering the method itself?
is there any way to figure this out besides reverse-engineering the method itself?
PKCS5_PBKDF2_HMAC_SHA1 looks like one of those undocumented functions because I can't find it in the OpenSSL docs. OpenSSL has a lot of them, so you should be prepared to study the sources if you are going to use the library.
I gather that it returns 0 if it succeeds, and some other value otherwise.
Actually, its reversed. Here's how I know...
$ grep -R PKCS5_PBKDF2_HMAC_SHA1 *
crypto/evp/evp.h:int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
crypto/evp/p5_crpt2.c:int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
...
So, you find the function's implementation in crypto/evp/p5_crpt2.c:
int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
const unsigned char *salt, int saltlen, int iter,
int keylen, unsigned char *out)
{
return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter,
EVP_sha1(), keylen, out);
}
Following PKCS5_PBKDF2_HMAC:
$ grep -R PKCS5_PBKDF2_HMAC *
...
crypto/evp/evp.h:int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
crypto/evp/p5_crpt2.c:int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
...
And again, from crypto/evp/p5_crpt2.c:
int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
const unsigned char *salt, int saltlen, int iter,
const EVP_MD *digest,
int keylen, unsigned char *out)
{
unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
int cplen, j, k, tkeylen, mdlen;
unsigned long i = 1;
HMAC_CTX hctx_tpl, hctx;
mdlen = EVP_MD_size(digest);
if (mdlen < 0)
return 0;
HMAC_CTX_init(&hctx_tpl);
p = out;
tkeylen = keylen;
if(!pass)
passlen = 0;
else if(passlen == -1)
passlen = strlen(pass);
if (!HMAC_Init_ex(&hctx_tpl, pass, passlen, digest, NULL))
{
HMAC_CTX_cleanup(&hctx_tpl);
return 0;
}
while(tkeylen)
{
if(tkeylen > mdlen)
cplen = mdlen;
else
cplen = tkeylen;
/* We are unlikely to ever use more than 256 blocks (5120 bits!)
* but just in case...
*/
itmp[0] = (unsigned char)((i >> 24) & 0xff);
itmp[1] = (unsigned char)((i >> 16) & 0xff);
itmp[2] = (unsigned char)((i >> 8) & 0xff);
itmp[3] = (unsigned char)(i & 0xff);
if (!HMAC_CTX_copy(&hctx, &hctx_tpl))
{
HMAC_CTX_cleanup(&hctx_tpl);
return 0;
}
if (!HMAC_Update(&hctx, salt, saltlen)
|| !HMAC_Update(&hctx, itmp, 4)
|| !HMAC_Final(&hctx, digtmp, NULL))
{
HMAC_CTX_cleanup(&hctx_tpl);
HMAC_CTX_cleanup(&hctx);
return 0;
}
HMAC_CTX_cleanup(&hctx);
memcpy(p, digtmp, cplen);
for(j = 1; j < iter; j++)
{
if (!HMAC_CTX_copy(&hctx, &hctx_tpl))
{
HMAC_CTX_cleanup(&hctx_tpl);
return 0;
}
if (!HMAC_Update(&hctx, digtmp, mdlen)
|| !HMAC_Final(&hctx, digtmp, NULL))
{
HMAC_CTX_cleanup(&hctx_tpl);
HMAC_CTX_cleanup(&hctx);
return 0;
}
HMAC_CTX_cleanup(&hctx);
for(k = 0; k < cplen; k++)
p[k] ^= digtmp[k];
}
tkeylen-= cplen;
i++;
p+= cplen;
}
HMAC_CTX_cleanup(&hctx_tpl);
return 1;
}
So it looks like 0 on failure, and 1 on success. You should not see other values. And if you get a 0, then all the OUT parameters are junk.
Memory error? Usage error?
Well, sometimes you can call ERR_get_error. If you call it and it makes sense, then the error code is good. If the error code makes no sense, then its probably not good.
Sadly, that's the way I handle it because the library is not consistent with setting error codes. For example, here's the library code to load the RDRAND engine.
Notice the code clears the error code on failure if its a 3rd generation Ivy Bridge (that's the capability being tested), and does not clear or set an error otherwise!!!
void ENGINE_load_rdrand (void)
{
extern unsigned int OPENSSL_ia32cap_P[];
if (OPENSSL_ia32cap_P[1] & (1<<(62-32)))
{
ENGINE *toadd = ENGINE_rdrand();
if(!toadd) return;
ENGINE_add(toadd);
ENGINE_free(toadd);
ERR_clear_error();
}
}
How should my program handle it (retry, quit?)?
It looks like a hard failure.
Finally, that's exactly how I navigate the sources in this situation. If you don't like grep you can try ctags or another source code browser.