I had a problem initializing the PMU in gem5 for an arm full system with the starter_fs.py in --cpu hpi.
i followed the instructions of this post Using perf_event with the ARM PMU inside gem5 and i managed to solve my problem. I added the patch and configure the system. I am not using perf. I try to access directly the registers and read them. As i see GEM5 has only some register events implemented. Can we add the others as well as :
for example EXC_TAKEN is not implemented. Is the following the way to add them?
self.addEvent(ProbeEvent(self,0x09, cpu, "EXC_TAKEN"))
#0x09: EXC_TAKEN ???
Also, reading the pmu event registers i manage to read them and extract the events but the pmccntr cycle register always returns zero? How gem5 increments this register? What are the steps to read the cycle reggister?
a code that i use to read using perf is the following:
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/perf_event.h>
#define NUM_NODES 100
#define NONE 9999
struct _NODE
{
int iDist;
int iPrev;
};
typedef struct _NODE NODE;
struct _QITEM
{
int iNode;
int iDist;
int iPrev;
struct _QITEM *qNext;
};
typedef struct _QITEM QITEM;
QITEM *qHead = NULL;
int AdjMatrix[NUM_NODES][NUM_NODES];
int g_qCount = 0;
NODE rgnNodes[NUM_NODES];
int ch;
int iPrev, iNode;
int i, iCost, iDist;
void print_path (NODE *rgnNodes, int chNode)
{
if (rgnNodes[chNode].iPrev != NONE)
{
//print_path(rgnNodes, rgnNodes[chNode].iPrev);
}
//printf (" %d", chNode);
fflush(stdout);
}
void enqueue (int iNode, int iDist, int iPrev)
{
QITEM *qNew = (QITEM *) malloc(sizeof(QITEM));
QITEM *qLast = qHead;
if (!qNew)
{
//fprintf(stderr, "Out of memory.\n");
exit(1);
}
qNew->iNode = iNode;
qNew->iDist = iDist;
qNew->iPrev = iPrev;
qNew->qNext = NULL;
if (!qLast)
{
qHead = qNew;
}
else
{
while (qLast->qNext) qLast = qLast->qNext;
qLast->qNext = qNew;
}
g_qCount++;
// ASSERT(g_qCount);
}
void dequeue (int *piNode, int *piDist, int *piPrev)
{
QITEM *qKill = qHead;
if (qHead)
{
// ASSERT(g_qCount);
*piNode = qHead->iNode;
*piDist = qHead->iDist;
*piPrev = qHead->iPrev;
qHead = qHead->qNext;
free(qKill);
g_qCount--;
}
}
int qcount (void)
{
return(g_qCount);
}
int dijkstra(int chStart, int chEnd)
{
for (ch = 0; ch < NUM_NODES; ch++)
{
rgnNodes[ch].iDist = NONE;
rgnNodes[ch].iPrev = NONE;
}
if (chStart == chEnd)
{
//printf("Shortest path is 0 in cost. Just stay where you are.\n");
}
else
{
rgnNodes[chStart].iDist = 0;
rgnNodes[chStart].iPrev = NONE;
enqueue (chStart, 0, NONE);
while (qcount() > 0)
{
dequeue (&iNode, &iDist, &iPrev);
for (i = 0; i < NUM_NODES; i++)
{
if ((iCost = AdjMatrix[iNode][i]) != NONE)
{
if ((NONE == rgnNodes[i].iDist) ||
(rgnNodes[i].iDist > (iCost + iDist)))
{
rgnNodes[i].iDist = iDist + iCost;
rgnNodes[i].iPrev = iNode;
enqueue (i, iDist + iCost, iNode);
}
}
}
}
//printf("Shortest path is %d in cost. ", rgnNodes[chEnd].iDist);
//printf("Path is: ");
//print_path(rgnNodes, chEnd);
//printf("\n");
}
}
int main(int argc, char *argv[]) {
int diff = 0;
uint64_t num_cycles_nominal=0;
uint64_t num_cycles_attack=0;
uint64_t counter_cpu_cycles = 0;
//system("./load-module");
int i,j,k;
FILE *fp;
static int perf_fd_cpu_cycles;
static struct perf_event_attr attr_cpu_cycles;
attr_cpu_cycles.size = sizeof(attr_cpu_cycles);
attr_cpu_cycles.exclude_kernel = 1;
attr_cpu_cycles.exclude_hv = 1;
attr_cpu_cycles.exclude_callchain_kernel = 1;
attr_cpu_cycles.type = PERF_TYPE_RAW;
attr_cpu_cycles.config = 0x11;
/* Open the file descriptor corresponding to this counter. The counter
should start at this moment. */
if ((perf_fd_cpu_cycles = syscall(__NR_perf_event_open, &attr_cpu_cycles, 0, -1, -1, 0)) == -1)
fprintf(stderr, "perf_event_open fail %d %d: %s\n", perf_fd_cpu_cycles, errno, strerror(errno));
if (argc<2) {
//fprintf(stderr, "Usage: dijkstra <filename>\n");
//fprintf(stderr, "Only supports matrix size is #define'd.\n");
}
/* open the adjacency matrix file */
fp = fopen (argv[1],"r");
/* make a fully connected matrix */
for (i=0;i<NUM_NODES;i++) {
for (j=0;j<NUM_NODES;j++) {
/* make it more sparce */
fscanf(fp,"%d",&k);
AdjMatrix[i][j]= k;
}
}
/* Get and close the performance counters. */
read(perf_fd_cpu_cycles, &counter_cpu_cycles, sizeof(counter_cpu_cycles));
//close(perf_fd_cpu_cycles);
printf("Number of cpu_cycles before: %d\n", counter_cpu_cycles);
num_cycles_nominal = counter_cpu_cycles;
/* Get and close the performance counters. */
read(perf_fd_cpu_cycles, &counter_cpu_cycles, sizeof(counter_cpu_cycles));
//close(perf_fd_cpu_cycles);
printf("Number of cpu_cycles after attack: %d\n", counter_cpu_cycles);
num_cycles_attack = counter_cpu_cycles - num_cycles_nominal;
/* finds 10 shortest paths between nodes */
for (i=0,j=NUM_NODES/2;i<100;i++,j++) {
j=j%NUM_NODES;
dijkstra(i,j);
}
read(perf_fd_cpu_cycles, &counter_cpu_cycles, sizeof(counter_cpu_cycles));
close(perf_fd_cpu_cycles);
printf("Number of cpu_cycles end: %d\n", counter_cpu_cycles);
num_cycles_nominal = counter_cpu_cycles - num_cycles_attack;
printf("Number of cpu_cycles nominal: %d\n", num_cycles_nominal);
printf("Number of cpu_cycles attack: %d\n", num_cycles_attack);
exit(0);
}
the problem is that i can read the branch misses with perf having 0x10 instead 0f 0x11 (cycle counters RAW EVENT in GEM5) but using 0x11 for reading the cycles i get zero. When i try to reverse engineer the increment of cycle counter i do the following comments:
when simple/atomic or simple/timing i see that updateCycleCounter is called from the base.hh, also for the 03 cpu model. When HPI and considering that hpi is a MinorCPU model i see that updateCycleCounter is called only in POWER_STATE_ON, but i didnt find in the code a POWER_STATE_ON reference updateCycleCounter(CPU_STATE_ON) which will update the cycle counter. Please help me verify this assumption.
*****The problem was that in the MinorCPU the updateCycleCounter wasnt called for the CPU_STATE_ON which updates the ActiveCycles. It was fixed by the following patch https://gem5-review.googlesource.com/c/public/gem5/+/38095 .
Still following the saga of a Cobol developer handling C programs on a environment migration.
I think we could manage 90% of the problems so far and most of our C programs are now compiling fine on the RHEL 64 bits.
Friday we found another module that is not compiling and I hope to be the last one.
I am receiving two warnings, but I have no idea about it and our make does not allow us to compile it properly.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <memory.h>
#include <errno.h>
#include </public/prod/src/mfqinc.h>
static FILE *infile = NULL;
static FILE *outfile = NULL;
char inbuf[1024], blockrec[10240];
static char workstring[1024];
static char workstring0[1024];
static char gra2533h [8];
static char gra2401h [8] ;
static char gra2501h [8] ;
static char gra2506h [8] ;
static char crtn[1] ; /* {"0x0A"};*/
int i;
int z;
int f;
int resulisn;
int j;
int d;
int ctrrec;
int nb_ecrit;
static int longueur;
void initworkstring()
{
extern char workstring [1024];
int ik;
for (ik=0; ik < 1024 ;ik++)
{
workstring [ik] = NULL;
}
}
void ecriture()
{
extern char workstring [1024];
extern int longueur;
extern int ctrrec;
nb_ecrit = fwrite(workstring,sizeof(char),longueur,outfile);
ctrrec++;
if ( nb_ecrit != longueur )
{
printf("andlog:erreur d ecriture ");
printf("Ecrit: %i",nb_ecrit);
printf("Erreur no: %i",errno);
exit(60);
}
}
static void errarg(char *errmsg)
{
fprintf(stderr,"ERROR - %s\nCommand format :\n\t",errmsg);
fprintf(stderr," : \n");
/* exit(1); */
}
main (int argc, char *argv[])
{
if ( argc < 3 )
{
printf("<<< Programme : and015 >>>\n");
printf("<<< Nombre de parametres incorrect >>>\n");
printf("<<< Remove catacteres speciaux >>>\n");
printf("<<< Param # 1 = nom du fichier d'input >>>\n");
printf("<<< Param # 2 = nom du fichier d'output >>>\n");
printf("\n");
exit(10);
}
if ((infile = fopen(argv[1],"rb")) == NULL )
{
printf("Erreur sur fichier input \n");
exit(20);
}
if ((outfile = fopen(argv[2],"wb")) == NULL )
{
printf("Erreur sur fichier output \n");
exit(30);
}
initworkstring();
/* remplir les table de catacteres */
crtn[0]=0x0a;
gra2533h[0]=0x1b;
gra2533h[1]=0x5b;
gra2533h[2]=0x32;
gra2533h[3]=0x35;
gra2533h[4]=0x3b;
gra2533h[5]=0x33;
gra2533h[6]=0x33;
gra2533h[7]=0x48;
gra2401h[0]=0x1b;
gra2401h[1]=0x5b;
gra2401h[2]=0x32;
gra2401h[3]=0x34;
gra2401h[4]=0x3b;
gra2401h[5]=0x30;
gra2401h[6]=0x31;
gra2401h[7]=0x48;
gra2501h[0]=0x1b;
gra2501h[1]=0x5b;
gra2501h[2]=0x32;
gra2501h[3]=0x35;
gra2501h[4]=0x3b;
gra2501h[5]=0x30;
gra2501h[6]=0x31;
gra2501h[7]=0x48;
gra2506h[0]=0x1b;
gra2506h[1]=0x5b;
gra2506h[2]=0x32;
gra2506h[3]=0x35;
gra2506h[4]=0x3b;
gra2506h[5]=0x30;
gra2506h[6]=0x36;
gra2506h[7]=0x48;
while (fgets(inbuf,1024,infile) != NULL )
{
i=0;
j=0;
d=0;
for (i=0; i < 1024 ; i++)
{
if ( inbuf [i] == NULL )
{
i = 9999;
}
else
{
if ( inbuf[i] == 0x1b )
{
i++;
d=0;
for (d=0 ;d < 8; d++)
{
if ( inbuf[i] == 0x48 )
{
j= j-d;
workstring[j]=0x0a;
d=99;
}
else
{
if (inbuf[i] == 0x6d)
{
j= j-d;
workstring[j]=0x0a;
d=99;
}
else
{
if (inbuf[i] == 0x53)
{
j=j-d;
workstring[j]=0x0a;
d=99;
}
else
{
workstring[j] = inbuf[i];
j++;
i++;
}
}
}
} /* end du for*/
}/*fin du if 01b*/
else
{
workstring[j] = inbuf[i];
j++;
}
}
/* mettre dans workstring */
workstring [j] = inbuf [i];
}
strcat(workstring,crtn);
longueur = j ;
ecriture ();
initworkstring();
} /* fin du while */
fclose(infile);
fclose(outfile);
exit(0);
}
Those are the warnings I am having.
/exp/prod/src>gcc -m64 mfqlog.c -o mfqlog
mfqlog.c: In function 'initworkstring':
mfqlog.c:48:20: warning: assignment makes integer from pointer without a cast [enabled by default]
workstring [ik] = NULL;
^
mfqlog.c: In function 'main':
mfqlog.c:146:18: warning: comparison between pointer and integer [enabled by default]
if ( inbuf [i] == NULL )
Really sorry to bother with this question. But I really need to compile this code.
The funny fact is that the program is working (probably, for some unknown reason to me, the program was compiling before and it is not anymore due to changes on the compiler maybe?!?) on our actual environment, but if we try to compile it will fail and the only way to make it working is restoring the executable backup.
As we are moving to a new 64 bits environment, it has to be recompiled.
Thank you all for the help.
NULL is defined as (void*)0. Replace NULL with '\0' or 0.
workstring [ik] = '\0';
if ( inbuf [i] == '\0' )
typedef struct Email
{
char domain [128];
char local [128];
} Email ;
Email email_in(char s[])
{
Email *result ;
int c=0;
for(c=0;c<128;c++)
{
result->domain[c]='\0';
result->local[c]='\0';
}
char *ss = s;//PG_GETARG_CSTRING(0);
//result = 0;
int i,j, ind1=0, x=0 , dot=0;
int length= strlen(ss);
for(i=0; i<length;i++)
{
if(ss[i]<='Z' && ss[i]>='A' )
{
ss[i]=ss[i]+32;
}
}
;
if ( ((ss[0]<'a') || (ss[0]>'z')) )
{
if((ss[0]<'A') || (ss[0]>'Z'))
perror("Error printed by perror=1");
}
else
{
for ( i=0;i<length;i++)
{
if (ss[i]=='#')
{
result->local[i]=ss[i];
ind1=i+1;
break;
}
else
if(ss[i]=='-' || ss[i]=='.')
if(ss[i-1]=='-' || ss[i-1]=='.')
{
perror("Error printed by perror=4 ");
}
if ( ((ss[i]<'a') || (ss[i]>'z') )&&((ss[i]<'0')||(ss[i]>'9')) )
{
if(((ss[i]<'A') || (ss[i]>'Z')) &&(ss[i]!='-') &&(ss[i]!='.') )
{
printf("%c \n",ss[i]);
perror("Error printed by perror=2");
}
}
if(ss[i]!='#')
result->local [i]=ss[i];
}
for ( j=ind1;j<length;j++)
{
if(ss[j]=='.')
dot= dot+1;
if(ss[j]=='-' || ss[j]=='.')
if(ss[j-1]=='-' || ss[j-1]=='.')
{
perror("Error printed by perror=6 ");
}
if ( (ss[j]<'a') || ((ss[j]>'z' ) ) )
{
if(((ss[j]<'A') || (ss[j]>'Z')) &&(ss[j]!='-') &&(ss[j]!='.') )
perror("Error printed by perror=3 ");
}
result->domain [x]=ss[j];
x=x+1;
}
result->domain[x+1]='\0';
result->domain[x]='\0';
if(dot<1 && dot >2)
perror("invalid domain");
}
return*(result);//PG_RETURN_POINTER(result);
}
void main()
{
char s1[]="tami#openu.ac.il\0";
email_in(s1);
//printf("%s",s1);
}
When it reach result->domain[c]='\0'; its showed me error
"reslut=null"
I need pointer to change in original copy but how to do it?
this function use to validate email address used in PostgreSQL to add new data type
I have zero experience in c or c++
I need help ><
When you do
Email *result ;
you get a pointer to Email but you don't get an Email variable.
In this case you should avoid pointer and use the struct directly. Something like:
#include <stdio.h>
#include <string.h>
typedef struct Email
{
char domain [128];
char local [128];
} Email ;
Email email_in()
{
Email result; // Don't use pointer
strcpy(result.domain, "test_domain");
strcpy(result.local, "test_local");
return result;
}
int main(void) {
Email x=email_in(); // Make the variable x of type Email
printf("%s\n", x.domain);
printf("%s\n", x.local);
return 0;
}
If you prefer working with pointers, you could try something like:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct Email
{
char domain [128];
char local [128];
} Email ;
Email* email_in()
{
Email* result;
result = malloc(sizeof(Email)); // Allocate memory for an Email and make result point to it
strcpy(result->domain, "test_domain");
strcpy(result->local, "test_local");
return result;
}
int main(void) {
Email* x=email_in(); // Make the variable x of type pointer to Email
printf("%s\n", x->domain);
printf("%s\n", x->local);
free(x); // Free the allocated memory
return 0;
}
The program should save a couple of points and put them out on request.
The program contains one .h file and two .c files.
This is the compiler info i get:
prog.c:46:25: fatal error: pointstack.h: No such file or directory #include "pointstack.h"
What did I miss?
//File: pointStack.h - Headerfile
#ifndef POINTSTACK_H
#define POINTSTACK_H
#include <stdio.h>
#include <stdlib.h>
//structs
//struct for coordinates
struct point
{
float rX;
float rY;
float rZ;
};
typedef struct point POINT;
struct stackPoint
{
POINT p;
struct stackPoint *next;
};
typedef struct stackPoint STACK_POINT;
typedef STACK_POINT *STACK_POINT_PTR;
//functions
void push(POINT pushPoint);
POINT pop();
int isEmpty();
void printStackElement(POINT aPoint);
#endif
//File: pointstack.c - functions of stack program
#include "pointstack.h"
//global variable
STACK_POINT_PTR stackTop = NULL;
void push(POINT pushPoint)
{
//temporary variable
STACK_POINT_PTR stackPoint = (STACK_POINT_PTR) malloc(sizeof(STACK_POINT));
//in case there is not enough memory
if(stackPoint == NULL)
{
printf("not enough memory ... End \n");
exit(1);
}
//save point
stackPoint->p = pushPoint;
stackPoint->next = stackTop;
stackTop = stackPoint;
return;
}
POINT pop()
{
//save stackTop and nextStackTop
STACK_POINT firstStackPoint = *stackTop;
free(stackTop);
stackTop = firstStackPoint.next;
return firstStackPoint.p;
}
int isEmpty()
{
if(stackTop == NULL)
{
return 1;
}
else {
return 0;
}
}
void printStackElement(POINT aPoint)
{
printf("Point x: %f, Point y: %f, Point z: %f \n", aPoint.rX, aPoint.rY, aPoint.rZ);
return;
}
//File: stackmain.c
#include "pointstack.h"
void exit(int);
POINT readPoint()
{
POINT userPoint;
printf("x-coordinate \n");
scanf("%62f", &userPoint.rX);
printf("y-coordinate \n");
scanf("%62f", &userPoint.rY);
printf("z-coordinate \n");
scanf("%62f", &userPoint.rZ);
return userPoint;
}
int main(void)
{
//declaration
char cCmd;
printf("’p’ for input, ’q’ for output: \n");
while(1)
{
scanf("%c", &cCmd);
if(cCmd == 'p')
{
push(readPoint());
printf("’p’ for input, ’q’ for output: \n");
}
if(cCmd == 'q')
{
while(!isEmpty())
{
printStackElement(pop());
}
break;
}
}
return 0;
}
What you missed is that your file is called pointStack.h with a capital S, not pointstack.h with a lower case s.
I'm writing a little program in C, for check the HTML file have the right open and close tags?
but i've got some issues...
i have a file what contains the all possible tags, named tags.txt(those are only the first ones):
<a>
</a>
<abbr>
</abbr>
<area>
</area>
<aside>
</aside>
and i have the htmlfile.html, what I have to check:
<!--#echo var="date" -->
<area>
</area>
<area>
</area>
secondly, i want to replace the comments like this to the sysdate
like , the format is OK i can do it, but the prog puts in the file
this
my code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#define MAX_SIZE 512
void menu();
void check();
void datumos();
int main(int argc,char *argv[])
{
menu();
return 0;
}
void menu()
{
char menu[MAX_SIZE];
while(1 < 2)
{
printf("\npress a button:\n\n");
printf("\tFile HTML check..............:c\n");
printf("\t<!--#echo var="date" -->...........:d\n");
printf("\tExit:\tCTRL + C\n");
scanf("%s",menu);
if( strcmp(menu,"c") == 0 )
{
check();
}
else if( strcmp(menu,"d") == 0 )
{
datumos();
}
}
}
void check()
{
FILE *htmlfile;
FILE *checkfile;
htmlfile = fopen("htmlfile.html","w");
checkfile = fopen("tags.txt","r");
char line[MAX_SIZE];
char htmlline[MAX_SIZE];
char tags[189][30];
int i=0;
printf("\tcheck__1\n");
while(fgets(line,sizeof(line),checkfile) != NULL)
{
int j;
for(j=0; j<sizeof(line); ++j)
{
tags[i][j]=line[j];
}
++i;
}
printf("\tcheck__2\n");
int k=0; char htmlfiletags[MAX_SIZE][30];
while(fgets(htmlline,sizeof(htmlline),htmlfile) != NULL)
{
char currentline[sizeof(htmlline)];
int j=0;
if( currentline[j]=="<" )
{
while(currentline[j]!=">")
{
htmlfiletags[k][j]=currentline[j];
++j;
}
strcat(htmlfiletags[k][j+1],">");
++k;
}
}
printf("\tcheck__3\n");
int n;
for(n=0; n<sizeof(htmlfiletags); ++n)
{
int j; int howmanytimesnot=0;
for(j=0; j<sizeof(tags); ++j)
{
printf("\tcheck__3/1\n");
if(strcmp(htmlfiletags[n],tags[j])==0)
{
printf("\t%d\n", howmanytimesnot);
++howmanytimesnot;
}
}
printf("\tcheck__3/3\n");
if(!(howmanytimesnot<sizeof(tags)))
{
printf("\tcheck__3/4\n");
printf("the file is not wellformed");
exit (1);
}
}
printf("\tcheck__4\n");
}
void copy_file(const char *from,const char *to)
{
FILE *fr;
FILE *t;
fr = fopen(from,"r");
t = fopen(to,"w");
char line[MAX_SIZE];
char row[MAX_SIZE];
while(fgets(line,sizeof(line),fr) != NULL)
{
sscanf(line,"%s",row);
fprintf(t,"%s\n",row);
}
fclose(fr);
fclose(t);
remove("tempfile.html");
}
void datumos()
{
time_t now = time(NULL);
struct tm *t = localtime(&now);
char date_time[30];
strftime( date_time, sizeof(date_time), "%x_%X", t );
FILE *htmlfile;
FILE *tempfile;
htmlfile = fopen("htmlfile.html","r");
tempfile = fopen("tempfile.html","w");
char line[MAX_SIZE];
//char datecomment[]="<!--#echo var=date -->";
while(fgets(line,sizeof(line),htmlfile) != NULL)
{
if( strcmp(line,"<!--#echo var="date" -->") == 0 )
{
char row[40];
strcpy(row,"<!--");
strcat(row, date_time);
strcat(row,"-->");
printf("%s",row);
fputs(row,tempfile);
}
else
{
fputs(line,tempfile);
}
}
fclose(htmlfile);
fclose(tempfile);
copy_file("tempfile.html","htmlfile.html");
}
it dies in this, in the inner for loop, in the if at the 200th check... i dont know why...
int n;
for(n=0; n<sizeof(htmlfiletags); ++n)
{
int j; int howmanytimesnot=0;
for(j=0; j<sizeof(tags); ++j)
{
printf("\tcheck__3/1\n");
if(strcmp(htmlfiletags[n],tags[j])==0)
{
printf("\t%d\n", howmanytimesnot);
++howmanytimesnot;
}
}
printf("\tcheck__3/3\n");
if(!(howmanytimesnot<sizeof(tags)))
{
printf("\tcheck__3/4\n");
printf("the file is not wellformed");
exit (1);
}
}
Thanks for all reply!!
G
Your code is very complicated, it has several issues.
Here's one:
for(j=0; j<sizeof(tags); ++j)
this will not do what I believe you expect; sizeof(tags) is not the array length of tags (which is declared as char tags[189][30];), it's the total size of the variable. So, this loop will go from 0 to 189 * 30 - 1, i.e. 5669, and thus index way out beyond the end of array.
Also, the idea to use sizeof here in any way is wrong, since the content of tags comes from a file and it thus impossible for the compiler to know. Remember that sizeof is evaluated at compile-time, for expressions like these.
You need to have a variable (e.g. size_t num_tags) that you increment for each line parsed from the tags file, and that you later use to iterate over tags.
Do not use regex, or some kind of string parsing, to parse HTML. Instead search the web, or this site, for a c library to parse html. Then check the parsed HTML file for the tags. This will ease the development a lot as you don't have to parse the files yourself.
i've fixed some things, but
- i still cant check the file's htmltags, dies at the same loop, i've fixed allocation of the tags array
- when in the htmlfile are 2 or more different comments and i'm replacing the comment the program replaces it with the sysdate, but the program copy the another comments badly, like =>
the code is now:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#define MAX_SIZE 512
void menu();
void check();
void datumos();
int main(int argc,char *argv[])
{
menu();
return 0;
}
void menu()
{
char menu[MAX_SIZE];
while(1 < 2)
{
printf("\npress a button:\n\n");
printf("\tFile HTML check..............:c\n");
printf("\t<!--#echo var="date" -->...........:d\n");
printf("\tExit:\tCTRL + C\n");
scanf("%s",menu);
if( strcmp(menu,"c") == 0 )
{
check();
}
else if( strcmp(menu,"d") == 0 )
{
datumos();
}
}
}
void check()
{
FILE *htmlfile;
FILE *checkfile;
htmlfile = fopen("htmlfile.html","r");
checkfile = fopen("tags.txt","r");
char line[MAX_SIZE];
char htmlline[MAX_SIZE];
int i2=0;
printf("\tcheck__1\n");
while(fgets(line,sizeof(line),checkfile) != NULL)
{
++i2;
}
char tags[i2][20];
int i=0;
printf("\tcheck__11\n");
while(fgets(line,sizeof(line),checkfile) != NULL)
{
int j;
for(j=0; j<sizeof(line); ++j)
{
tags[i][j]=line[j];
}
++i;
}
printf("\tcheck__2\n");
int k=0; char htmlfiletags[MAX_SIZE][30];
while(fgets(htmlline,sizeof(htmlline),htmlfile) != NULL)
{
char currentline[sizeof(htmlline)];
int j=0;
if( currentline[j]=="<" )
{
while(currentline[j]!=">")
{
htmlfiletags[k][j]=currentline[j];
++j;
}
strcat(htmlfiletags[k][j+1],">");
++k;
}
}
printf("\tcheck__3\n");
int n;
for(n=0; n<sizeof(htmlfiletags); ++n)
{
int j; int howmanytimesnot=0;
for(j=0; j<sizeof(tags); ++j)
{
//printf("\tcheck__3/1\n");
if(strcmp(htmlfiletags[n],tags[j])==0)
{
// printf("\t%d\n", howmanytimesnot);
++howmanytimesnot;
}
}
printf("\tcheck__3/3\n");
if(!(howmanytimesnot<sizeof(tags)))
{
printf("\tcheck__3/4\n");
printf("the file is not wellformed");
exit (1);
}
}
printf("\tcheck__4\n");
}
void copy_file(const char *from,const char *to)
{
FILE *fr;
FILE *t;
fr = fopen(from,"r");
t = fopen(to,"w");
char line[MAX_SIZE];
char row[MAX_SIZE];
while(fgets(line,sizeof(line),fr) != NULL)
{
sscanf(line,"%s",row);
fprintf(t,"%s\n",row);
}
fclose(fr);
fclose(t);
remove("tempfile.html");
}
void datumos()
{
time_t now = time(NULL);
struct tm *t = localtime(&now);
char date_time[30];
strftime( date_time, sizeof(date_time), "%x_%X", t );
FILE *htmlfile;
FILE *tempfile;
htmlfile = fopen("htmlfile.html","r");
tempfile = fopen("tempfile.html","w");
char line[MAX_SIZE];
char* datecomment="<!--#echo var=\"date\" -->";
while(fgets(line,sizeof(line),htmlfile) != NULL)
{
int i3; int db=0;
for(i3=0; i3<strlen(datecomment); ++i3)
{
if(line[i3]==datecomment[i3])
{
++db;
}
}
if(db==strlen(datecomment))
{
char row[30];
strcpy(row,"<!--");
strcat(row, date_time);
strcat(row,"-->\n");
fputs(row,tempfile);
}
else
{
fputs(line,tempfile);
}
}
fclose(htmlfile);
fclose(tempfile);
copy_file("tempfile.html","htmlfile.html");
}
the currentline it's not necessary,and i've fixed the compares too
while(fgets(htmlline,sizeof(htmlline),htmlfile) != NULL)
{
int j=0;
if( htmlline[j]=='<' )
{
while(htmlline[j]!='>')
{
htmlfiletags[k][j]=htmlline[j];
++j;
}
strcat(htmlfiletags[k][j+1],">");
++k;
}
}
-in addition, the another problem to replace only the suitable comments, and dont hurt the different ones still dont work
"so it replaces
<!--#echo var="date" --> to the sysdate, it's ok, but when there are different comments like
<!--#include something -->, it wont be copied back well, in the htmlfile will be only <!--#include"
ideas?