Weird Syntax Error In C in If-else - c

I was programming an apache module. In the middle of the programming, I was opening a file, but I got an error while compiling.
32. static int wqb_handler(request_rec* req){
33. // Open and read our requested file
34. const char* p_file = req->filename;
35.
36. FILE* req_file;
37. if((req_file = fopen(p_file,"r"))==NULL){
38. return HTTP_NOT_FOUND;
39. }else{
40. fclose(req_file);
41. }
42. // Required variables
43. const char* content_type_a = "text/html";
44.
45. // Set Headers
46. ap_set_content_type(req,content_type_a);
47. if(req->header_only){
48. return OK;
49. }
50.
51.
52. return OK;
53. }
The problem is in that function, I was checking that was the problem, and I think the problem is the if-else statement, the code is written in C, not in C++.
These are the errors:
C:/wqb/wqb1_apache2.c(43) : error C2143: syntax error : missing ';' in front of 'const'
C:/wqb/wqb1_apache2.c(46) : error C2065: 'content_type_a' : undeclarated identifier

If this is C, and you're not compiling in C99 mode (i.e. with a C89 compiler), remember that all declarations must be directly following the start of a block.
Mixing declarations and code is a C99 feature imported from C++.
It appears you are compiling with a Micrososft Visual Studio Compiler in C mode. Note that William H. Gates III chose to ignore C99 entirely and refuses to update the C implemenation for the third millennium. :-)

