--- capa/capa51/pProj/capaCgiUtils.c 1999/12/13 21:38:44 1.8 +++ capa/capa51/pProj/capaCgiUtils.c 2000/08/07 20:47:29 1.20 @@ -1,5 +1,28 @@ +/* Most of the web output generation routines. + Copyright (C) 1992-2000 Michigan State University + + The CAPA system is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The CAPA system is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with the CAPA system; see the file COPYING. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + As a special exception, you have permission to link this program + with the TtH/TtM library and distribute executables, as long as you + follow the requirements of the GNU GPL in regard to all of the + software in the executable aside from TtH/TtM. +*/ + /* ===================================================================== */ -/* copyrighted by Isaac Tsai, 1998, 1999, 2000 */ /* ===================================================================== */ #include #include @@ -229,14 +252,6 @@ void web_printheader(FILE *out) fprintf(out,"\n"); fprintf(out,"\n"); } - -#ifdef CAPA_WEB - fprintf(out,"\n", - CAPA_VER,COMPILE_DATE); -#else - fprintf(out,"\n", - CAPA_VER,COMPILE_DATE); -#endif } void web_printfooter(FILE *out) @@ -425,6 +440,7 @@ void w_get_responses(int x,int q_idx,cha sa_p->a_idx = sub_idx; sa_p->a_str = strsave(g_entries[x].val); sa_p->a_next = NULL; + trim_response_ws(sa_p->a_str); if( g_stu_ans_pp[q_idx] == NULL ) { g_stu_ans_pp[q_idx] = sa_p; } else { @@ -789,6 +805,42 @@ and have entered you student id correctl return (error); } +void append_qtext_addbr(new_str) char *new_str; +{ + int ii,jj,len; + char *br_added; + if (new_str==NULL) return; + len=strlen(new_str); + br_added=capa_malloc(len*5,sizeof(char)); + for (ii=0,jj=0;iig_qsize-1) { + if (g_qchar_cnt+len>g_qsize-3) { char *temp_text; g_qsize=(g_qchar_cnt+len)*2; temp_text=capa_malloc(g_qsize,sizeof(char)); strncpy(temp_text,g_question_txt,g_qchar_cnt); + temp_text[g_qchar_cnt]='\0'; capa_mfree(g_question_txt); g_question_txt=temp_text; + /* + g_qsize=(g_qchar_cnt+len)*2; + g_question_txt=realloc(g_question_txt,g_qsize); + */ } for(ii=0;iig_ssize-1) { + if (g_schar_cnt+len>g_ssize-2) { char *temp_text; g_ssize=(g_schar_cnt+len)*2; temp_text=capa_malloc(g_ssize,sizeof(char)); @@ -1062,6 +1119,8 @@ print_page_header(mode,num_quest) int mo char *serverName; int configResult,term_summary_button=1; + buf[0]='\0'; + discussdir[0]='\0'; serverName=getenv("SERVER_NAME"); if (!serverName) { fprintf(stdout,"Enviroment variable SERVER_NAME not set.\n"); @@ -1300,6 +1359,7 @@ char *class_dir; char *c_owner;char *cla char cmp_ans[MAX_BUFFER_SIZE],date_str[DATE_BUFFER]; time_t curtime; char *serverName; + char *c_ans; serverName=getenv("SERVER_NAME"); if (!serverName) { @@ -1376,7 +1436,7 @@ char *class_dir; char *c_owner;char *cla } } - if ((mode==CHECK_ANSWER_MODE) || (mode== TRY_SET_MODE)) + if ((mode==CHECK_ANSWER_MODE) || (mode== TRY_SET_MODE) || (mode==VIEW_PREVIOUS_MODE)) capa_set_login_time(g_student_number,set); capa_get_header(&header,set); @@ -1405,7 +1465,7 @@ char *class_dir; char *c_owner;char *cla if ( result != 0 ) { if( !g_passdue ) { - append_qtext("
",serverName, g_cgibin_path,c_owner); append_qtext(buf); @@ -1450,10 +1510,12 @@ char *class_dir; char *c_owner;char *cla if ( !prob_idx->show_br ) { append_qtext(prob_idx->question); } else { + append_qtext_addbr(prob_idx->question); + /* for(idx=0;idx= g_qsize ) { + if ( g_qchar_cnt+2 > g_qsize-2 ) { char *temp_text; - g_qsize=g_qchar_cnt*2; + g_qsize=(g_qchar_cnt+2)*2; temp_text=capa_malloc(g_qsize,sizeof(char)); strncpy(temp_text,g_question_txt,g_qsize); capa_mfree(g_question_txt); @@ -1465,30 +1527,43 @@ char *class_dir; char *c_owner;char *cla append_qtext("
\n"); } } + */ } } } if(mode == VIEW_PREVIOUS_MODE) { /* VIEW_PREVIOUS_MODE */ - if( display_ans ) { + /* if( prob_idx->ans_type == ANSWER_IS_FLOAT ) { a = (double)atof(prob_idx->answer); sprintf(cmp_ans,prob_idx->ans_fmt, a); } else { - strcpy(cmp_ans,prob_idx->answer); + if ( prob_idx->ans_type == ANSWER_IS_SUBJECTIVE) { + strcpy(cmp_ans,"Subjective Answer"); + } else { + if (prob_idx->answer) { + strcpy(cmp_ans,prob_idx->answer); + } else { + strcpy(cmp_ans,"No Answer"); + } + } } if( prob_idx->ans_unit ) { sprintf(buf,"

