示例#1
0
/* Get an integer definition. This function always return on
 * success or exits on error.
 */
int getDefine_Int(const char *high_name, const char *low_name, int min, int max)
{
    int ret;
    char *value;
    char *pt;

    /* Try to read from the local define file */
    value = _read_file(high_name, low_name, OSSEC_LDEFINES);
    if (!value) {
        value = _read_file(high_name, low_name, OSSEC_DEFINES);
        if (!value) {
            ErrorExit(DEF_NOT_FOUND, __local_name, high_name, low_name);
        }
    }

    pt = value;
    while (*pt != '\0') {
        if (!isdigit((int)*pt)) {
            ErrorExit(INV_DEF, __local_name, high_name, low_name, value);
        }
        pt++;
    }

    ret = atoi(value);
    if ((ret < min) || (ret > max)) {
        ErrorExit(INV_DEF, __local_name, high_name, low_name, value);
    }

    /* Clear memory */
    free(value);

    return (ret);
}
示例#2
0
be_node * load_be_node(char * torf, char ** file){
  char * torf_d; //stores the raw data of the torrent file
  long long torf_s;
  be_node * node; //store the top node in the bencoding of the torrent file
  torf_d = _read_file(torf,&torf_s);
  if(file!=NULL){
  	*file = _read_file(torf,&torf_s);
  }
  //printf("%s\n",torf_d );
  //printf("%s\n", *file );
  node = be_decoden(torf_d,torf_s);
  free(torf_d); //free the raw torrent file, not needed anymore

  return node;
}
示例#3
0
int threads_runnable(unsigned int *threads_running, unsigned int *threads_total)
{
    DIR             *dip;
    struct dirent   *dit;
    const char *task_path = "/proc/self/task";
    char thread_path[1024];
    char thread_data[MAX_RESULT_SIZE+1];
    char dummy[MAX_RESULT_SIZE+1];
    char state;
    int pid;
    unsigned int running_count = 0, total_count = 0;

    dbg_puts("Checking threads_runnable()");

    if ((dip = opendir(task_path)) == NULL)
    {
        dbg_perror("opendir");
        return -1;
    }
        
    while ((dit = readdir(dip)) != NULL)
    {
        memset(thread_data, 0, sizeof(thread_data));
        
        sprintf(thread_path, "%s/%s/stat",task_path, dit->d_name);

        if (_read_file(thread_path, thread_data) == 0)
        {
            if (sscanf(thread_data, "%d %s %c", &pid, dummy, &state) == 3)
            {
                total_count++;
                dbg_printf("The state for thread %s is %c", dit->d_name, state);
                switch (state)
                {
                    case 'R':
                        running_count++;
                        break;
                    default:
                        break;
                }
            }
            else
            {
                dbg_printf("Failed to scan state for thread %s (%s)", dit->d_name, thread_data);
            }
        }
    }

    if (closedir(dip) == -1)
    {
        perror("closedir");
    }

    dbg_printf("Running count is %d", running_count);
    *threads_running = running_count;
    *threads_total = total_count;
    
    return 0;
}
示例#4
0
be_node * load_be_node(char * torf){
  char * torf_d; //stores the raw data of the torrent file
  long long torf_s;//size of the torrent file
  be_node * node; //store the top node in the bencoding of the torrent file
  torf_d = _read_file(torf,&torf_s);
  node = be_decoden(torf_d,torf_s);
  free(torf_d); //free the raw torrent file, not needed anymore

  return node;
}
示例#5
0
/* Load jobcomp data from save state file */
static int _load_pending_jobs(void)
{
	int i, rc = SLURM_SUCCESS;
	char *saved_data = NULL, *state_file = NULL, *job_data = NULL;
	uint32_t data_size, job_cnt = 0, tmp32 = 0;
	Buf buffer;
	struct job_node *jnode;

	state_file = slurm_get_state_save_location();
	if (state_file == NULL) {
		error("%s: Could not retrieve StateSaveLocation from conf",
		      plugin_type);
		return SLURM_ERROR;
	}

	if (state_file[strlen(state_file) - 1] != '/')
		xstrcat(state_file, "/");
	xstrcat(state_file, save_state_file);

	slurm_mutex_lock(&save_lock);
	data_size = _read_file(state_file, &saved_data);
	if ((data_size <= 0) || (saved_data == NULL)) {
		slurm_mutex_unlock(&save_lock);
		xfree(saved_data);
		xfree(state_file);
		return rc;
	}
	slurm_mutex_unlock(&save_lock);

	buffer = create_buf(saved_data, data_size);
	safe_unpack32(&job_cnt, buffer);
	for (i = 0; i < job_cnt; i++) {
		safe_unpackstr_xmalloc(&job_data, &tmp32, buffer);
		jnode = xmalloc(sizeof(struct job_node));
		jnode->serialized_job = job_data;
		list_enqueue(jobslist, jnode);
	}
	if (job_cnt > 0) {
		if (slurm_get_debug_flags() & DEBUG_FLAG_ESEARCH)
			info("%s: Loaded %u jobs from state file", plugin_type,
			     job_cnt);
	}
	free_buf(buffer);
	xfree(state_file);

	return rc;

unpack_error:
	error("%s: Error unpacking file %s", plugin_type, state_file);
	free_buf(buffer);
	xfree(state_file);
	return SLURM_ERROR;
}
			Map(const char* fname, float real_w) :
				_real_w(real_w), _real_h(real_w) {
				try {
					//std::cout << "go";
					//_w = 0
					//_h = 0;
					_read_file(fname, false);
				} catch (Exception e) {
					std::cerr << "error : " << e.get_msg() << std::endl;
				}
				//std::cout << "_w=" << _w;
				//std::cout << "_h=" << _h;
				assert(_w == _h);
				_fx = _w / _real_w;
			}