Share with the solution of your problem. It will help the others to understand it more quickly.
Improve your knowledge about operators and comments.
You're writing too many unnecessary { and } in the operators.
For example, your code:
for( i = 0; i < N; i++ )
{
printf("Hello");
}
More simple/clear code:
for( i = 0; i < N; i++ )
printf("Hello");
...........................................................................
Your code (original) may look so (It's easier to read and understand.):
static int wqb_handler(request_rec* req)
{
/* Open and read our requested file */
const char* p_file = req -> filename;
FILE* req_file;
if((req_file = fopen(p_file,"r"))==NULL)
return HTTP_NOT_FOUND;
else
fclose(req_file);
/* Required variables */
const char* content_type_a = "text/html";
/* Set Headers */
ap_set_content_type(req,content_type_a);
if(req->header_only)
return 0;
return OK;
}

Related

Polyspace Run-time check alert with C open() function

First, please consider the following piece of code (static function called once from main()):
#define SYSFS_GPIO_DIR "/sys/class/gpio"
#define MAX_BUF ((UI_8)64)
typedef uint8_t UI_8
typedef int32_t SI_32
typedef char CHAR_8
static SI_32 ImuGpioFdOpen(UI_8 gpio)
{
SI_32 fd_gpio_open = -1;
SI_32 byte_count = -1;
CHAR_8 aux_buf[MAX_BUF] = {'\0'};
byte_count = snprintf(aux_buf, sizeof(aux_buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
if((byte_count > 0) && (byte_count < sizeof(aux_buf))){
fd_gpio_open = open(aux_buf, O_RDONLY | O_NONBLOCK );
if(fd_gpio_open < 0){
syslog (LOG_ERR,"gpio/fd_open");
fd_gpio_open = ERROR;
}
}
return fd_gpio_open;
}/*ImuGpioFdOpen*/
On the call to open(), static analysis with Polyspace Code Prover raises and alert regarding MISRA's "Dir 4.1 Run-time failures shall be minimized". The alerts says that: "first argument (file path) may not be a valid string"
We don't seem to understand the directive very well, because all our efforts to solve the alerts like this (we have several similar ones) are not yielding results. I mean, we are clearly not building the string correctly, but since the program compiles and runs correctly, we are at a loss.
What kind of run-time check are we missing?
Thank you!
EDIT: I forgot to mention that passing a string literal seems to work for Polyspace, but it doesn't work if we try to pass string generated at runtime (like in the code). Could it be because open()'s prototype declares that the first argument is const char* and Polyspace is taking it too seriously?
The issue has been judged to be a false positive. The alerts shall be justified accordingly.
Thanks!

How to use the array from another function in main?

Edit: I made some changes at my code.
I want to write a line fitting program by using the data from two .txt file. The code is as following:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int data_read(char programs_x[], char programs_y[]) {
int i=0, j=0, k;
int numProgs_x=0;
int numProgs_y=0;
char line_x[1024];
char line_y[1024];
FILE *file_x;
FILE *file_y;
file_x = fopen("data_x.txt", "r");
file_y = fopen("data_y.txt", "r");
while(fgets(line_x, sizeof line_x, file_x)!=NULL) {
//check to be sure reading correctly
//printf("%s", line_x);
//add each filename into array of programs
programs_x[i]=strdup(line_x);
i++;
//count number of programs in file
numProgs_x++;
}
while(fgets(line_y, sizeof line_y, file_y)!=NULL) {
//check to be sure reading correctly
//printf("%s", line_y);
//add each filename into array of programs
programs_y[j]=strdup(line_y);
j++;
//count number of programs in file
numProgs_y++;
}
fclose(file_x);
fclose(file_y);
return 0;
}
int main ( void ) {
int i, j, k, n=1024;
float s1=0,s2=0,s3=0,s4=0,a,d,b;
char programs_x[1024], programs_y[1024];
data_read(programs_x, programs_y);
for(i=0;i<n;i++) {
scanf("%f", &programs_x[k]);
}
for(i=0; i<n; i++){
scanf("%f", &programs_y[k]);
}
for(i=0;i<n;i++) {
s1=s1+programs_x[i];
s2=s2+programs_x[i] * programs_x[i];
s3=s3+programs_y[i];
s4=s4+programs_x[i] * programs_y[i];
}
d=n*s2-s1*s1;
a=(s2*s3-s1*s4)/d;
b=(n*s4-s1*s3)/d;
printf("\nThe values of a and b are : %f\t%f\n",a,b);
printf("\nThe Required Linear Relation is : \n");
if(b>0){
printf("\ny=%f+%fx\n",a,b);
}
else {
printf("y=%f%fx",a,b);
}
return 0;
}
When I try to compile this code, the compiler shows these error:
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
test3.c:
Error E2349 test3.c 22: Nonportable pointer conversion in function data_read
Error E2349 test3.c 33: Nonportable pointer conversion in function data_read
*** 2 errors in Compile ***
How do I fix the errors? Where did I make mistakes in declaring and calling the data types? I'm pretty sure I declare programs_x and programs_y as char this time and not int.
The error is difficulty to pin down as we don't have line numbers but this line is definitely not right in your main:
data_read(char programs_x[], char programs_y[]);
To call a function you just list the variables and values you're passing to it like this:
data_read(programs_x, programs_y);
Which will no doubt cause more errors/warnings to be flagged as you declare programs_x and programs_y as arrays of int, but data_read is expecting arrays of char. So there's a conflict in what you think your function wants and what you're providing to it which you need to sort out.
The error could mean that the non-standard function strdup() is not supported. A C compiler does not need to support it, which is why it is a good idea to avoid that function. If the function is supported as a non-standard extension (it is part of POSIX), you might find it in the header <string.h> which you didn't include.
As for the cause of the rest of the errors, I have no idea, since those appear to originate from other files than the one you posted.

How can I create a grammar rule for an error?

I am writing a compiler in C, and I use bison for the grammar and flex for the tokens. To improve the quality of error messages, some common errors need to appear in the grammar. This has the side effect, however, of bison thinking that an invalid input is actually valid.
For example, consider this grammar:
program
: command ';' program
| command ';'
| command {yyerror("Missing ;.");} // wrong input
;
command
: INC
| DEC
;
where INC and DEC are tokens and program is the initial symbol. In this case, INC; is a valid program, but INC is not, and an error message is generated. The function yyparse(), however, returns 0 as if the program were correct.
Looking at the bison manual, I found the macro YYERROR, which should behave as if the parser itself found an error. But even if I add YYERROR after the call to yyerror(), the function yyparse() still returns 0. I could use YYABORT instead, but that would stop on the first error, which is terrible and not what I want.
Is there anyway to make yyparse() return 1 without stopping on the first error?
Since you intend to recover from syntax errors, you're not going to be able to use the return code from yyparse to signal that one or more errors occurred. Instead, you'll have to track that information yourself.
The traditional way to do that would be to use a global error count (just showing the crucial pieces):
%{
int parse_error_count = 0;
%}
%%
program: statement { yyerror("Missing semicolon");
++parse_error_count; }
%%
int parse_interface() {
parse_error_count = 0;
int status = yyparse();
if (status) return status; /* Might have run out of memory */
if (parse_error_count) return 3; /* yyparse returns 0, 1 or 2 */
return 0;
}
A more modern solution is to define an additional "out" parameter to yyparse:
%parse-param { int* error_count }
%%
program: statement { yyerror("Missing semicolon");
++*error_count; }
%%
int main() {
int error_count = 0;
int status = yyparse(&error_count);
if (status || error_count) { /* handle error */ }
Finally, in case you really need to export the symbol yyparse from your bison-generated code, you can do the following ugly hack:
%code top {
#define yyparse internal_yyparse
}
%parse-param { int* error_count }
%%
program: statement { yyerror("Missing semicolon");
++*error_count; }
%%
#undef yyparse
int yyparse() {
int error_count = 0;
int status = internal_yyparse(&error_count);
// Whatever you want to do as a summary
return status ? status : error_count ? 1 : 0;
}
yyerror() just prints an error message. It doesn't alter what yyparse() returns.
What you're attempting is not a good idea. You'll enormously expand the grammar and you run a major risk of making it ambiguous. All you need to do is remove the production that calls yyerror(). That input will produce a syntax error anyway, and that will cause yyparse() not to return 0. You're keeping a dog and barking yourself. What you should be checking for is semantic errors that the parser can't see.
If you really want to improve the error messages, there's enough information in the parse tables and state information to tell you what the expected next token was. However in most cases it's such a large set it's pointless to print it. But programmers are used to sorting out 'syntax error'. Don't sweat it. Writing compilers is hard enough already.
NB You should make your grammar left-recursive to avoid excessive stack usage: for example, program : program ';' command.

Lex/Flex Scanner Isn't Scanning and I Have No Idea Why

I have written a simple lex scanner in the file myscanner.l, where testlex.h is just a bunch of #defines as integers (MATCH_0 == 0, etc)
%{
#include "testlex.h"
%}
%%
"dinky" return MATCH_0;
"pinky" return MATCH_1;
"stinky" return MATCH_2;
[ \t\n] ;
. printf("unexpected character\n");
%%
int yywrap(void)
{
return 1;
}
After using lex to create the lex.yy.c file, I implement the code using this C file
#include <stdio.h>
#include "myscanner.h"
extern int yylex();
extern int yylineno;
extern char* yytext;
int main(void)
{
int l = yylex();
while (l)
{
printf("%d\n", l);
l = yylex();
}
return 0;
}
When I pass it this input stream: dinky pinky stinky stinky pinky dinky, there is absolutely no output. The output I am expecting looks like this:
0
1
2
2
1
0
Not even "unexpected character". I know my stack is set up right because I've compiled others' examples and they all scan correctly, but for some inconceivable reason my code _will_not_scan_!
What am I missing?
Looking at your expected output, what you see is the simple result of defining "dinky" -> MATCH_0 as 0.
The first value of l now becomes 0, after having scanned dinky. So while(l) is while(0) and the block is not even executed once. Subsequently your main immediately returns 0.
So don't define any tokens as 0, and then write:
int main(void)
{
int token;
while (token = yylex())
{
printf("%d\n", token);
}
return 0;
}
To be honest I'm surprised you did not find this yourself. Simply trying other input would immediately have giving a clue. And, it should be easy to find that yylex() returns 0 at EOF.
BTW, I think it's better to not use l as variable name as it's almost the same as 1.
The reason why your code does not print anything is that your first input happens to be "dinky", which returns MATCH_0. According to your expected output, MATCH_0 is zero. Therefore, the code will exit right away, before entering the loop even once.
Re-defining MATCH_0 to 1, MATCH_1 to 2, and so on will fix this problem.

print concat value of newline("\n") result shows as <?> symbol in C

I have a code below
#include <stdio.h>
int main()
{
char *price_c = "200";
char *s_att = "test ";
int satt=strlen(s_att);
int price_len = strlen(price_c);
int send_attach_len = price_len+satt;
size_t length = send_attach_len +2;
char *concat = malloc(sizeof(char) *length);
snprintf(concat, length, "%s%s%s", s_att, price_c, "\n");
printf("value of concat is %s", concat);
}
when I see the value printed, I have only test 200 , but on some other occasion, I have test 200 < ? > where < ? > is a weird symbol, somehow the new line is not recognised.
But it is very strange because not all the time this weird symbol is shown up..
It just came up randomly. I am using ubuntu 10.04
Can anyone help me to solve this new line problem, so that it shows new line, and not weird symbol. Or maybe I can change the approach to concat the above value so that the new line is rendered correctly, and not showing a weird symbol?
The code looks ok, except for the very important fact that you are missing some headers.
strlen is in <string.h>, and malloc is in <stdlib.h>.
Include those, turn on your compiler warnings (-Wall for GCC), change your main signature to:
int main(void) { }
and actually return an int from it (or compile as C99, std=c99 for GCC), and the problems should go away.

Resources