Answer: %s %s
\n",cmp_ans, prob_idx->unit_str); } else { sprintf(buf,"

Answer: %s
\n",cmp_ans); } + */ + if( display_ans ) { + c_ans=answers_string(ANSWER_STRING_MODE, prob_idx); + sprintf(buf,"

Answer: %s
",c_ans); append_qtext(buf); + capa_mfree(c_ans); if ( prob_idx->explain) { sprintf(buf,"

Explanation: \n

%s
\n",prob_idx->explain); append_qtext(buf); } - } - } else { /* could be TRY_SET_MODE, CHECK_ANSWER_MODE */ - + } + } else { /* could be TRY_SET_MODE, CHECK_ANSWER_MODE */ if( g_passdue ) { get_response(header.partial_credit[question_idx],entry.answers[question_idx],question_idx,prob_idx); }else{ @@ -1512,7 +1587,7 @@ char *class_dir; char *c_owner;char *cla append_qtext("\n\n"); if( EndText_p ) append_qtext(EndText_p); free_problems(first_prob); - + free_units(); #ifdef CGI_DBUG fprintf(g_cgi,"End display each problem\n"); fflush(g_cgi); #endif /* CGI_DBUG */ @@ -1895,7 +1970,7 @@ int gather_answers(char ***ans,int q_idx int cnt; if(p->ans_op==ANS_AND) { int i; StudentAnswer_t *sa_p; - *ans=(char**)capa_malloc(p->ans_cnt,1); + *ans=(char**)capa_malloc(p->ans_cnt,sizeof(char*)); sa_p= g_stu_ans_pp[q_idx+1]; for(i=0;((ians_cnt)&&(sa_p));i++){ ans[0][i]=sa_p->a_str; @@ -1905,7 +1980,7 @@ int gather_answers(char ***ans,int q_idx cnt=p->ans_cnt; if (ians_cnt) return -1; } else { - *ans=(char**)capa_malloc(p->ans_cnt,1); + *ans=(char**)capa_malloc(p->ans_cnt,sizeof(char*)); ans[0][0]=g_stu_ans_pp[q_idx+1]->a_str; if ((strlen(ans[0][0])+1) > ANSWER_STRING_LENG) ans[0][0][ANSWER_STRING_LENG]='\0'; cnt=1; @@ -1918,21 +1993,23 @@ void log_user_ans(int q_idx,Problem_t *p) { char **ans; + char *error; int cnt; if (p->ans_type==ANSWER_IS_SUBJECTIVE) { /*capa_set_subjective(g_login_set,q_idx+1,g_student_number, g_stu_ans_pp[q_idx+1]->a_str);*/ } else { if (-1 != (cnt=gather_answers(&ans,q_idx,p))) { - switch( capa_check_answers(p,ans,cnt) ) { + switch( capa_check_answers(p,ans,cnt,&error) ) { case EXACT_ANS: g_log_string[q_idx]='Y'; break; case APPROX_ANS: g_log_string[q_idx]='Y'; break; - case SIG_FAIL: g_log_string[q_idx]='S'; break; - case UNIT_FAIL: g_log_string[q_idx]='U'; break; - case UNIT_NOTNEEDED: g_log_string[q_idx]='U'; break; + case SIG_FAIL: g_log_string[q_idx]='S'; capa_mfree(error); break; + case UNIT_FAIL: g_log_string[q_idx]='U'; capa_mfree(error); break; + case UNIT_NOTNEEDED: g_log_string[q_idx]='U'; capa_mfree(error); break; case NO_UNIT: g_log_string[q_idx]='u'; break; case BAD_FORMULA: g_log_string[q_idx]='F'; break; case INCORRECT: g_log_string[q_idx]='N'; break; + case WANTED_NUMERIC: g_log_string[q_idx]='s'; break; } } } @@ -1977,7 +2054,8 @@ int sig_u; char *a_fmt; int tries; char buf[MAX_BUFFER_SIZE]; - + char *error; + a_tpe = p->ans_type; t_tpe = p->tol_type; tol = p->tolerance; @@ -2014,7 +2092,7 @@ int tries; return; } - switch( capa_check_answers(p,ans,cnt) ) { + switch( capa_check_answers(p,ans,cnt,&error) ) { case EXACT_ANS: case APPROX_ANS: c_ans=answers_string(ANSWER_STRING_MODE, p); @@ -2024,18 +2102,28 @@ int tries; g_log_string[q_idx]='Y'; capa_mfree(c_ans); break; + case WANTED_NUMERIC: + create_answer_area(p,q_idx); + g_tried[q_idx]--; /* don't count as a try */ + sprintf(buf,"
This question expects a numeric answer, tries %d/%d.\n",g_tried[q_idx],tries); + append_qtext(buf); + g_new_answerdb[q_idx] = 'N'; + g_log_string[q_idx]='s'; + break; case SIG_FAIL: create_answer_area(p,q_idx); g_tried[q_idx]--; /* don't count as a try */ - sprintf(buf,"
Please adjust significant figures, tries %d/%d.\n",g_tried[q_idx],tries); + sprintf(buf,"
Please adjust significant figures, you provided %s significant figures, tries %d/%d.\n",error,g_tried[q_idx],tries); append_qtext(buf); + capa_mfree(error); g_new_answerdb[q_idx] = 'N'; g_log_string[q_idx]='S'; break; case UNIT_FAIL: create_answer_area(p,q_idx); g_tried[q_idx]--; /* don't count as a try */ - sprintf(buf,"
Units incorrect, tries %d/%d.\n",g_tried[q_idx],tries); + sprintf(buf,"
Units incorrect, Computer reads units as %s, tries %d/%d.\n",error,g_tried[q_idx],tries); + capa_mfree(error); append_qtext(buf); g_new_answerdb[q_idx] = 'N'; g_log_string[q_idx]='U'; @@ -2044,9 +2132,10 @@ int tries; create_answer_area(p,q_idx); g_tried[q_idx]--; /* don't count as a try */ if(tries > 0) { - sprintf(buf,"
Only a number required, tries %d/%d.\n",g_tried[q_idx],tries); + sprintf(buf,"
Only a number required, Computer reads units of %s, tries %d/%d.\n",error,g_tried[q_idx],tries); append_qtext(buf); } + capa_mfree(error); g_new_answerdb[q_idx] = 'N'; g_log_string[q_idx]='U'; break; @@ -2097,7 +2186,8 @@ int sig_u; char *a_fmt; int tries; char buf[MAX_BUFFER_SIZE]; - + char *error; + a_tpe = p->ans_type; c_ans = p->answer; t_tpe = p->tol_type; @@ -2136,23 +2226,30 @@ int tries; return; } - switch( capa_check_answers(p,ans,cnt) ) { + switch( capa_check_answers(p,ans,cnt,&error) ) { case EXACT_ANS: case APPROX_ANS: g_new_answerdb[q_idx] = 'Y'; g_log_string[q_idx]='Y'; break; + case WANTED_NUMERIC: + g_new_answerdb[q_idx] = 'N'; + g_log_string[q_idx]='s'; + break; case SIG_FAIL: g_new_answerdb[q_idx] = 'N'; g_log_string[q_idx]='S'; + capa_mfree(error); break; case UNIT_FAIL: g_new_answerdb[q_idx] = 'N'; g_log_string[q_idx]='U'; + capa_mfree(error); break; case UNIT_NOTNEEDED: g_new_answerdb[q_idx] = 'N'; g_log_string[q_idx]='U'; + capa_mfree(error); break; case NO_UNIT: g_new_answerdb[q_idx] = 'N'; @@ -2597,7 +2694,7 @@ FILE *out; fprintf(out,"

