How does this retarget.c work - c

Can someone explain to me how this retarget.c works?
I am trying to send integers to and from the uart of a microcontroller, i have been successful with using fgets to get a char (16 bits) and returning an integer using the atoi function in the Uart Interupt service routine but I am trying to get an integer using scanf, i am thinking i need to change the retarget file outlined below?
#include <stdio.h>
#include <time.h>
#include <rt_misc.h>
#define AHB_LED_BASE 0x50000000
#define AHB_UART_BASE 0x51000000
#pragma import(__use_no_semihosting)
struct __FILE {
unsigned char * ptr;
};
FILE __stdout = {(unsigned char *) AHB_UART_BASE};
FILE __stdin = {(unsigned char *) AHB_UART_BASE};
int fputc(int ch, FILE *f)
{
return(uart_out(ch));
}
int fgetc(FILE *f)
{
return(uart_in());
}
int ferror(FILE *f)
{
return 0;
}
int uart_out(int ch)
{
int* UARTPtr;
UARTPtr = (int*)AHB_UART_BASE;
*UARTPtr = (int)ch;
return(ch);
}
int uart_in()
{
int ch;
int* UARTPtr;
UARTPtr = (int*)AHB_UART_BASE;
ch = *UARTPtr;
uart_out(ch);
return((int)ch);
}
void _ttywrch(int ch)
{
fputc(ch,&__stdout);
}
void _sys_exit(void) {
while(1);
}
//------------------------------------------------------------------------------
// Cortex-M0
//------------------------------------------------------------------------------
#include <stdio.h>
#include <time.h>
#include <rt_misc.h>
#include <stdlib.h>
#define AHB_LED_BASE 0x50000000
#define AHB_UART_BASE 0x51000000
void UART_ISR(void)
{
int sample;
printf("the value entered is %d\n", sample);
}
//////////////////////////////////////////////////////////////////
// Main Function
//////////////////////////////////////////////////////////////////
int main() {
{
int sample;
scanf ("%d",&sample);
}
}

The scanf function will need ungetc because it must scan ahead in the buffer to see when fields end. E.g., when looking for a number, it needs to pull one character after the number to see where the number ends. When it sees the non-number character, it needs to put it back into the stream so the next call to getc will get it.
Something like this:
struct __FILE
{
unsigned char * ptr;
int unchar; /* place to keep the character put back in the stream */
};
FILE __stdout = {(unsigned char *) AHB_UART_BASE, -1};
FILE __stdin = {(unsigned char *) AHB_UART_BASE, -1};
int fgetc(FILE *f)
{
int c;
if (f->unchar == -1)
{
c = uart_in(); /* just read a character */
}
else
{
c = f->unchar; /* reuse the character put back by ungetc */
f->unchar = -1; /* mark it as used */
}
return c;
}
int fungetc(int c, FILE *f)
{
unsigned char uc = c; /* POSIX says that it is converted first to unsigned char */
f->unchar = (int )uc; /* put back the character */
return (int )uc;
}

Related

gcc: conflicting types for 'malloc'; have 'char *()' - trying to build an ancient version of ls

