/* =||>|===================== 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 #if defined(__sun) || defined(linux) || defined(__alpha) || defined(hpux) || defined(AIX) || defined(IRIX) #include /* lockf() */ #endif #include #include #include #include "capaParser.h" #include "capaToken.h" #include "capaCommon.h" #include "ranlib.h" /*----------------------------------------------------------*/ /* flock() in SUN is in BSD compatibility lib */ /* #include */ /*----------------------------------------------------------*/ 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("\n"); break; case MODE_BLOCK: send("\n"); break; case MODE_SCRIPT: send("\n"); break; case MODE_OUTTEXT: send("\n"); break; case MODE_ANSWER: send("\n"); break; case MODE_HINT: send("\n\n\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("\n"); break; case MODE_BLOCK: send("\n",args); break; case MODE_SCRIPT: send("