示例#7
0
PNG::PNG(string const & file_name) 
{
_pixels = NULL; 
_read_file(file_name); 
} 
示例#8
0
bool PNG::readFromFile(string const & file_name) 
{
_clear(); 
return _read_file(file_name); } 
示例#9
0
/* parse xml file and create objects */
void* zelia_xml_parse_file(const char* xml_path, void* parser)
{
    char* _buff = NULL;					/* buffer to hold the file contents */
    size_t _sz = 0;					/* buffer file size */

    xmlDocPtr _xml_doc = NULL;				/* xml document pointer */
    xmlNodePtr _root = NULL;
    struct _zparser* obj = NULL;
    
    /* check arguments */
    ZCHECK_OBJ_INT(xml_path);
    
    if(parser == NULL)
	{
	    ZCONSTRUCTOR(obj, struct _zparser);
	}
    else
	obj = (struct _zparser*) parser;

    /* read the file */
    if(_read_file(xml_path, &_buff, &_sz) != ZELIA_OK)
	return NULL;


    /* initialise object array */
    blist_new(&obj->object_array, _delete_helper);

    if(!zfile_new(&obj->file))
	return NULL;

    /* toggle the force overwrite mode */
    zfile_toggle_overwrite(&obj->file);

    /* parse the document */
    xmlInitParser();

    _xml_doc = xmlParseMemory(_buff, _sz);

    if(_xml_doc == NULL)
	{
	    ZELIA_LOG_MESSAGE("zelia_xml unable to parse the document");
	    goto clean_up;
	}

    _root = xmlDocGetRootElement(_xml_doc);

    _main_loop(xmlFirstElementChild(_root), obj);
    
    xmlFreeDoc(_xml_doc);
    xmlCleanupParser();

 clean_up:

    if(_buff != NULL && _sz > 0)
	free(_buff);
    _buff = NULL;
    _sz = 0;
    
    if(ZDESTRUCTOR_CHECK)
	{
	    _finalise_parser(obj);
	    free(obj);
	}
    else
	return obj;
    
    return NULL;
}
			void terrain_switch(const std::string &fname) {
				_read_file(fname, false);
			}
			void terrain_switch_only_obstacles(const std::string &fname) {
				_read_file(fname, true);
						}