I'm trying to build an ancient version of the ls command (written in pre-ANSI/ISO C). But I'm getting a lot of warnings, which for most of these I can fix, however I also get a few errors. This is one of them: error: conflicting types for ‘malloc’; have ‘char *()’
This is the affected part of the program:
static char sccsid[] = "#(#)ls.c 1.21";
/*
* list file or directory;
* define DOTSUP to suppress listing of files beginning with dot
*/
#include <sys/param.h>
#include <sys/types.h>
#include <sys/sysmacros.h>
#include <sys/stat.h>
#include <sys/dir.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef STANDALONE
#define TERMINFO
#endif
/* -DNOTERMINFO can be defined on the cc command line to prevent
* the use of terminfo. This should be done on systems not having
* the terminfo feature (pre 6.0 sytems ?).
* As a result, columnar listings assume 80 columns for output,
* unless told otherwise via the COLUMNS environment variable.
*/
#ifdef NOTERMINFO
#undef TERMINFO
#endif
#ifdef TERMINFO
#include <curses.h>
#include <term.h>
#endif
#define DOTSUP 1
#define ISARG 0100000 /* this bit equals 1 in lflags of structure lbuf
* if *namep is to be used;
*/
#define DIRECT 10 /* Number of direct blocks */
#ifdef u370
/* Number of pointers in an indirect block */
#define INDIR (BSIZE/sizeof(daddr_t))
/* Number of right shifts to divide by INDIR */
#define INSHFT 10
#else
/* Number of pointers in an indirect block */
#define INDIR 128
/* Number of right shifts to divide by INDIR */
#define INSHFT 7
#endif
struct lbuf {
union {
char lname[DIRSIZ]; /* used for filename in a directory */
char *namep; /* for name in ls-command; */
} ln;
char ltype; /* filetype */
unsigned short lnum; /* inode number of file */
short lflags; /* 0777 bits used as r,w,x permissions */
short lnl; /* number of links to file */
unsigned short luid;
unsigned short lgid;
long lsize; /* filesize or major/minor dev numbers */
long lmtime;
};
struct dchain {
char *dc_name; /* path name */
struct dchain *dc_next; /* next directory in the chain */
};
struct dchain *dfirst; /* start of the dir chain */
struct dchain *cdfirst; /* start of the durrent dir chain */
struct dchain *dtemp; /* temporary - used for linking */
char *curdir; /* the current directory */
int nfiles = 0; /* number of flist entries in current use */
int nargs = 0; /* number of flist entries used for arguments */
int maxfils = 0; /* number of flist/lbuf entries allocated */
int maxn = 0; /* number of flist entries with lbufs assigned */
int quantn = 1024; /* allocation growth quantum */
struct lbuf *nxtlbf; /* pointer to next lbuf to be assigned */
struct lbuf **flist; /* pointer to list of lbuf pointers */
struct lbuf *gstat();
FILE *pwdfu, *pwdfg, *dirf;
int aflg, bflg, cflg, dflg, fflg, gflg, iflg, lflg, mflg;
int nflg, oflg, pflg, qflg, sflg, tflg, uflg, xflg;
int Cflg, Fflg, Rflg;
int rflg = 1; /* initialized to 1 for special use in compar() */
int flags;
int err = 0; /* Contains return code */
char *dmark; /* Used if -p option active. Contains "/" or NULL. */
unsigned lastuid = -1, lastgid = -1;
int statreq; /* is > 0 if any of sflg, (n)lflg, tflg are on */
char *dotp = ".";
char *makename();
char tbufu[16], tbufg[16]; /* assumed 15 = max. length of user/group name */
char *ctime();
long nblock();
long tblocks; /* total number of blocks of files in a directory */
long year, now;
int num_cols = 80;
int colwidth;
int filewidth;
int fixedwidth;
int curcol;
int compar();
int new_line()
{
if (curcol) {
putc('\n',stdout);
curcol = 0;
}
}
int pprintf(char *s1, char *s2)
{
register char *s;
register int c;
register int cc;
int i;
for (s = s1, i = 0; i < 2; i++, s = s2)
while(c = *s++) {
if (c < ' ' || c >= 0177) {
if (qflg)
c = '?';
else if (bflg) {
curcol += 3;
putc ('\\', stdout);
cc = '0' + (c>>6 & 07);
putc (cc, stdout);
cc = '0' + (c>>3 & 07);
putc (cc, stdout);
c = '0' + (c & 07);
}
}
curcol++;
putc(c, stdout);
}
}
/*
* pdirectory: print the directory name, labelling it if title is
* nonzero, using lp as the place to start reading in the dir.
*/
int pdirectory (char *name, int title, int lp)
{
register struct dchain *dp;
register struct lbuf *ap;
register char *pname;
register int j;
filewidth = 0;
curdir = name;
if (title) {
putc('\n', stdout);
pprintf(name, ":");
new_line();
}
nfiles = lp;
readdir(name);
if (fflg==0)
qsort(&flist[lp],(unsigned)(nfiles - lp),sizeof(struct lbuf *),compar);
if (Rflg) for (j = nfiles - 1; j >= lp; j--) {
ap = flist[j];
if (ap->ltype == 'd' && strcmp(ap->ln.lname, ".") &&
strcmp(ap->ln.lname, "..")) {
dp = (struct dchain *)calloc(1,sizeof(struct dchain));
if (dp == NULL)
fprintf(stderr,"ls: out of memory\n");
pname = makename(curdir, ap->ln.lname);
dp->dc_name = (char *)calloc(1,strlen(pname)+1);
if (dp->dc_name == NULL) {
fprintf(stderr,"ls: out of memory\n");
free(dp);
}
else {
strcpy(dp->dc_name, pname);
dp -> dc_next = dfirst;
dfirst = dp;
}
}
}
if (lflg || sflg)
curcol += printf("total %ld", tblocks);
pem(&flist[lp],&flist[nfiles],lflg||sflg);
}
int main(int argc, char **argv)
{
extern char *optarg;
extern int optind;
int amino, opterr=0;
int c;
register struct lbuf *ep;
struct lbuf lb;
int i, width;
long time();
char *malloc();
void qsort(), exit();
malloc is declared in stdlib.h as :
void *malloc(size_t size);
You code wrongly re-declares it as:
char *malloc();
Remove the wrong re-declaration and review use of malloc() carefully.

Trying to write a C function to read in stdin to elements of a struct

I have no idea how to call the function or what arguments to put in it. I've written the code in the main function, but I want to put it in a separate function I can call into main later. Would love some help on how I can do this!
The input comes from stdin
Here is the code (in the main function) that I want to put into a separate function:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
/* * * Define Constants * * */
#define WORD_LEN 22
#define MAX_NUM_POS_TAGS 5
#define SIZE_POS_TAG 4
#define MAX_NUM_VAR_FORMS 4
#define VAR_FORM_LEN 25
#define MAX_DICT_WORDS 100
/* * * Typedefs * * */
typedef char word_line_one[WORD_LEN+1];
typedef char word_line_two[MAX_NUM_POS_TAGS+1];
typedef char word_line_three[SIZE_POS_TAG+VAR_FORM_LEN*SIZE_POS_TAG+1];
//getword function prototype
int getword(char W[], int limit);
//check_if_valid function prototype
int check_if_valid(char in_char);
//stage1 function
int stage1(char ln1[], char ln2[], char ln3[]);
//main function
//stage 1
int main (int argc, char *argv[])
{
//define the struct for one word
struct
{
word_line_one line_one;
word_line_two line_two;
word_line_three line_three;
}one_word_dict_t;
//reading line 1
char temp1[WORD_LEN+1];
getword(temp1, WORD_LEN+1);
strncpy(one_word_dict_t.line_one, temp1,WORD_LEN+1 );
//reading line 2
getword(one_word_dict_t.line_two,MAX_NUM_POS_TAGS+1);//do something about spaces in between tags!
//reading line 3
getword(one_word_dict_t.line_three,SIZE_POS_TAG+VAR_FORM_LEN*SIZE_POS_TAG+1);
//printing the word in the format:
printf("==========================Stage 1==========================\n");
printf("Word 0: %s\n", one_word_dict_t.line_one);
printf("POS: %s\n", one_word_dict_t.line_two);
printf("Form: %s\n", one_word_dict_t.line_three);
//stage 1 ends here
}
//getword function def
/* Extract a single word out of the standard input, of not
more than limit characters. Argument array W must be
limit+1 characters or bigger. */
int
getword(char W[], int limit)
{
int c, len=0;
/* first, skip over any non alphabetics */
while ((c=getchar())!=EOF && !check_if_valid(c))
{
/* do nothing more */
}
if (c==EOF)
{
return EOF;
}
/* ok, first character of next word has been found */
W[len++] = c;
while (len<limit && (c=getchar())!=EOF && check_if_valid(c))
{
/* another character to be stored */
W[len++] = c;
}
/* now close off the string */
W[len] = '\0';
return 0;
}
//check if valid function, used in modified version of getword():
int check_if_valid(char in_char)
{
if ((('A'<=in_char)&&(in_char<='Z')) || (('a'<=in_char)&&(in_char<='z')) ||
(('0'<=in_char)&&(in_char<='9')))
{
return 1;
}
else
{
return 0;
}
}

How to convert array of char into array of int?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stats.h"
/* Size of the Data Set */
#define SIZE (40)
void print_array (unsigned char *p, int l) {
int i;
for (i=0;i<l;i++) {
printf("%d\t",*p);
p++;
}
}
void print_array_int (int *p, int l) {
int i;
for (i=0;i<l;i++) {
printf("%d\t",*p);
p++;
}
}
void typecasting(unsigned char test[SIZE], int array[SIZE]) {
int i=0;
unsigned char *token = strtok(test,",");
while (token) {
if(i<SIZE) {
array[i++] = atoi(token);
}
token = strtok(NULL,",");
}
}
void main() {
int array[SIZE] = {};
unsigned char test[SIZE] = {34,201,190,154,8,194,2,6,114,88,45,76,123,87,25,23,200,122,150,90,92,87,177,244,201,6,12,60,8,2,5,67,7,87,250,230,99,3,100,90};
/* Other Variable Declarations Go Here */
/* Statistics and Printing Functions Go Here */
print_array(test, SIZE);
typecasting(test,array);
print_array_int(array,SIZE);
}
What I want in this code is to convert the array of char into an array of int.
Previously I tried doing this by using pointers but didn't work and it showed stack smashing error. I want to convert this array of char into array of int to perform some mathematical operations.
You are trying too hard. Here's how typecasting should look
void typecasting(unsigned char test[SIZE], int array[SIZE]) {
for (int i = 0; i < SIZE; ++i)
array[i] = test[i];
}
Your code might be suitable if you were converting from a C string, i.e. if your original test array was
char test[] = "34,201,190,154,8,194,2,6,114,88,45,76,123,87,25,23,...";
So I guess you could say you're misunderstanding the nature of char (and unsigned char) in C++. They can represent character data as in char greeting[] = "hello"; or they can represent small integers as in char test[] = {1,2,3};.

passing uninitialized character array to function. Crashing

The string lengths are not getting the correct lengths, so the rest of the program doesn't work. I am trying to read 62 chars per line then print a new line with another 62 chars.
Can anyone help me correctly pass the char arrays to the output function?
#include <stdio.h>
#include <string.h>
#define _CRT_SECURE_NO_DEPRECATE
void output(char *wbuf, char *lbuf, int lineLength);
void readFile(FILE *getty, char *wbuf, char *lbuf);
FILE *getty;
int main(void) {
char wbuf[1000] = {0}, lbuf[1000] = {0};
if (fopen_s(&getty,"getty.txt", "r") != 0 )
{
printf("Failed to open getty.txt for reading.");
} else {
readFile(getty, wbuf, lbuf);
}
fclose(getty);
return 0;
}
void readFile(FILE *getty, char *wbuf, char *lbuf)
{
static int lineLength = 62;
while (!feof(getty))
{
fscanf(getty, "%s", wbuf);
output(wbuf, lbuf, lineLength);
}
}
void output(char *wbuf, char *lbuf, int lineLength)
{
int wbufLength, lbufLength, i = 0;
wbufLength = strlen(wbuf);
lbufLength = strlen(lbuf);
//prints incorrect
printf("wbuflength %d lbuflength %d\n", wbufLength, lbufLength);
// lengths
if ( (wbufLength + lbufLength) <= lineLength)
{
strcat(lbuf,wbuf); //lbuf should be 0 but it starts at
} //274, wbuf not correct either
else
{
strcat(lbuf,"\n");
lineLength += 62;
strcat(lbuf, wbuf);
}
}
The problem is your loop condition:
while (!feof(getty)) { ... }
The EOF flag is not set until after an input operation fails.
In your case, the loop loops, then the fscanf operation fails because it's at the end of the file but you don't check for that inside the loop, and you then call output even though nothing was read from the file. Then the loop continues and then it notices that the file have reached EOF.

qsort for structures c

Below is my code:
I cant seem to use qsort effectively... It turns my array into 0's after they are populated with names and start times... Is it a problem with my qsort call? or the qsort itself.
The header with the structures is as follows:
/**
* Simulation of a process scheduler
*/
//#ifndef SCHEDULER_H_
#define SCHEDULER_H_
#include <stddef.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
/* types */
/** units of time */
typedef long time;
/** process identifier */
typedef int pid;
/** Information about a job of interest to the task scheduler */
struct job_data {
/* pid of this process */
pid pid;
/* time process starts */
time start;
/* time needed to finish */
time finish;
/* time spent processing so far */
time scheduled;
/* Number of lines */
int lines;
};
struct job {
/* Various parameters used by the scheduler */
char job_id[20];
struct job_data parameters;
char *lines[20];
};
/* I/O Files */
//static char *inputFile;
char * in;
static FILE *input;
static FILE *cur;
/*Scheduled jobs indexed by PID*/
struct job list[20];
/* the next job to schedule */
//static struct job *job_next = NULL;
/* Time */
time clock;
/*Comparison for qsort*/
int compare_start(const void *x, const void *y)
{
const struct job *a = x;
const struct job *b = y;
printf("%ld, %ld\n", a->parameters.start, b->parameters.start);
if (a->parameters.start < b->parameters.start)
{
return -1;
}
if (a->parameters.start > b->parameters.start)
{
return 1;
}
return 0;
}
/*Order Jobs*/
static void order_jobs(void)
{
qsort(list, (sizeof list) / (sizeof list[0]), sizeof list[0], compare_start);
}
/** Read and parse input from input file */
static void parse_input(void)
{
char buffer[BUFSIZ];
char lines[BUFSIZ];
int jobs = 0;
struct job *current;
while( fgets(buffer, sizeof(buffer), input) )
{
time start;
char buf[BUFSIZ];
sscanf(buffer,"./%s/", buf);
cur = fopen(buf, "r" );
int n_lines = 0;
while( fgets(lines, sizeof(lines), cur) )
{
if( n_lines == 0 )
{
current = &list[jobs];
strcpy(current->job_id, buf);
sscanf(lines,"%ld", &start);
current->parameters.start = start;
}
n_lines++;
}
current->parameters.lines = n_lines;
jobs++;
fclose(cur);
}
order_jobs();
for (int i = 0; i < jobs; i++)
{
printf("%s %ld %d\n", list[i].job_id, list[i].parameters.start, list[i].parameters.lines);
}
}
int main(int argc, char **argv)
{
in = argv[1];
if ( (input = fopen(in, "r")) == NULL ) {
fprintf(stderr, "cannot open %s\n", argv[1]);
}
parse_input();
fclose(input);
return EXIT_SUCCESS;
}
You only load jobs entries into the array, but you tell qsort() to sort the entire array (20 elements). This probably puts non-initialized elements at the front, which you then print.

Resources