Download get_new_entry.h
//Function for getting user date for new entry.
////Brian Smith 2022-04-10
/*Copyright (C) 2022 Brian R. Smith
* Contact: briansmith2865@gmail.com
**The source code in this file is free software: you can
**redistribute it and/or modify it under the terms of the GNU
**General Public License (GNU GPL) as published by the Free Software
**foundation, either version 3 of the License, or (at your option)
**any later version. The code is distributed WITHOUT ANY WARRANTY;
**without even the implied warranty of MERCHANTABILITY or FITNESS
**FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
**
**As additional permission under GNU GPL version 3 section 7, you
**may distribute non-source (e.g., minimized or compacted) forms of
**that code without the copy of the GNU GPL normally required by
**section 4, provided you include this license notice and a URL
**through which recipients can access the Corresponding Source.
**
** @licend The above is the entire license notice
**for the source code in this file.
*/
#ifndef GET_NEW_ENTRY_H
#define GET_NEW_ENTRY_H
//User data should have format 'KEYWORD: DATA'
//Commands with no data (print, cancel, clear) do not need a colon.
//command 'done' needs a colon: should be entered 'done:'
//KEYWORDS::
//done --- finished, exit func., ret_code for 'entry to be saved'.
//cancel ---- finished, exit func., ret_code for 'do not save'.
//print --- show entry.
//clear -- clear screen
//date --- command format -- 'date: yy-mm-dd'
//start --- command format -- 'start: hh:mm'
//end --- command format -- 'end:hh:mm'
//type --- sesion type after colon. Format 'type: sessiontype'
// types are 'ausk, lekt, meet, conv'. Anything else will result in NOTSET.
//with --- format: 'with: anystring'. max string length 20 bytes.
//comments --- format: 'comments: whaterveryouwant'. Max length 1024 bytes.
//
//WARNING: I'm not always checking if user data will fit in buffers :-/
#include"parse_log_entry.h"
char* EMPTY_STRING = ""; //An empty string as macro. This is sometimes needed since comments
//is a pointer to comments ... needs somewhere to point even if empty.
//Aux functions: declared here, defined after next func.
int noMatch(LOG_ENTRY* entry, LOG_INDEX* schedule_start);
int schedOverlap(LOG_ENTRY* entry, LOG_INDEX* schedule_start);
void getNewEntry (LOG_INDEX** index_start, int* NUM_ELEMS, LOG_INDEX* schedule_start) {
char ds = 0, t1 = 0, t2 = 0, cs = 0, ws = 0; //Set to 1 if, respectively,
//date is set, startime is set, endtime is set, comments are given, 'with' is set.
//Allocate a LOG_ENTRY.
LOG_ENTRY* entry = (struct LOG_ENTRY*) malloc(sizeof(struct LOG_ENTRY));
init_entry(entry); //Set all bytes to 0, sessiontype to NOTSET.
//NOTE: I should probably free this before program exit. I'm also allocating
//in insertentry().
char comments[2048]; //Buffer for comments.
memset(comments, 0, 2048); //All bytes to 0.
char buff[2048]; //Buffer for user commands.
int ret_code= 0;
char no_colon; //Record if colon was found in string.
char* keyword; //Will be pointer to keyword.
while(1) {
printf("\033[0;35m>>>>>>>>\033[0m ");
getmaline(buff);
char* rest = toColon(&no_colon, buff);
if(no_colon){
keyword = strip(buff);
if(strcmp(keyword, "print") == 0)
printEntry(entry, comments);
else if(strcmp(keyword, "cancel") == 0){
free(entry);
return;
}
else if(strcmp(keyword, "clear") == 0)
system("clear");
else
printf("Colon expected.\n");
}
else {
keyword = strip(buff);
if (strcmp(keyword, "cancel") == 0) {//Can also enter 'cancel:'
free(entry);
return;
}
else if(strcmp(keyword, "print") == 0) //Can alos enter 'print:'
printEntry(entry, comments);
else if(strcmp(keyword, "date")==0) {
if(getdate(&(entry->date), rest) != 0)
printf("INVALID DATE\n");
else {
ds = 1;
setWday(entry); //Don't forget to set day of week!
}
}
else if(strcmp(keyword, "start")==0) {
if(gettime(&(entry->startTime), rest) != 0)
printf("INVALID TIME\n");
else t1 = 1;
}
else if(strcmp(keyword, "end")==0) {
if(gettime(&(entry->endTime), rest) != 0)
printf("INVALID TIME\n");
else t2 = 1;
}
else if(strcmp(keyword, "type")==0) {
rest = strip(rest);
entry->sessiontype = fromString(rest);
}
else if (strcmp(keyword, "with") == 0) {
rest = strip(rest);
if(strlen(rest) >= 20)
printf("\033[0;31mONLY 20 BYTES ALLOWED IN FIELD.\033[0m\n");
else {
strcpy(entry->with, rest);
ws = 1;
}
}
else if (strcmp(keyword, "comments") == 0) {
rest = strip(rest);
strcpy(comments, rest);
cs = 1;
}
else if (strcmp(keyword, "done") == 0){ //Logic below may get a bit convoluted :-/
if (ds && t1 && t2 && cs && ws && cmptm(&(entry->startTime), &(entry->endTime)) < 0) {
char* new_comments = NULL;
int comm_len = strlen(comments);
if(comm_len > 0) {
new_comments = (char*)malloc(comm_len+1);
strcpy(new_comments, comments);
}
else new_comments=EMPTY_STRING;
if(entry != NULL) { //Insert new_entry in list:
if(noMatch(entry, schedule_start)){ //Check to see if entry matches
//schedule on file.
printf("\033[0;31mNO ENTRY MADE.\033[0m.\n");
}
else if(schedOverlap(entry, schedule_start)){//Check if non-scheduled
//even conflicts with schedule. schedOverlap() defined after current func.
printf("\033[0;31mNO ENTRY MADE.\033[0m\n");
}
else {
LOG_INDEX* ret_p = insertentry(index_start, entry, new_comments);
//ret_p points to overlaping entry if overlap; NULL otherwise.
if(ret_p == NULL) {
++(*NUM_ELEMS); //DON'T FORGET THIS!
printf("\033[0;32m\nNEW ENTRY INSERTED IN LIST.\033[0m\n\n");
return;
}
else {
printf("\033[0;31mOVERLAP WITH:\n");
printEntry(ret_p -> entryPtr, ret_p->comments);
}
}
}
else {
printf("\033[0;31m\nNO NEW LOG ENTRY MADE.\033[0m\n\n");
free(entry);
}
}
else {
if(cmptm(&(entry->startTime), &(entry->endTime)) >= 0)
printf("\033[0;31mEnd TIME SAME AS OR BEFORE START TIME.\033[0m\n");
else
printf("\033[0;31mSOME FIELDS HAVE NOT BEEN FILLED.\033[0m\n");
}
}
else {
printf("INVALD KEYWORD\n");
}
}
}
}
//If type is ausk or lekt checks for missmatch with schedule.
//Returns 1 if missmatch and user does not wish to proceed.
//0 otherwise.
int noMatch(LOG_ENTRY* entry, LOG_INDEX* schedule_start) {
char buff[10];
char* s;
if(entry->sessiontype != AUSK && entry->sessiontype != LEKT)
return 0;
for(LOG_INDEX* p = schedule_start; p != NULL; p = p->next) {
if(
(entry->date).wday == ((p->entryPtr)->date).wday
&& memcmp(&(entry->startTime), &((p->entryPtr)->startTime), sizeof(struct mytime)) == 0
&& memcmp(&(entry->endTime), &((p->entryPtr)->endTime), sizeof(struct mytime)) == 0
&& entry->sessiontype == (p->entryPtr)->sessiontype
&& strcmp(entry->with, (p->entryPtr)->with) == 0
) return 0;
}
printf("\033[0;31mLESSON/AUDIT: SCHEDULE MISSMATCH!!\n DO YOU WISH TO PROCEED? (y/n)\033[0m\n");
getmaline(buff); s = strip(buff);
if(strcmp(s, "y") == 0)
return 0;
return 1;
}
//Checks if non-scheduled event overlaps with schedule.
//If overlap and user does not wish to proceed returns 1.
//0 otherwise.
int schedOverlap(LOG_ENTRY* entry, LOG_INDEX* schedule_start) {
char buff[10];
char* s;
if(entry->sessiontype == LEKT || entry->sessiontype == AUSK)
return 0;
for(LOG_INDEX* p = schedule_start; p != NULL; p = p->next) {
if(overlap2(entry, p->entryPtr)) {
printf("\033[0;31mCONFLICT WITH: \n\033[0m");
printEntry(p->entryPtr, p->comments);
printf("\033[0;31mDO YOU WISH TO PROCEED? (y/n)\033[0m");
getmaline(buff); s = strip(buff);
if(strcmp(s,"y") == 0)
return 0;
return 1;
}
}
return 0;
}
#endif