示例#12
0
int NDOStreamMsg::FromFile(const char *file)
{
	Reset();
	return _read_file(file, _packet);
}
示例#13
0
//-----------------------------------------------------------------------------
// fopen: Open or Create a file for reading or writing
//-----------------------------------------------------------------------------
FL_FILE* fl_fopen(char *path, char *mode)
{
	int modlen, i;
	FL_FILE* file; 

	BOOL read = FALSE;
	BOOL write = FALSE;
	BOOL append = FALSE;
	BOOL binary = FALSE;
	BOOL create = FALSE;
	BOOL erase = FALSE;

	// If first call to library, initialise
	CHECK_FL_INIT();

	if ((path==NULL) || (mode==NULL))
		return NULL;

	modlen = (int)strlen(mode);

	// Supported Modes:
	// "r" Open a file for reading. The file must exist. 
	// "w" Create an empty file for writing. If a file with the same name already exists its content is erased and the file is treated as a new empty file.  
	// "a" Append to a file. Writing operations append data at the end of the file. The file is created if it does not exist. 
	// "r+" Open a file for update both reading and writing. The file must exist. 
	// "w+" Create an empty file for both reading and writing. If a file with the same name already exists its content is erased and the file is treated as a new empty file. 
	// "a+" Open a file for reading and appending. All writing operations are performed at the end of the file, protecting the previous content to be overwritten. You can reposition (fseek, rewind) the internal pointer to anywhere in the file for reading, but writing operations will move it back to the end of file. The file is created if it does not exist. 

	for (i=0;i<modlen;i++)
	{
		switch (tolower(mode[i]))
		{
		case 'r':
			read = TRUE;
			break;
		case 'w':
			write = TRUE;
			erase = TRUE;
			create = TRUE;
			break;
		case 'a':
			write = TRUE;
			append = TRUE;
			create = TRUE;
			break;
		case '+':
			if (read)
				write = TRUE;
			else if (write)
			{
				read = TRUE;
				erase = TRUE;
				create = TRUE;
			}
			else if (append)
			{
				read = TRUE;
				write = TRUE;
				append = TRUE;
				create = TRUE;
			}
			break;
		case 'b':
			binary = TRUE;
			break;
		}
	}
	
	file = NULL;

	// Read
	if (read)
		file = _read_file(path);

	// Create New
#ifdef INCLUDE_WRITE_SUPPORT
	if ( (file==NULL) && (create) )
		file = _create_file(path, 0);
#else
	create = FALSE;
	write = FALSE;
	append = FALSE;
#endif

	// Write Existing
	if ( !create && !read && (write || append) )
		file = _read_file(path);

	if (file!=NULL)
	{
		file->Read = read;
		file->Write = write;
		file->Append = append;
		file->Binary = binary;
		file->Erase = erase;
	}

	return file;	
}
示例#14
0
int32_t _dfu_send_image(Dfu_t *pD, int program_mode, class_Firmware_t *firmware_manifest)
{
    int32_t r;
    int  softdevice_size;
    int  bootloader_size;
    int  application_size;
    int firmware_size;
    char *bin_file_path ;
    buf32_t *firmware;
    char *dat_file_path;
    buf32_t *init_packet;
    DfuTransport_t *pT;

    /*
    Does DFU for one image. Reads the firmware image and init file.
    Opens the transport backend, calls setup, send and finalize and closes the backend again.
    @param program_mode: What type of firmware the DFU is
    @type program_mode: nordicsemi.dfu.model.HexType
    @param firmware_manifest: The manifest for the firmware image
    @type firmware_manifest: nordicsemi.dfu.manifest.Firmware
    @return:
    */

    pT = pD->dfu_transport;

    r = 0;
    if(firmware_manifest == 0)//is None:
    {
        printf("firmware_manifest must be provided.\n"); //raise MissingArgumentException("firmware_manifest must be provided.")
        return(-1);
    }

    bool bRet;
    bRet = pT->is_open(pT);
    if( bRet )
    {
        printf("IllegalStateException(Transport is already open.)\n"); //raise IllegalStateException("Transport is already open.")
        return(-1);
    }

    r = pT->open(pT); //TODO this initialisation (e.g. put RTR500BLE into program mode [SET_DEVICE_DFU_MODE_ON]) should be done here
    if(r != 0) {return(r);}

    r = self_wait_while_opening_transport(pD);
    if(r != 0) {return(r);}

    softdevice_size = 0;
    bootloader_size = 0;
    application_size = 0;

    bin_file_path = os_path_join(pD->unpacked_zip_path, firmware_manifest->bin_file); //"TODO";//os.path.join(self.unpacked_zip_path, firmware_manifest.bin_file);
    firmware = _read_file(bin_file_path);
    free( bin_file_path );
    if( firmware == 0)
    {
        return(-1);
    }

    dat_file_path = os_path_join(pD->unpacked_zip_path, firmware_manifest->dat_file); //"TODO"; //os.path.join(self.unpacked_zip_path, firmware_manifest.dat_file);    
    init_packet = _read_file(dat_file_path);
    free( dat_file_path );
    if( init_packet == 0)
    {
        return(-1);
    }

    if(program_mode == HexType_SD_BL)
    {
        //if( firmware_manifest->manifestType != SoftdeviceBootloaderFirmware ) //if( not isinstance(firmware_manifest, SoftdeviceBootloaderFirmware) )
        //{
        //    printf("Wrong type of manifest\n"); //raise NordicSemiException("Wrong type of manifest")
        //    return(-1);
        //}
        softdevice_size = firmware_manifest->sd_size;
        bootloader_size = firmware_manifest->bl_size;
        firmware_size = firmware->length;

        if( softdevice_size + bootloader_size != firmware_size )
        {
            /*TODO raise NordicSemiException(
                "Size of bootloader ({} bytes) and softdevice ({} bytes)"
                " is not equal to firmware provided ({} bytes)".format(
                bootloader_size, softdevice_size, firmware_size));
                */
            return(42);
        }
    }
    else
    {
        if(program_mode == HexType_SOFTDEVICE)
        {
            softdevice_size = firmware->length;
        }
        else
        {
            if(program_mode == HexType_BOOTLOADER)
            {
                bootloader_size = firmware->length;
            }
            else
            {
                if(program_mode == HexType_APPLICATION)
                {
                    application_size = firmware->length;
                }
            }
        }
    }

    //TODO start_time = time();
    /*
    logger.info("Starting DFU upgrade of type %s, SoftDevice size: %s, bootloader size: %s, application size: %s",
    program_mode,
    softdevice_size,
    bootloader_size,
    application_size)

    logger.info("Sending DFU start packet, afterwards we wait for the flash on "
    "target to be initialized before continuing.")
    */


    pT->SET_DEVICE_DFU_MODE_ON(pT);

    pT->send_start_dfu(pT, program_mode, softdevice_size, bootloader_size, application_size);

    //logger.info("Sending DFU init packet");
    pT->send_init_packet(pT, init_packet);

    //logger.info("Sending firmware file");
    pT->send_firmware(pT, firmware);

    pT->send_validate_firmware(pT);

    pT->send_activate_firmware(pT);

    //TODO end_time = time();
    //logger.info("DFU upgrade took {0}s".format(end_time - start_time));
   
    printf("     5\n");
    time_sleep(1.0);
    printf("    4\n");
    time_sleep(1.0);
    printf("   3\n");
    time_sleep(1.0);
    printf("  2\n");
    time_sleep(1.0);
    printf(" 1\n");
    time_sleep(1.0);
    printf("0\n");

    pT->SET_DEVICE_DFU_MODE_OFF(pT);
    pT->close(pT);  //TODO this DEinitialisation (e.g. put RTR500BLE into Normal mode [SET_DEVICE_DFU_MODE_OFF]) should be done here

    return(r);
}
示例#15
0
short opencl_load_kernel(struct openclenv* env, const char *bitcode_path, const char *kernname, size_t index)
{
	char *err_msg = NULL;
	int err = 0, log_error;
	size_t pathlen = strlen(bitcode_path);
	char *build_log;
	size_t build_log_size;
	char build_opts[MAX_BUILD_OPTS_LENGTH];


#ifdef __APPLE__
	env->program = clCreateProgramWithSource(env->context, 1, (const char **)&bitcode_path, &pathlen, &err);
#else
	size_t code_length;
	char *code_contents = _read_file(bitcode_path, &code_length);

	if (!code_contents) {
		err_msg = strerror(errno);
		err = errno;
		goto error;
	}

	env->program = clCreateProgramWithSource(env->context, 1 , (const char **)&code_contents, &code_length, &err);

	free(code_contents);
#endif


	if (err) {
		err_msg = "clCreateProgramWithSource";
		goto error;
	}

	_opencl_generate_build_opts(build_opts, MAX_BUILD_OPTS_LENGTH);

	stablecl_log(log_message, "Building kernel %s from %s...", kernname, bitcode_path);
	stablecl_log(log_message, "Build options: %s", build_opts);

	err = clBuildProgram(env->program, 1, &env->device, build_opts, NULL, NULL);

#ifndef SIMULATOR_BUILD
	log_error = clGetProgramBuildInfo(env->program, env->device, CL_PROGRAM_BUILD_LOG, 0, NULL, &build_log_size);

	if (log_error)
		stablecl_log(log_err, "Error retrieving build log size.");
	else {
		build_log = malloc(build_log_size);

		if (!build_log)
			stablecl_log(log_err, "Couldn't allocate enough memory for build log.");
		else {
			log_error = clGetProgramBuildInfo(env->program, env->device, CL_PROGRAM_BUILD_LOG, build_log_size, build_log, &build_log_size);

			if (log_error)
				stablecl_log(log_err, "Couldn't get build log: %s", opencl_strerr(log_err));
			else if (err)
				stablecl_log(log_err, "Build log (size %zu):\n%s", build_log_size, build_log);

			free(build_log);
		}
	}

#endif

	if (err) {
		err_msg = "clBuildProgram";
		goto error;
	}

	env->kernel[index] = clCreateKernel(env->program, kernname, &err);

	if (err) {
		err_msg = "clCreateKernel";
		goto error;
	}

	_opencl_kernel_info(env, env->kernel[index]);

	env->enabled_kernels[index] = 1;
	env->kernel_count++;

	stablecl_log(log_message, "Kernel %s loaded successfully", kernname);

error:

	if (err && err_msg)
		stablecl_log(log_err, "Kernel load failed with error %d at %s: %s", err, err_msg, opencl_strerr(err));

	return err;
}
示例#16
0
static NEOERR* _hdf_read_string (HDF *hdf, const char **str, STRING *line,
                                 const char *path, int *lineno,
                                 int include_handle, int expect_end_brace) {
  NEOERR *err;
  HDF *lower;
  char *s;
  char *name, *value;
  HDF_ATTR *attr = NULL;

  while (**str != '\0')
  {
    /* Reset string length, but don't free the reserved buffer */
    line->len = 0;
    err = _copy_line_advance(str, line);
    if (err) return nerr_pass(err);
    attr = NULL;
    (*lineno)++;
    s = line->buf;
    SKIPWS(s);
    if ((!strncmp(s, "#include ", 9) || !strncmp(s, "-include ", 9)) && include_handle != INCLUDE_IGNORE)
    {
      int required = !strncmp(s, "#include ", 9);
      if (include_handle == INCLUDE_ERROR)
      {
	return nerr_raise (NERR_PARSE,
                           "[%d]: #include not supported in string parse",
                           *lineno);
      }
      else if (include_handle < INCLUDE_MAX_DEPTH)
      {
        int l;
        s += 9;
        name = neos_strip(s);
        l = strlen(name);
        if (name[0] == '"' && name[l-1] == '"')
        {
          name[l-1] = '\0';
          name++;
        }
        char fullpath[PATH_MAX];
        if (name[0] != '/') {
          memset(fullpath, 0, PATH_MAX);

          char *p = strrchr(path, '/');
          if (p == NULL) {
            char pwd[PATH_MAX];
            memset(pwd, 0, PATH_MAX);
            getcwd(pwd, PATH_MAX);
            snprintf(fullpath, PATH_MAX, "%s/%s", pwd, name);
          } else {
            int dir_len = p - path + 1;
            snprintf(fullpath, PATH_MAX, "%s", path);
            snprintf(fullpath + dir_len, PATH_MAX - dir_len, "%s", name);
          }
          name = fullpath;
        }
        err = hdf_read_file_internal(hdf, name, include_handle + 1);
        if (err != STATUS_OK && required)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else {
        return nerr_raise (NERR_MAX_RECURSION,
                           "[%d]: Too many recursion levels.",
                           *lineno
                           );
      }
    }
    else if (s[0] == '#')
    {
      /* comment: pass */
    }
    else if (s[0] == '}') /* up */
    {
      s = neos_strip(s);
      if (strcmp(s, "}"))
      {
        err = nerr_raise(NERR_PARSE,
	    "[%s:%d] Trailing garbage on line following }: %s", path, *lineno,
	    line->buf);
        return err;
      }
      return STATUS_OK;
    }
    else if (s[0])
    {
      /* Valid hdf name is [0-9a-zA-Z_.]+ */
      int splice = *s == '@';
      if (splice) s++;
      name = s;
      while (*s && (isalnum(*s) || *s == '_' || *s == '.' || *s == '*')) s++;
      SKIPWS(s);

      char num[16];
      static int counter = 0;
      if (*name == '*') {
        snprintf(num, sizeof(num), "%d", counter++);
        name = num;
      }

      if (s[0] == '[') /* attributes */
      {
	*s = '\0';
	name = neos_strip(name);
	s++;
	err = parse_attr(&s, &attr);
	if (err)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
	SKIPWS(s);
      }
      if (splice) {
        name = neos_strip(name);
        HDF *h = hdf_get_obj(hdf->top, name);
        if (h) {
          HDF *c = hdf_obj_child(h);
          while (c) {
            err = hdf_copy (hdf, hdf_obj_name(c), c);
            if (err != STATUS_OK) break;
            c = hdf_obj_next(c);
          }
        }
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      } else if (s[0] == '=') /* assignment */
      {
	*s = '\0';
	name = neos_strip(name);
	s++;
	value = neos_strip(s);
	err = _set_value (hdf, name, value, 1, 1, 0, attr, NULL);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == ':' && s[1] == '=') /* copy */
      {
	*s = '\0';
	name = neos_strip(name);
	s+=2;
	value = neos_strip(s);
        HDF *h = hdf_get_obj(hdf->top, value);
        if (!h)
        {
	  err = nerr_raise(NERR_PARSE,
                           "[%s:%d] Failed to copy a node that is not loaded "
                           "yet: %s", path, *lineno, value);
          return err;
        }
        err = hdf_copy(hdf, name, h);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == '!' && s[1] == '=') /* exec */
      {
	*s = '\0';
	name = neos_strip(name);
	s+=2;
	value = neos_strip(s);

        FILE *f = popen(value, "r");
	if (f == NULL)
        {
	  err = nerr_raise(NERR_PARSE,
                           "[%s:%d] Failed to exec specified command: %s",
                           path, *lineno, line->buf);
          return err;
        }
        char *content = _read_file(f);
        fclose(f);
        int len = strlen(content);
        if (len > 0 && content[len - 1] == '\n') {
          content[len - 1] = '\0'; // remove \n artifact
        }
	err = _set_value (hdf, name, content, 1, 1, 0, attr, NULL);
        free(content);

	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == ':') /* link */
      {
	*s = '\0';
	name = neos_strip(name);
	s++;
	value = neos_strip(s);
	err = _set_value (hdf, name, value, 1, 1, 1, attr, NULL);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == '{') /* deeper */
      {
	*s = '\0';
	name = neos_strip(name);
	lower = hdf_get_obj (hdf, name);
	if (lower == NULL)
	{
	  err = _set_value (hdf, name, NULL, 1, 1, 0, attr, &lower);
	}
	else
	{
	  err = _set_value (lower, NULL, lower->value, 1, 1, 0, attr, NULL);
	}
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
	err = _hdf_read_string (lower, str, line, path, lineno, include_handle,
                                1);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == '<' && s[1] == '<') /* multi-line assignment */
      {
	char *m;
	int msize = 0;
	int mmax = 128;
	int l;

	*s = '\0';
	name = neos_strip(name);
	s+=2;
	value = neos_strip(s);
	l = strlen(value);
	if (l == 0)
        {
	  err = nerr_raise(NERR_PARSE,
	      "[%s:%d] No multi-assignment terminator given: %s", path, *lineno,
	      line->buf);
          return err;
        }
	m = (char *) malloc (mmax * sizeof(char));
	if (m == NULL)
        {
	  return nerr_raise(NERR_NOMEM,
	    "[%s:%d] Unable to allocate memory for multi-line assignment to %s",
	    path, *lineno, name);
        }
	while (_copy_line (str, m+msize, mmax-msize) != 0)
	{
          (*lineno)++;
	  if (!strncmp(value, m+msize, l) && isspace(m[msize+l]))
	  {
	    m[msize] = '\0';
	    break;
	  }
	  msize += strlen(m+msize);
	  if (msize + l + 10 > mmax)
	  {
	    void *new_ptr;
	    mmax += 128;
	    new_ptr = realloc (m, mmax * sizeof(char));
	    if (new_ptr == NULL)
	    {
        free(m);
	      return nerr_raise(NERR_NOMEM,
		  "[%s:%d] Unable to allocate memory for multi-line assignment to %s: size=%d",
		  path, *lineno, name, mmax);
      }
      m = (char *) new_ptr;
	  }
	}
	err = _set_value (hdf, name, m, 0, 1, 0, attr, NULL);
	if (err != STATUS_OK)
	{
	  free (m);
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
	}

      }
      else
      {
	err = nerr_raise(NERR_PARSE, "[%s:%d] Unable to parse line %s", path,
	    *lineno, line->buf);
        return err;
      }
    }
  }
  if (expect_end_brace) {
    err = nerr_raise(NERR_PARSE, "[%s:%d] Missing matching }", path, *lineno);
    return err;
  }
  return STATUS_OK;
}