Annotation of loncom/homework/CAPA-converter/capaCommon.c, revision 1.8
1.1 albertel 1: /* =||>|===================== capaCommon.c =====================|<||= */
2: /* created 1994 by Isaac Tsai */
3: /* 1994, 1995, 1996, 1997, 1998, 1999 copyrighted by Isaac Tsai */
4: /* TODO: restructure capa_check_ans*() calls into one */
5: /* =||>|===================== capaCommon.c =====================|<||= */
6: #include <ctype.h>
7: #if defined(__sun) || defined(linux) || defined(__alpha) || defined(hpux) || defined(AIX) || defined(IRIX)
8: #include <unistd.h> /* lockf() */
9: #endif
10: #include <sys/types.h>
11: #include <sys/stat.h>
12: #include <fcntl.h>
13: #include "capaParser.h"
14: #include "capaToken.h"
15: #include "capaCommon.h"
16: #include "ranlib.h"
17:
18:
19: /*----------------------------------------------------------*/
20: /* flock() in SUN is in BSD compatibility lib */
21: /* #include <sys/file.h> */
22: /*----------------------------------------------------------*/
23: char Parse_class[QUARTER_K];
24: int Parse_set;
25: int Parse_section;
26: char Parse_student_number[MAX_STUDENT_NUMBER+1];
27: char Parse_name[MAX_NAME_CHAR+1];
28: long capaid_plus_gen;
29: int managermode;
30:
31: int yyparse();
32: int yylex();
33: extern FILE *yyin;
34: extern void yyrestart();
35:
36:
37: /*----------------------------------------------------------*/
38: /* Lock file shared */
39: /* lock the file specified by file stream pointer sp */
40: /*----------------------------------------------------------*/
41: int
42: flockstream_sh(sp) FILE *sp;
43: {
44: int fd;
45:
46: fd = fileno(sp);
47:
48: #if defined(__sun) || defined(hpux) || defined(AIX)
49: return ( lockf(fd,F_LOCK, 0L) );
50: #else
51: return (flock(fd,LOCK_SH));
52: #endif
53: }
54: /*----------------------------------------------------------*/
55: int
56: flockstream(sp) FILE *sp;
57: {
58: int fd;
59:
60: fd = fileno(sp);
61:
62: #if defined(__sun) || defined(hpux) || defined(AIX)
63: return ( lockf(fd,F_LOCK, 0L) );
64: #else
65: return (flock(fd,LOCK_EX));
66: #endif
67: }
68: /*----------------------------------------------------------*/
69: int
70: funlockstream(sp) FILE *sp;
71: {
72: int fd;
73:
74: fd = fileno(sp);
75:
76: #if defined(__sun) || defined(hpux) || defined(AIX)
77: return ( lockf(fd,F_ULOCK, 0L) );
78: #else
79: return ( flock(fd,LOCK_UN) );
80: #endif
81: }
82:
83: int
84: inquery_a_lock(sp,cmd,type,offset,whence,len)
85: FILE *sp;int cmd;off_t offset;int whence;off_t len;
86: {
87: struct flock lock;
88: int fd;
89: lock.l_type = type; lock.l_start = offset;
90: lock.l_whence = whence; lock.l_len = len;
91: fd=fileno(sp);
92: return (fcntl(fd,cmd,&lock));
93: }
94: #define Blocked_Write_Lock(sp) \
95: inquery_a_lock(sp,F_SETLK,F_WRLCK,0,0,0)
96:
97: #define Blocked_Write_Lock(sp) \
98: inquery_a_lock(sp,F_SETLK,F_WRLCK,0,0,0)
99:
100: #define Un_Lock(sp) \
101: inquery_a_lock(sp,F_SETLK,F_UNLCK,0,0,0)
102:
103:
104:
105:
106: /******************************************************************************/
107: /* PARSE SOURCE FILE AND RETURN BLOCKS OF TEXT, unlike capa_parse_student */
108: /******************************************************************************/
109: int
110: capa_parse(set,problem,filename,num_questions,func_ptr)
111: int set;Problem_t **problem;char *filename;int *num_questions;
112: void (*func_ptr)();
113: {
1.3 albertel 114: int errcode,temp;
1.1 albertel 115: extern FILE *Input_stream[MAX_OPENED_FILE];
116: extern char Opened_filename[MAX_OPENED_FILE][QUARTER_K];
117: extern int Lexi_line;
118: extern int Lexi_qnum;
119: extern Problem_t *FirstProblem_p;
120: extern Problem_t *LastProblem_p;
121: extern Problem_t *LexiProblem_p;
122: extern char *StartText_p;
123: extern char *EndText_p;
124: extern char *ErrorMsg_p;
125: extern int ErrorMsg_count;
126: extern int Symb_count;
127: extern int first_run;
128: extern void (*Status_Func)();
129: char warn_msg[WARN_MSG_LENGTH];
130:
131: if(ErrorMsg_p) { capa_mfree(ErrorMsg_p); ErrorMsg_p = NULL; }
132: if(EndText_p) { capa_mfree(EndText_p); EndText_p = NULL; }
133: if(StartText_p) { capa_mfree(StartText_p); StartText_p = NULL; }
134: ErrorMsg_p = NULL; first_run = 1; EndText_p = NULL;
135: Symb_count = ErrorMsg_count = Lexi_line = Lexi_qnum = 0;
136: FirstProblem_p = LastProblem_p = NULL;
137: LexiProblem_p = (Problem_t *)capa_malloc(sizeof(Problem_t),1);
138: Status_Func=func_ptr;
139:
140: #ifdef AVOIDYYINPUT
141: yyin=fopen(filename,"r");
142: #else
143: if ( (Input_stream[0]=fopen(filename,"r")) == NULL) {
144: /* printf("Error: can't open %s\n",filename);*/
145: sprintf(warn_msg,"capa_parse(): CANNOT OPEN FILE\"%s\", file does not exist or is not readable.\n", filename);
146: capa_msg(MESSAGE_ERROR,warn_msg);
147: return (-1);
148: }
149: #endif
150: sprintf(Opened_filename[0],"%s",filename);
151:
152: /*yyrestart(yyin);*/
153: begin_text();
154: /*if ( !yyparse() ) { errcode = Lexi_qnum; } else { errcode = 0; }*/
1.3 albertel 155: if (!(temp=yylex())) { errcode = Lexi_qnum; } else { errcode = 0; }
1.8 ! albertel 156: /* printf("\nExited on: %d\n",temp); */
! 157: /* printf("Flushing:\n"); */
1.3 albertel 158: flush_delayed();
1.1 albertel 159: /* fclose(Input_stream[0]);*/ /*The Lexer handles closing this*/
160: /* print_symb_stat(); */
161: /*
162: capa_mfree((char *)LexiProblem_p);
163: LexiProblem_p = NULL;
164: */
165: (*problem) = FirstProblem_p;
166: (*num_questions) = Lexi_qnum;
167: return (errcode);
168: }
169:
1.3 albertel 170: int dyn_maxlen=1000000;
171: int delay;
172: void dyn_init()
173: {
174: dyn_delayed.len=0;
175: dyn_delayed.max=0;
176: dyn_delayed.str=NULL;
177: }
178:
179: /* this can be used to free up the str components if the output
180: compenants are used internally, as in the reinit code
181: */
182: void dyn_free()
183: {
184: if (dyn_delayed.str) {free(dyn_delayed.str);dyn_delayed.str=NULL;}
185: }
186:
187: int append_message(struct dyn_string *dyn_msg,char *format,va_list ap) {
188: char *new;
189: int len,result;
190:
191: result=vasprintf(&new,format,ap);
192: len=strlen(new);
193:
194: #ifdef DYN_DEBUG
195: fprintf(stderr,"before: len %d; gcount %d; max %d\n",
196: len,dyn_msg->len,dyn_msg->max);
197: #endif /* DYN_DEBUG */
198:
199: if (dyn_msg->len+len < dyn_maxlen) {
200: if (dyn_msg->len+len>dyn_msg->max-2) {
201: dyn_msg->max=(dyn_msg->len+len)*2;
202: if (dyn_msg->max>dyn_maxlen) { dyn_msg->max=dyn_maxlen; }
203: if (dyn_msg->max != 0) {
204: dyn_msg->str=realloc(dyn_msg->str,dyn_msg->max);
205: } else {
206: return 1;
207: }
208: dyn_msg->str[dyn_msg->len]='\0';
209: }
210: strcat(dyn_msg->str,new);
211: dyn_msg->len+=len;
212: } else {
213: if (dyn_msg->max != dyn_maxlen-1) { /*already maxed out or can
214: we fit this one in?*/
215: dyn_msg->max=dyn_maxlen;
216: dyn_msg->str=realloc(dyn_msg->str,dyn_msg->max);
217: dyn_msg->str[dyn_msg->len]='\0';
218: strncat(dyn_msg->str,new,dyn_msg->max-dyn_msg->len-1);
219: dyn_msg->len=strlen(dyn_msg->str);
220: }
221: }
222: free(new);
223:
224: #ifdef DYN_DEBUG
225: fprintf(stderr,"after: len %d; gcount %d; max %d; strlen(dyn_msg): %d\n",
226: len,dyn_msg->len,dyn_msg->max,strlen(dyn_msg->str));
227: #endif /* DYN_DEBUG */
228:
229: return 1;
230: }
231:
232: void start_delayed(){ delay=1; }
233: void end_delayed(){ delay=0; }
234:
1.4 albertel 235: void add_delayed(char *format, ...) {
1.3 albertel 236: va_list ap;
237:
238: va_start(ap,format);
239: append_message(&dyn_delayed,format,ap);
240: }
241:
242: void flush_delayed()
243: {
1.4 albertel 244: if (dyn_delayed.str) fputs(dyn_delayed.str,stdout);
1.3 albertel 245: dyn_free();dyn_init();
246: delay=0;
247: }
248:
1.2 albertel 249: void send(char *text,...)
1.1 albertel 250: {
1.2 albertel 251: va_list ap;
252: va_start(ap,text);
1.3 albertel 253: if (delay) {
254: append_message(&dyn_delayed,text,ap);
255: } else {
256: vprintf(text,ap);
257: }
1.2 albertel 258: }
259:
1.3 albertel 260: void end_mode()
1.2 albertel 261: {
1.3 albertel 262: switch (mode) {
263: case MODE_COMMENT: send("</comment>\n"); break;
264: case MODE_BLOCK: send("</block>\n"); break;
265: case MODE_SCRIPT: send("</script>\n"); break;
1.7 albertel 266: case MODE_OUTTEXT: send("<endouttext />\n"); break;
1.8 ! albertel 267: case MODE_ANSWER: send("\n"); break;
! 268: case MODE_HINT: send("<endouttext />\n</hintpart>\n</hintgroup>\n"); break;
1.3 albertel 269: case MODE_NONE: break;
270: }
271: mode=MODE_NONE;
1.2 albertel 272: }
273:
1.3 albertel 274: void start_mode(int newmode,char* args)
1.2 albertel 275: {
1.3 albertel 276: if (newmode == mode) return;
277: end_mode();
278: switch (newmode) {
279: case MODE_COMMENT: send("<comment>\n"); break;
280: case MODE_BLOCK: send("<block %s>\n",args); break;
1.5 albertel 281: case MODE_SCRIPT: send("<script type=\"loncapa/perl\">\n"); break;
1.7 albertel 282: case MODE_OUTTEXT: send("<startouttext />\n"); break;
1.8 ! albertel 283: case MODE_ANSWER: send("\n"); break;
! 284: case MODE_HINT: send("<hintgroup>\n<hintpart on=\"default\">\n<startouttext />\n"); break;
1.3 albertel 285: case MODE_NONE: break;
286: }
287: mode=newmode;
1.1 albertel 288: }
289: /* =||>|===================== End of capaCommon.c =====================|<||= */
290:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>