\n"); - fprintf(out,"\n",capa_server,width,height); + fprintf(out,"\n",capa_server,width,height); fprintf(out,"\n", hw_w); fprintf(out,"\n", qz_w); fprintf(out,"\n", ex_w); @@ -2641,7 +2738,7 @@ FILE *out; capa_mfree((char *)capa_server); } -int +void get_tscore_width_height(width,height) int *width;int *height; { @@ -2677,7 +2774,7 @@ int *hc;int *qc;int *fs; configResult=read_capa_config("homework_weight",buf); if (configResult != 0 && configResult != -1 ) { sscanf(buf,"%f", &hw_w); - if(hw_w <= 0.0 ) { + if(hw_w < 0.0 ) { hw_w = DEFAULT_HW_W; } } else { @@ -2686,7 +2783,7 @@ int *hc;int *qc;int *fs; configResult=read_capa_config("quiz_weight",buf); if (configResult != 0 && configResult != -1 ) { sscanf(buf,"%f", &qz_w); - if(qz_w <= 0.0 ) { + if(qz_w < 0.0 ) { qz_w = DEFAULT_QZ_W; } } else { @@ -2695,7 +2792,7 @@ int *hc;int *qc;int *fs; configResult=read_capa_config("exam_weight",buf); if (configResult != 0 && configResult != -1 ) { sscanf(buf,"%f", &ex_w); - if(ex_w <= 0.0 ) { + if(ex_w < 0.0 ) { ex_w = DEFAULT_EX_W; } } else { @@ -2704,7 +2801,7 @@ int *hc;int *qc;int *fs; configResult=read_capa_config("final_weight",buf); if (configResult != 0 && configResult != -1 ) { sscanf(buf,"%f", &fe_w); - if(fe_w <= 0.0 ) { + if(fe_w < 0.0 ) { fe_w = DEFAULT_FE_W; } } else { @@ -2713,7 +2810,7 @@ int *hc;int *qc;int *fs; configResult=read_capa_config("correction_weight",buf); if (configResult != 0 && configResult != -1 ) { sscanf(buf,"%f", &pc_w); - if(pc_w <= 0.0 ) { + if(pc_w < 0.0 ) { pc_w = DEFAULT_PC_W; } } else {