/* =||>|===================== capaCommon.c =====================|<||= */
/* created 1994 by Isaac Tsai */
/* 1994, 1995, 1996, 1997, 1998, 1999 copyrighted by Isaac Tsai */
/* TODO: restructure capa_check_ans*() calls into one */
/* =||>|===================== capaCommon.c =====================|<||= */
#include <ctype.h>
#if defined(__sun) || defined(linux) || defined(__alpha) || defined(hpux) || defined(AIX) || defined(IRIX)
#include <unistd.h> /* lockf() */
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "capaParser.h"
#include "capaToken.h"
#include "capaCommon.h"
#include "ranlib.h"
/*----------------------------------------------------------*/
/* flock() in SUN is in BSD compatibility lib */
/* #include <sys/file.h> */
/*----------------------------------------------------------*/
char Parse_class[QUARTER_K];
int Parse_set;
int Parse_section;
char Parse_student_number[MAX_STUDENT_NUMBER+1];
char Parse_name[MAX_NAME_CHAR+1];
long capaid_plus_gen;
int managermode;
int yyparse();
int yylex();
extern FILE *yyin;
extern void yyrestart();
/*----------------------------------------------------------*/
/* Lock file shared */
/* lock the file specified by file stream pointer sp */
/*----------------------------------------------------------*/
int
flockstream_sh(sp) FILE *sp;
{
int fd;
fd = fileno(sp);
#if defined(__sun) || defined(hpux) || defined(AIX)
return ( lockf(fd,F_LOCK, 0L) );
#else
return (flock(fd,LOCK_SH));
#endif
}
/*----------------------------------------------------------*/
int
flockstream(sp) FILE *sp;
{
int fd;
fd = fileno(sp);
#if defined(__sun) || defined(hpux) || defined(AIX)
return ( lockf(fd,F_LOCK, 0L) );
#else
return (flock(fd,LOCK_EX));
#endif
}
/*----------------------------------------------------------*/
int
funlockstream(sp) FILE *sp;
{
int fd;
fd = fileno(sp);
#if defined(__sun) || defined(hpux) || defined(AIX)
return ( lockf(fd,F_ULOCK, 0L) );
#else
return ( flock(fd,LOCK_UN) );
#endif
}
int
inquery_a_lock(sp,cmd,type,offset,whence,len)
FILE *sp;int cmd;off_t offset;int whence;off_t len;
{
struct flock lock;
int fd;
lock.l_type = type; lock.l_start = offset;
lock.l_whence = whence; lock.l_len = len;
fd=fileno(sp);
return (fcntl(fd,cmd,&lock));
}
#define Blocked_Write_Lock(sp) \
inquery_a_lock(sp,F_SETLK,F_WRLCK,0,0,0)
#define Blocked_Write_Lock(sp) \
inquery_a_lock(sp,F_SETLK,F_WRLCK,0,0,0)
#define Un_Lock(sp) \
inquery_a_lock(sp,F_SETLK,F_UNLCK,0,0,0)
/******************************************************************************/
/* PARSE SOURCE FILE AND RETURN BLOCKS OF TEXT, unlike capa_parse_student */
/******************************************************************************/
int
capa_parse(set,problem,filename,num_questions,func_ptr)
int set;Problem_t **problem;char *filename;int *num_questions;
void (*func_ptr)();
{
int errcode,temp;
extern FILE *Input_stream[MAX_OPENED_FILE];
extern char Opened_filename[MAX_OPENED_FILE][QUARTER_K];
extern int Lexi_line;
extern int Lexi_qnum;
extern Problem_t *FirstProblem_p;
extern Problem_t *LastProblem_p;
extern Problem_t *LexiProblem_p;
extern char *StartText_p;
extern char *EndText_p;
extern char *ErrorMsg_p;
extern int ErrorMsg_count;
extern int Symb_count;
extern int first_run;
extern void (*Status_Func)();
char warn_msg[WARN_MSG_LENGTH];
if(ErrorMsg_p) { capa_mfree(ErrorMsg_p); ErrorMsg_p = NULL; }
if(EndText_p) { capa_mfree(EndText_p); EndText_p = NULL; }
if(StartText_p) { capa_mfree(StartText_p); StartText_p = NULL; }
ErrorMsg_p = NULL; first_run = 1; EndText_p = NULL;
Symb_count = ErrorMsg_count = Lexi_line = Lexi_qnum = 0;
FirstProblem_p = LastProblem_p = NULL;
LexiProblem_p = (Problem_t *)capa_malloc(sizeof(Problem_t),1);
Status_Func=func_ptr;
#ifdef AVOIDYYINPUT
yyin=fopen(filename,"r");
#else
if ( (Input_stream[0]=fopen(filename,"r")) == NULL) {
/* printf("Error: can't open %s\n",filename);*/
sprintf(warn_msg,"capa_parse(): CANNOT OPEN FILE\"%s\", file does not exist or is not readable.\n", filename);
capa_msg(MESSAGE_ERROR,warn_msg);
return (-1);
}
#endif
sprintf(Opened_filename[0],"%s",filename);
/*yyrestart(yyin);*/
begin_text();
/*if ( !yyparse() ) { errcode = Lexi_qnum; } else { errcode = 0; }*/
if (!(temp=yylex())) { errcode = Lexi_qnum; } else { errcode = 0; }
/* printf("\nExited on: %d\n",temp); */
/* printf("Flushing:\n"); */
flush_delayed();
/* fclose(Input_stream[0]);*/ /*The Lexer handles closing this*/
/* print_symb_stat(); */
/*
capa_mfree((char *)LexiProblem_p);
LexiProblem_p = NULL;
*/
(*problem) = FirstProblem_p;
(*num_questions) = Lexi_qnum;
return (errcode);
}
int dyn_maxlen=1000000;
int delay;
void dyn_init()
{
dyn_delayed.len=0;
dyn_delayed.max=0;
dyn_delayed.str=NULL;
}
/* this can be used to free up the str components if the output
compenants are used internally, as in the reinit code
*/
void dyn_free()
{
if (dyn_delayed.str) {free(dyn_delayed.str);dyn_delayed.str=NULL;}
}
int append_message(struct dyn_string *dyn_msg,char *format,va_list ap) {
char *new;
int len,result;
result=vasprintf(&new,format,ap);
len=strlen(new);
#ifdef DYN_DEBUG
fprintf(stderr,"before: len %d; gcount %d; max %d\n",
len,dyn_msg->len,dyn_msg->max);
#endif /* DYN_DEBUG */
if (dyn_msg->len+len < dyn_maxlen) {
if (dyn_msg->len+len>dyn_msg->max-2) {
dyn_msg->max=(dyn_msg->len+len)*2;
if (dyn_msg->max>dyn_maxlen) { dyn_msg->max=dyn_maxlen; }
if (dyn_msg->max != 0) {
dyn_msg->str=realloc(dyn_msg->str,dyn_msg->max);
} else {
return 1;
}
dyn_msg->str[dyn_msg->len]='\0';
}
strcat(dyn_msg->str,new);
dyn_msg->len+=len;
} else {
if (dyn_msg->max != dyn_maxlen-1) { /*already maxed out or can
we fit this one in?*/
dyn_msg->max=dyn_maxlen;
dyn_msg->str=realloc(dyn_msg->str,dyn_msg->max);
dyn_msg->str[dyn_msg->len]='\0';
strncat(dyn_msg->str,new,dyn_msg->max-dyn_msg->len-1);
dyn_msg->len=strlen(dyn_msg->str);
}
}
free(new);
#ifdef DYN_DEBUG
fprintf(stderr,"after: len %d; gcount %d; max %d; strlen(dyn_msg): %d\n",
len,dyn_msg->len,dyn_msg->max,strlen(dyn_msg->str));
#endif /* DYN_DEBUG */
return 1;
}
void start_delayed(){ delay=1; }
void end_delayed(){ delay=0; }
void add_delayed(char *format, ...) {
va_list ap;
va_start(ap,format);
append_message(&dyn_delayed,format,ap);
}
void flush_delayed()
{
if (dyn_delayed.str) fputs(dyn_delayed.str,stdout);
dyn_free();dyn_init();
delay=0;
}
void send(char *text,...)
{
va_list ap;
va_start(ap,text);
if (delay) {
append_message(&dyn_delayed,text,ap);
} else {
vprintf(text,ap);
}
}
void end_mode()
{
switch (mode) {
case MODE_COMMENT: send("</comment>\n"); break;
case MODE_BLOCK: send("</block>\n"); break;
case MODE_SCRIPT: send("</script>\n"); break;
case MODE_OUTTEXT: send("<endouttext />\n"); break;
case MODE_ANSWER: send("\n"); break;
case MODE_HINT: send("<endouttext />\n</hintpart>\n</hintgroup>\n"); break;
case MODE_NONE: break;
}
mode=MODE_NONE;
}
void start_mode(int newmode,char* args)
{
if (newmode == mode) return;
end_mode();
switch (newmode) {
case MODE_COMMENT: send("<comment>\n"); break;
case MODE_BLOCK: send("<block %s>\n",args); break;
case MODE_SCRIPT: send("<script type=\"loncapa/perl\">\n"); break;
case MODE_OUTTEXT: send("<startouttext />\n"); break;
case MODE_ANSWER: send("\n"); break;
case MODE_HINT: send("<hintgroup>\n<hintpart on=\"default\">\n<startouttext />\n"); break;
case MODE_NONE: break;
}
mode=newmode;
}
/* =||>|===================== End of capaCommon.c =====================|<||= */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>