Converting the result from JSON GENERATE to EBCDIC - cobol

For one of my requirements I need the JSON GENERATE function in COBOL 6. My problem is, that it returns UTF-8, but I need the data in EBCDIC (CCSID 1140). Is there a way to convert this? Every solution I found uses national data types, but I have to use the NODBCS compiler option, so those don't work.

I do apologize for not first asking a question (but I am too new to StackOverflow to allow that.) The question would be "do you have C++ and can you link C++ with your COBOL?" I just tried this program:
#include <iconv.h>
class myConv
{
public:
static myConv globalConv;
size_t conv(char ** restrict f, unsigned int * restrict flen,
char ** restrict t, unsigned int * restrict tlen)
{
if (ok_)
{
return iconv(cd_, f, flen, t, tlen);
}
else
{
return (size_t)-1;
}
}
private:
myConv()
{
cd_ = iconv_open("1047", // EBCDID
"1208"); // UTF-8
ok_ = (cd_ != (iconv_t)-1);
// possibly indicate what the error is
}
~myConv()
{
if (ok_)
{
if (iconv_close(cd_) != 0)
{
// possibly indicate what the error is
}
}
}
bool ok_;
iconv_t cd_;
};
myConv myConv::globalConv;
extern "C" bool CNV(char * f, unsigned int flen,
char * t, unsigned int tlen)
{
return myConv::globalConv.conv(&f, &flen,
&t, &tlen) != (size_t)-1;
}
and the COBOL call looked like this:
json generate result from grp
call "CNV" using by reference result,
by value length of result,
by reference convertedres,
by value length of convertedres,
returning cres
and cres is a PIC S9(9) COMP data item which will have a non-zero value of the conversion succeeded.
Again, I apologize for not first asking if C++ is a possibility. (Or even C. The code could be easily done in C.) Also, the result is not quite perfect owing to the JSON GENERATE result being zero filled.

Related

Passing an object that undergoes default argument promotion to 'va_start'

This is my first Xcode app and objective-c so give me some slack :)
I tried googling on the issue but I cannot see any help regarding Xcode and app development. I added the error masseages after //
- (id)initWithBytes:(int8_t)byte1, ... { //Error: 1. Parameter of type 'int8_t' (aka 'signed char') is declared here
va_list args;
va_start(args, byte1); //Error: Passing an object that undergoes default argument promotion to 'va_start' has undefined behavior
unsigned int length = 0;
for (int8_t byte = byte1; byte != -1; byte = va_arg(args, int)) {
length++;
}
va_end(args);
if ((self = [self initWithLength:length]) && (length > 0)) {
va_list args;
va_start(args, byte1); // Error: Passing an object that undergoes default argument promotion to 'va_start' has undefined behavior
int i = 0;
for (int8_t byte = byte1; byte != -1; byte = va_arg(args, int)) {
_array[i++] = byte;
}
va_end(args);
}
return self;
}
Thank you in advance!!
va_start() saves the pointer to the first argument passed to the function into a va_list.
The arguments themselves are passed via a hardware stack.
The issue with int8_t comes from the way the hardware stack is implemented. (in x86 at least)
Just like the SSE and MMX does, the stack requires elements stored on it to have an alignment equal to a multiple of 16bits, so everything passed to the function WILL have at least 16 bits of size, regardless of its type.
But the problem is va_arg() doesn't know about all that. Historically, it was a macro, and all it does is returning a pointer stored in va_list, and incrementing va_list by sizeof(type).
So, when you retrieve the next argument, the pointer returned does not point to the next argument but one byte before it, or not - depending on whether the va_arg is a macro or a compiler built-in function.
And this is what a warning is about.
IMO at least. Pardon my English, It's my 2nd language.

Objective-C how to convert a keystroke to ASCII character code?

I need to find a way to convert an arbitrary character typed by a user into an ASCII representation to be sent to a network service. My current approach is to create a lookup dictionary and send the corresponding code. After creating this dictionary, I see that it is hard to maintain and determine if it is complete:
__asciiKeycodes[#"F1"] = #(112);
__asciiKeycodes[#"F2"] = #(113);
__asciiKeycodes[#"F3"] = #(114);
//...
__asciiKeycodes[#"a"] = #(97);
__asciiKeycodes[#"b"] = #(98);
__asciiKeycodes[#"c"] = #(99);
Is there a better way to get ASCII character code from an arbitrary key typed by a user (using standard 104 keyboard)?
Objective C has base C primitive data types. There is a little trick you can do. You want to set the keyStroke to a char, and then cast it as an int. The default conversion in c from a char to an int is that char's ascii value. Here's a quick example.
char character= 'a';
NSLog("a = %ld", (int)test);
console output = a = 97
To go the other way around, cast an int as a char;
int asciiValue= (int)97;
NSLog("97 = %c", (char)asciiValue);
console output = 97 = a
Alternatively, you can do a direct conversion within initialization of your int or char and store it in a variable.
char asciiToCharOf97 = (char)97; //Stores 'a' in asciiToCharOf97
int charToAsciiOfA = (int)'a'; //Stores 97 in charToAsciiOfA
This seems to work for most keyboard keys, not sure about function keys and return key.
NSString* input = #"abcdefghijklkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!##$%^&*()_+[]\{}|;':\"\\,./<>?~ ";
for(int i = 0; i<input.length; i ++)
{
NSLog(#"Found (at %i): %i",i , [input characterAtIndex:i]);
}
Use stringWithFormat call and pass the int values.

I get a Suspicious pointer conversion in function main. How to get rid of this?

I'm new here at stackoverflow. The title is my question. Can someone please help me on this. Thanks. I've been working on this for like 3 days.
This part of code encodes the file to a huffman code
void encode(const char *s, char *out)
{
while (*s) {
strcpy(out, code[*s]);
out += strlen(code[*s++]);
}
}
This part of code deciphers the file from a huffman code to a human readable code
void decode(const char *s, node t)
{
node n = t;
while (*s) {
if (*s++ == '0') n = n->left;
else n = n->right;
if (n->c) putchar(n->c), n = t;
}
putchar('\n');
if (t != n) printf("garbage input\n");
}
This part is where I get my error.
int main(void)
{
int i;
const char *str = "this is an example for huffman encoding", buf[1024];
init(str);
for (i=0;i<128;i++)
if (code[i]) printf("'%c': %s\n", i, code[i]);
encode(str, buf); /* I get the error here */
printf("encoded: %s\n", buf);
printf("decoded: ");
decode(buf, q[1]);
return 0;
}
Declare 'buf' in a different line, and not as 'const':
char buf[1024];
The const applies to all the declarations on the line, so you're declaring buf as a const char[1024]. That means that calling encode casts away the constness, resulting in the warning.
Avoid having multiple variable declarations on the same line, unless they are all exactly the same type.

segmentation fault when printing a list of values from the memory

I am trying to make a small application that prints the content of a number of consecutive memory locations. As an indication of where the program is in the memory, I am printing the memory location of the main function and of a dummy variable.
In a first column, I want to print the address. In a second column, I want the contents of this address and the content of the 9 addresses behind it. In a third column, I want to print the byte value as a char, if it is printable. If it is not printable, I want to print a dot. In the rows under the first, I do exactly the same.
At startup, a number of values to print can be entered. If a positive value is entered, the addresses will increment, if a negative value is entered, the addresses will decrement.
To quickly see where I want to get to, you could run the code and enter for example 20 bytes to dump and use the address of the dummy as a starting address.
So far, my code only works for positive values. When I enter a negative number, I get a segmentation fault, but I can't figure out why. I tried to find the error in Valgrind, without success.
Some help would be greatly appreciated!
Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define NUMBER_OF_BYTES 10
void showAddresses(void);
void printMemory(void);
void getDumpSize(void);
char* dummy; // dummy is een pointer naar een int
signed int dumpSize; // how many bytes have to be dumped?
signed int upDown; // do I need to go up or down?
int main(void)
{
dummy = (char *) malloc (sizeof(unsigned char));// memory allocation
showAddresses(); // prints the main function address and a variable address
getDumpSize(); //
printMemory(); //
free(dummy); // free memory
return 0; // end the main function
}
void showAddresses(void)
{
printf("Main function address is %p \n", main);
printf("Dummy variable address is %p \n",(void*)dummy);
}
void getDumpSize(void)
{
printf("Enter number of bytes to dump <negative or positive>:");
scanf("%d",&dumpSize);
if(dumpSize<0)
{
upDown = -1; // count down
printf("upDown was set to -1\n");
}
else
{
upDown = 1; // count up
printf("upDown was set to +1\n");
}
}
void printMemory(void)
{
int input;
printf("Enter the address:");
scanf("%x", &input); // enter the input
printf("Address \tBytes \t\t\t\tChars \n"); // print the table header
printf("--------- \t----------------------------- \t---------- ");
int i;
unsigned char* address; //
for(i=0;i<abs(dumpSize);i++)
{
address = (unsigned char*) (input+(i*upDown)); // make the address to print
if( (i%NUMBER_OF_BYTES) == 0) // show the address every 'i*NUMBER_OF_BYTES' times
{
printf("\n%p \t", (void*) address);
}
printf("%02x ", *address); // print as a 2 number hex and use zero padding if needed
if( (i%NUMBER_OF_BYTES) == (NUMBER_OF_BYTES-1) )// print the char list for every value (if printable)
{
printf("\t");
int j;
for(j=(NUMBER_OF_BYTES-1);j>=0;j--)
{
address = (unsigned char*) (input+(i*upDown)-j);
if(isprint(*address)==0)// print a dot if the byte value is not printable
{
printf(".");
}
else
{
printf("%c",*address); // print the byte value as a char, if printable
}
}
}
}
}
Your segmentation fault is likely coming from attempting to access memory outside of your program's scope. The address in "dummy" is the first malloc from your program, so it represents (possibly) the first "area" of memory available to your program. Going up from there might be keeping you in program space (hence the lack of seg fault), but going backward might be driving you into a restricted memory area. Out of curiosity: what is the memory address returned for your "dummy" malloc? Is the number even large enough to go backward without going negative? (I'm wondering if your program sees the true system memory map or a paged map that is already sand-boxed for programs.)

C Programming: Linked Lists

I'm writing a program using linked list (such a nightmare).
Anyway, the purpose of the program is to enter 8 characters and have the program print the characters back out to you and also print the characters back out in reverse order, using linked lists of course.
I got this so far. There's a lot wrong with it (i think).
Problems are
When asking for characters from the user it should read in the amount of characters automatically without having to ask for how many characters
Also, when it it compiles it prints gibberish to the screen, for example I just ran it and it printed
¿r
(àõ($ê¿¿
a¿r
(àõ($ê¿¿
¿r
(àõ($ê¿¿
b¿r
(àõ($ê¿¿
Lots of help needed here. It would be so much appreciated!
Code of course
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define strsize 30
typedef struct member
{
int number;
char fname[strsize];
struct member *next;
}
RECORD;
RECORD* insert (RECORD *it);
RECORD* print(RECORD *it, int j);
int main (void)
{
int i, result;
RECORD *head, *p;
head=NULL;
printf("Enter the number of characters: ");
scanf("%d", &result);
for (i=1; i<=result; i++)
head=insert (head);
print (head, result);
return 0;
}
RECORD* insert (RECORD *it)
{
RECORD *cur, *q;
int num;
char junk;
char first[strsize];
printf("Enter a character:");
scanf("%c", &first);
cur=(RECORD *) malloc(sizeof(RECORD));
strcpy(cur->fname, first);
cur->next=NULL;
if (it==NULL)
it=cur;
else
{
q=it;
while (q->next!=NULL)
q=q->next;
q->next=cur;
}
return (it);
}
RECORD* print(RECORD *it, int j)
{
RECORD *cur;
cur=it;
int i;
for(i=1;i<=j;i++)
{
printf("%s \n", cur->fname);
cur=cur->next;
}
return;
}
You have:
in insert:
char first[strsize];
scanf("%c", &first); /* note the %c */
strcpy(cur->fname, first);
in print
printf("%s \n", cur->fname);
You should have %s instead of %c and therefore change &format to format in the argument list, as format itself represents the address of the location the string is to be stored.
So the scanf call should be like below
scanf("%s", first);
Another thing. If you have specified a return type in the print function then you should return something, or make it return nothing (declare return type as void). This will not pose any problem in this case although.
Read the warning messages which the compiler throws to you and you would see the compiler actually had answered your questions.
You need to do some redesigns i think. For example to traverse the linked list you do not need to counter 'j'. you can detect the list termination by inspecting if the next link is NULL or not.
Your question was to print the characters or strings in reverse, so you need to write some other print function than what you have wrote.

Resources